def parse_args(): """Parse and return command line arguments, validate the host.""" parser = lib.get_base_parser('Automated reimaging of a single host') parser.add_argument( '--rename', help='FQDN of the new name to rename this host to while reimaging') parser.add_argument( '--rename-mgmt', help='FQDN of the new name management interface, see --rename') parser.add_argument('host', metavar='HOST', action='store', help='FQDN of the host to be reimaged') parser.add_argument('mgmt', metavar='MGMT', action='store', nargs='?', default=None, help='FQDN of the management interface for the host') args = parser.parse_args() fqdns = [args.host] if args.rename is not None: fqdns.append(args.rename) if args.no_pxe: raise argparse.ArgumentTypeError( 'The --rename option cannot be used in conjunction with --no-pxe.' ) # Gather the management interfaces, if missing if args.mgmt is None: mgmts = lib.get_mgmts([args.host]) args.mgmt = mgmts[args.host] else: mgmts = {args.host: args.mgmt} fqdns.append(args.mgmt) if args.rename is not None and args.rename_mgmt is None: mgmts.update(lib.get_mgmts([args.rename])) fqdns.append(mgmts[args.rename]) # Perform a quick sanity check on the host and mgmt for name in fqdns: if '.' not in name or not lib.HOSTS_PATTERN.match(name): raise argparse.ArgumentTypeError( "Expected FQDN, got '{name}'".format(name=name)) if not lib.is_hostname_valid(name): raise argparse.ArgumentTypeError( "Unable to resolve host '{name}'".format(name=name)) for mgmt in mgmts.values(): if '.mgmt.' not in mgmt: raise argparse.ArgumentTypeError( 'The MGMT parameter {} does not follow the *.mgmt.* format'. format(mgmt)) return args
def parse_args(): """Parse and return command line arguments, validate the hosts.""" parser = lib.get_base_parser('Automated reimaging of a list of hosts') parser.add_argument( '--sequential', action='store_true', help=('run one reimage at a time, sequentially. By default the reimage for all the hosts ' 'are run in parallel.')) parser.add_argument( '--sleep', action='store', type=int, default=0, help=('amount of seconds to sleep between one reimage and the next when --sequential ' 'is set. Has no effect if --sequential is not set. [default: 0]')) parser.add_argument( '--force', action='store_true', help='override the default limit of that can be reimaged: 3 in parallel, 5 in sequence.') parser.add_argument( 'hosts', metavar='HOST', nargs='+', action='store', help='FQDN of the host(s) to be reimaged') args = parser.parse_args() # Safety limits if not args.force: if args.sequential and len(args.hosts) > 5: parser.error('More than 5 sequential hosts specified and --force not set') elif len(args.hosts) > 3: parser.error(("More than 3 parallel hosts specified and --force not set. Before using " "the --force parameter, ensure that there aren't too many hosts in the " "same rack.")) # Perform a quick sanity check on the hosts for host in args.hosts: if '.' not in host or not lib.HOSTS_PATTERN.match(host): parser.error("Expected FQDN of hosts, got '{host}'".format(host=host)) if not lib.is_hostname_valid(host): parser.error("Unable to resolve host '{host}'".format(host=host)) # Ensure there are no duplicates in the hosts list duplicates = {host for host in args.hosts if args.hosts.count(host) > 1} if len(duplicates) > 0: parser.error("Duplicate hosts detected: {dup}".format(dup=duplicates)) # Ensure Phab task is properly formatted if (args.phab_task_id is not None and lib.PHAB_TASK_PATTERN.search(args.phab_task_id) is None): parser.error(("Invalid Phabricator task ID '{task}', expected in " "the form T12345").format(task=args.phab_task_id)) return args