
- Additionally, add password validation function. - Breaks Parser.py into more manageable functions. - Changes where defaults are set (Parser.py instead of class under /consts) The goal is to not have any reference to a password in the code itself, only in configuration files or README files, if strictly necessary. The new password validation function, besides failing fast at the argument parser, makes sure the password will be allowed by Debian later on the installation. This commit is not touching any Shell script because they will probably be removed or change in follow-up commits. Test Plan: PASS: Operating system password should be set to value passed via --password Failure Path: PASS: Script fails fast without the parameter --password PASS: Script fails fast if password requirements are not met Regression: PASS: AIO-SX install works Story: 2005051 Task: 47960 Task: 48230 Change-Id: Ibf42b792ef825cee61cc69d1b5afa807361037b7 Signed-off-by: Bruno Muniz <bruno.muniz@encora.com>
448 lines
18 KiB
Python
448 lines
18 KiB
Python
# pylint: disable=invalid-name
|
|
#!/usr/bin/python3
|
|
#
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
#
|
|
|
|
"""
|
|
Parser to handle command line arguments
|
|
"""
|
|
import argparse
|
|
import re
|
|
from argparse import ArgumentParser, RawTextHelpFormatter
|
|
import getpass
|
|
|
|
|
|
def validate_password(pwd: str):
|
|
"""
|
|
Validation function that raises an argparse.ArgumentTypeError if
|
|
requirements are not met.
|
|
|
|
Args:
|
|
pwd: the password to validate against requirements
|
|
|
|
Returns: the password, if requirements are met
|
|
"""
|
|
errors = [
|
|
None if len(pwd) >= 7 else "at least 7 characters long",
|
|
None if re.search(r'[!@#$%^&*(),.?":{}|<>]', pwd) else "at least one special character",
|
|
None if any(c.isupper() for c in pwd) else "at least one capital letter",
|
|
None if any(c.isdigit() for c in pwd) else "at least one digit"
|
|
]
|
|
errors = list(filter(None, errors)) # Remove occurrences of None from errors list
|
|
if errors:
|
|
raise argparse.ArgumentTypeError(f'unmet requirements: {"; ".join(errors)}')
|
|
return pwd
|
|
|
|
|
|
def handle_args():
|
|
"""
|
|
Handle arguments supplied via command line
|
|
"""
|
|
parser = ArgumentParser(formatter_class=RawTextHelpFormatter)
|
|
|
|
parse_setup_config(parser)
|
|
parse_config_location(parser)
|
|
parse_disk_info(parser)
|
|
parse_networking(parser)
|
|
parse_custom_scripts(parser)
|
|
parse_other(parser)
|
|
|
|
return parser
|
|
|
|
|
|
def parse_setup_config(parser: ArgumentParser):
|
|
"""
|
|
Mutate parser with CLI arguments related to the setup type
|
|
"""
|
|
parser.add_argument("--setup-type", help=
|
|
"""
|
|
Type of setup:
|
|
AIO-SX
|
|
AIO-DX
|
|
STANDARD
|
|
STORAGE
|
|
""",
|
|
choices=['AIO-SX', 'AIO-DX', 'STANDARD', 'STORAGE'],
|
|
type=str)
|
|
parser.add_argument("--controllers", help=
|
|
"""
|
|
Number of controllers:
|
|
1 - single controller
|
|
2 - two controllers
|
|
""",
|
|
choices=[1, 2],
|
|
type=int,
|
|
default=2)
|
|
parser.add_argument("--workers", help=
|
|
"""
|
|
Number of workers:
|
|
1 - single worker
|
|
2 - two workers
|
|
etc.
|
|
""",
|
|
type=int,
|
|
default=2)
|
|
parser.add_argument("--storages", help=
|
|
"""
|
|
Number of storage nodes:
|
|
1 - single storage node
|
|
2 - two storage nodes
|
|
etc.\n
|
|
""",
|
|
type=int,
|
|
default=2)
|
|
parser.add_argument("--from-stage", help=
|
|
"""
|
|
Start stage.
|
|
For a list of stages run --list-stages
|
|
\n
|
|
""",
|
|
type=str)
|
|
parser.add_argument("--to-stage", help=
|
|
"""
|
|
End stage.
|
|
For a list of stages run --list-stages
|
|
\n
|
|
""",
|
|
type=str)
|
|
parser.add_argument("--custom-stages", help=
|
|
"""
|
|
Custom, comma separated list of stages.
|
|
For a list of stages run --list-stages
|
|
\n
|
|
""",
|
|
type=str,
|
|
default=None)
|
|
parser.add_argument("--lowlatency", help=
|
|
"""
|
|
Whether to install an AIO system as low latency.
|
|
""",
|
|
action='store_true')
|
|
parser.add_argument("--install-mode", help=
|
|
"""
|
|
Lab will be installed using the mode specified. Serial mode by default
|
|
""",
|
|
type=str, choices=['serial', 'graphical'],
|
|
default='serial')
|
|
parser.add_argument("--username", help=
|
|
"""
|
|
Username. default is 'sysadmin'
|
|
""",
|
|
type=str,
|
|
default="sysadmin")
|
|
parser.add_argument("--password", help=
|
|
"""
|
|
Password.
|
|
""",
|
|
type=validate_password,
|
|
required=True)
|
|
|
|
|
|
def parse_config_location(parser: ArgumentParser):
|
|
"""
|
|
Mutate parser with CLI arguments related with the location of files and
|
|
configuration
|
|
"""
|
|
parser.add_argument("--iso-location", help=
|
|
"""
|
|
Location of ISO including the filename:
|
|
/folk/myousaf/bootimage.ISO
|
|
""",
|
|
type=str)
|
|
parser.add_argument("--config-files-dir", help=
|
|
"""
|
|
Directory with config files, scripts, images (i.e.
|
|
lab_setup.sh, lab_setup.conf, ...) that are needed
|
|
for the install. All files at this location are
|
|
transfered to controller-0 in /home/sysadmin. You
|
|
can add you own scripts that you need to be
|
|
present on the controller. Caution: rsync will
|
|
follow links and will fail if links are broken!
|
|
Use --config-files-dir-dont-follow-links
|
|
instead. Also, you can use both options for
|
|
different folders.
|
|
""",
|
|
type=str)
|
|
parser.add_argument("--config-files-dir-dont-follow-links", help=
|
|
"""
|
|
Same as --config-files-dir but keep symbolic link as is.
|
|
""",
|
|
type=str)
|
|
parser.add_argument("--config-controller-ini", help=
|
|
"""
|
|
Path to the local config_controller .ini. This
|
|
file is transferred to the controller. NOTE: OAM
|
|
configuration in this ini is updated dynamically
|
|
based on networking related args.
|
|
(e.g. stx_config.ini_centos,
|
|
~/stx_config.ini_centos, /home/myousaf ...).
|
|
""",
|
|
type=str)
|
|
parser.add_argument("--ansible-controller-config", help=
|
|
"""
|
|
Path to a local YAML file to be copied as localhost.yml
|
|
to the home directory of the controller-0.
|
|
""",
|
|
type=str)
|
|
parser.add_argument("--vbox-home-dir", help=
|
|
"""
|
|
This is the folder where vbox disks will be
|
|
placed. e.g. /home or /folk/cgts/users
|
|
The disks will be in /home/wzhou/vbox_disks/ or
|
|
/folk/cgts/users/wzhou/vbox_disks/
|
|
""",
|
|
type=str, default='/home')
|
|
parser.add_argument("--lab-setup-conf", help=
|
|
"""
|
|
Path to the config file to use
|
|
""",
|
|
action='append')
|
|
|
|
|
|
def parse_disk_info(parser: ArgumentParser):
|
|
"""
|
|
Mutate parser with CLI arguments related with VirtualBox disks
|
|
arguments
|
|
"""
|
|
parser.add_argument("--controller-disks", help=
|
|
"""
|
|
Select the number of disks for a controller VM. default is 3
|
|
""",
|
|
type=int, default=3, choices=[1, 2, 3, 4, 5, 6, 7])
|
|
parser.add_argument("--storage-disks", help=
|
|
"""
|
|
Select the number of disks for storage VM. default is 3
|
|
""",
|
|
type=int, default=3, choices=[1, 2, 3, 4, 5, 6, 7])
|
|
parser.add_argument("--worker-disks", help=
|
|
"""
|
|
Select the number of disks for a worker VM. default is 2
|
|
""",
|
|
type=int, default=2, choices=[1, 2, 3, 4, 5, 6, 7])
|
|
parser.add_argument("--controller-disk-sizes", help=
|
|
"""
|
|
Configure size in MiB of controller disks as a comma separated list.
|
|
""",
|
|
type=str)
|
|
parser.add_argument("--storage-disk-sizes", help=
|
|
"""
|
|
Configure size in MiB of storage disks as a comma separated list.
|
|
""",
|
|
type=str)
|
|
parser.add_argument("--worker-disk-sizes", help=
|
|
"""
|
|
Configure size in MiB of worker disks as a comma separated list.
|
|
""",
|
|
type=str)
|
|
|
|
|
|
def parse_networking(parser: ArgumentParser):
|
|
"""
|
|
Mutate parser with CLI arguments related with VirtualBox networking
|
|
"""
|
|
|
|
parser.add_argument("--vboxnet-name", help=
|
|
"""
|
|
Which host only network to use for setup.
|
|
""",
|
|
type=str)
|
|
parser.add_argument("--vboxnet-ip", help=
|
|
"""
|
|
The IP address of the host only adapter as it
|
|
is configured on the host (i.e. gateway). This is also used to
|
|
update GATEWAY_IP in [OAM_NETWORK] of config_controller config file.
|
|
""",
|
|
type=str)
|
|
parser.add_argument("--add-nat-interface", help=
|
|
"""
|
|
Add a new NAT interface to hosts.
|
|
""",
|
|
action='store_true')
|
|
parser.add_argument("--controller-floating-ip", help=
|
|
"""
|
|
OAM floating IP.
|
|
""",
|
|
type=str,
|
|
default="10.10.10.5")
|
|
parser.add_argument("--controller0-ip", help=
|
|
"""
|
|
OAM IP of controller-0. This is also used to
|
|
update IP_ADDRESS in [OAM_NETWORK] of
|
|
config_controller config file of an AIO SX setup.
|
|
This should not be the floating IP.
|
|
""",
|
|
type=str,
|
|
default="10.10.10.3")
|
|
parser.add_argument("--controller1-ip", help=
|
|
"""
|
|
OAM IP of controller-1.
|
|
This should not be the floating IP.
|
|
""",
|
|
type=str,
|
|
default="10.10.10.4")
|
|
parser.add_argument("--vboxnet-type", help=
|
|
"""
|
|
Type of vbox network, either hostonly on nat
|
|
""",
|
|
choices=['hostonly', 'nat'],
|
|
type=str,
|
|
default='hostonly')
|
|
parser.add_argument("--nat-controller-floating-local-ssh-port", help=
|
|
"""
|
|
When oam network is configured as 'nat' a port on
|
|
the vbox host is used for connecting to ssh on
|
|
floating controller. No default value is
|
|
configured. This is mandatory if --vboxnet-type is
|
|
'nat' for non AIO-SX deployments.
|
|
""",
|
|
type=str)
|
|
parser.add_argument("--nat-controller0-local-ssh-port", help=
|
|
"""
|
|
When oam network is configured as 'nat' a port on
|
|
the vbox host is used for connecting to ssh on
|
|
controller-0. This is mandatory if --vboxnet-type
|
|
is 'nat'. No default value is configured.
|
|
""",
|
|
type=str)
|
|
parser.add_argument("--nat-controller1-local-ssh-port", help=
|
|
"""
|
|
When oam network is configured as 'nat' a port on
|
|
the vbox host is used for connecting to ssh on
|
|
controller-1. No default value is configued. This
|
|
is mandatory if --vboxnet-type is 'nat' for non
|
|
AIO-SX deployments or if second controller is
|
|
installed.
|
|
""",
|
|
type=str)
|
|
parser.add_argument("--ini-oam-cidr", help=
|
|
"""
|
|
The IP network and mask for the oam net, used to
|
|
update CIDR value in [OAM_NETWORK] of
|
|
config_controller config file. Default is
|
|
10.10.10.0/24
|
|
""",
|
|
type=str)
|
|
parser.add_argument("--ini-oam-ip-start-address", help=
|
|
"""
|
|
The start for the oam net allocation, used to
|
|
update IP_START_ADDRESS value in [OAM_NETWORK] of
|
|
config_controller config file. Not needed for AIO
|
|
SX setups.
|
|
""",
|
|
type=str)
|
|
parser.add_argument("--ini-oam-ip-end-address", help=
|
|
"""
|
|
The end for the oam net allocation, used to update
|
|
IP_END_ADDRESS value in [OAM_NETWORK] of
|
|
config_controller config file. Not needed for AIO
|
|
SX setups.
|
|
""",
|
|
type=str)
|
|
|
|
|
|
def parse_custom_scripts(parser: ArgumentParser):
|
|
"""
|
|
Mutate parser with CLI arguments related to custom scripts
|
|
"""
|
|
parser.add_argument("--script1", help=
|
|
"""
|
|
Name of an executable script file plus options.
|
|
Has to be present in --config-files-dir.
|
|
It will be transfered to host in rsync-config
|
|
stage and executed as part of custom-script1
|
|
stage.
|
|
Example: --script1 'scripts/k8s_pv_cfg.sh,50,ssh,user'
|
|
Contains a comma separated value of:
|
|
<script_name>,<timeout>,<serial or ssh>,<user/root> Where:
|
|
script_name = name of the script, either .sh or .py;
|
|
timeout = how much to wait, in seconds, before considering failure;
|
|
serial/ssh = executed on the serial console;
|
|
user/root = as a user or as root (sudo <script_name);
|
|
|
|
Script executes successfully if return code is 0. Anything else
|
|
is considered error and further execution is aborted.
|
|
""",
|
|
default=None,
|
|
type=str)
|
|
parser.add_argument("--script2", help=
|
|
"""
|
|
See --script1
|
|
""",
|
|
default=None,
|
|
type=str)
|
|
parser.add_argument("--script3", help=
|
|
"""
|
|
See --script1
|
|
""",
|
|
default=None,
|
|
type=str)
|
|
parser.add_argument("--script4", help=
|
|
"""
|
|
See --script1
|
|
""",
|
|
default=None,
|
|
type=str)
|
|
parser.add_argument("--script5", help=
|
|
"""
|
|
See --script1
|
|
""",
|
|
default=None,
|
|
type=str)
|
|
|
|
|
|
def parse_other(parser: ArgumentParser):
|
|
"""
|
|
Mutate parser with CLI arguments related to overall flow control
|
|
"""
|
|
parser.add_argument("--list-stages", help=
|
|
"""
|
|
List stages that can be used by autoinstaller.
|
|
""",
|
|
action='store_true')
|
|
parser.add_argument("--logpath", help=
|
|
"""
|
|
Base directory to store logs.
|
|
""",
|
|
type=str)
|
|
parser.add_argument("--force-delete-lab", help=
|
|
"""
|
|
Don't ask for confirmation when deleting a lab.
|
|
""",
|
|
action='store_true')
|
|
parser.add_argument("--snapshot", help=
|
|
"""
|
|
Take snapshot at different stages when the lab is installed.
|
|
E.g. before and after config_controller, before and after lab_setup.
|
|
""",
|
|
action='store_true')
|
|
parser.add_argument("--securityprofile", help=
|
|
"""
|
|
Security profile to use:
|
|
standard
|
|
extended
|
|
Standard is the default
|
|
""",
|
|
type=str, choices=['standard', 'extended'],
|
|
default='standard')
|
|
parser.add_argument("--labname", help=
|
|
"""
|
|
The name of the lab to be created.
|
|
""",
|
|
type=str)
|
|
parser.add_argument("--userid", help=
|
|
"""
|
|
Unique user id to differentiate vbox machine
|
|
unique names such as interface names or serial
|
|
ports even if setups have the same names for
|
|
different users. Default is your username on this
|
|
machine.
|
|
""",
|
|
type=str,
|
|
default=getpass.getuser())
|
|
parser.add_argument("--hostiocache", help=
|
|
"""
|
|
Turn on host i/o caching
|
|
""",
|
|
action='store_true')
|