def test_wildcard_excl_fixed_host(self): """ A list of namespaces is selected through wildcards with a fixed hostname """ sel = hostslist.HostSelection(self.mockroot) for host in self.mockhosts: sel.select(host[0], host[1]) namespace = self.mockhosts[3][0][:] namespace[-1] = "*" print namespace hst = "host3" sel.exclude(namespace, hst) count = len(self.mockhosts) for host in self.mockhosts: print host if len(host[0]) == 0: pass elif host[0][0] == namespace[0] and host[1] == hst: print host[0], host[1] count -= 1 result = sel.flatten() print result print len(result), count assert len(result) == count, \ "The returned host differs in size from the expected"
def test_explicit_multiple_exclude(self): """ A list of hosts is explicitly excluded """ sel = hostslist.HostSelection(self.mockroot) for host in self.mockhosts: sel.select(host[0], host[1]) for host in self.mockhosts: sel.exclude(host[0], host[1]) result = sel.flatten() assert len(result) == 0, \ "The returned host differs in size from the expected"
def test_duplicate_host_removal(self): """ Some Hosts are selected through multiple patterns thus can be double """ self.mockroot.add(self.mockhosts[13][0], self.mockhosts[17][1]) # one entry is multiplied the result size must stay the same sel = hostslist.HostSelection(self.mockroot) for host in self.mockhosts: sel.select(host[0], host[1]) result = sel.flatten() print len(result), len(self.mockhosts) assert len(result) == len(self.mockhosts), \ "The returned host differs in size from the expected"
def test_explicit_single_select(self): """ A lsingle host is explicitly selected """ sel = hostslist.HostSelection(self.mockroot) namespace = self.mockhosts[12][0] host = self.mockhosts[12][1] sel.select(namespace, host) result = sel.flatten() print len(result) assert len(result) == 1, \ "The returned host differs in size from the expected" print result[0], host assert result[0] == host, "The Host is wrong"
def test_explicit_multiple_select(self): """ A list of hosts is explicitly selected """ sel = hostslist.HostSelection(self.mockroot) for host in self.mockhosts: sel.select(host[0], host[1]) result = sel.flatten() print len(result), len(self.mockhosts) assert len(result) == len(self.mockhosts), \ "The returned host differs in size from the expected" for host in self.mockhosts: print host[1], result assert host[1] in result, "A host is mising from the result"
def test_wildcard_select_all(self): """ A list of namespaces is selected through wildcards """ sel = hostslist.HostSelection(self.mockroot) namespace = ["*"] print namespace host = "*" sel.select(namespace, host) count = len(self.mockhosts) result = sel.flatten() print result print len(result), count assert len(result) == count, \ "The returned host differs in size from the expected"
def test_wildcard_select_hosts(self): """ A list of hosts is selected through wildcards """ sel = hostslist.HostSelection(self.mockroot) namespace = self.mockhosts[3][0] host = "*" sel.select(namespace, host) count = 0 for host in self.mockhosts: if cmp(host[0], namespace) == 0: count += 1 result = sel.flatten() print len(result), count assert len(result) == count, \ "The returned host differs in size from the expected"
def test_explicit_single_exclude(self): """ A list of hosts is explicitly excluded """ sel = hostslist.HostSelection(self.mockroot) for host in self.mockhosts: sel.select(host[0], host[1]) namespace = self.mockhosts[3][0] host = self.mockhosts[3][1] sel.exclude(namespace, host) result = sel.flatten() print len(self.mockhosts) print len(result), (len(self.mockhosts) - 1) assert len(result) == (len(self.mockhosts) - 1), \ "The returned host differs in size from the expected" print host, result assert host not in result, "The excluded host was found in the result"
def test_no_namespace_single(self): """ A single Host with no namespoace is selected """ sel = hostslist.HostSelection(self.mockroot) namespace = [] host = "host22" sel.select(namespace, host) count = 0 for hst in self.mockhosts: if len(hst[0]) == 0 and hst[1] == host: count += 1 print count result = sel.flatten() print result print len(result), count assert len(result) == count, \ "The returned host differs in size from the expected"
def test_no_namespace_all(self): """ All hosts without Namespace are selected """ sel = hostslist.HostSelection(self.mockroot) namespace = [] host = "*" sel.select(namespace, host) count = 0 for hst in self.mockhosts: if len(hst[0]) == 0: count += 1 print count result = sel.flatten() print result print len(result), count assert len(result) == count, \ "The returned host differs in size from the expected"
def test_wildcard_select_namespace(self): """ A list of namespaces is selected through wildcards """ sel = hostslist.HostSelection(self.mockroot) namespace = self.mockhosts[3][0][:] namespace[-1] = "*" print namespace host = "*" sel.select(namespace, host) count = 0 for host in self.mockhosts: if len(host[0]) == 0: pass elif host[0][0] == namespace[0] and host[0][1] == namespace[1]: print host[0], host[1] count += 1 print count result = sel.flatten() print result print len(result), count assert len(result) == count, \ "The returned host differs in size from the expected"
def main(fabfile_locations=None): """ Main command-line execution loop. """ try: # Parse command line options parser, options, arguments = parse_options() # Handle regular args vs -- args arguments = parser.largs remainder_arguments = parser.rargs # Allow setting of arbitrary env keys. # This comes *before* the "specific" env_options so that those may # override these ones. Specific should override generic, if somebody # was silly enough to specify the same key in both places. # E.g. "fab --set shell=foo --shell=bar" should have env.shell set to # 'bar', not 'foo'. for pair in _escape_split(',', options.env_settings): pair = _escape_split('=', pair) # "--set x" => set env.x to True # "--set x=" => set env.x to "" key = pair[0] value = True if len(pair) == 2: value = pair[1] state.env[key] = value # Update env with any overridden option values # NOTE: This needs to remain the first thing that occurs # post-parsing, since so many things hinge on the values in env. for option in env_options: state.env[option.dest] = getattr(options, option.dest) # Read Hosts from file if "hosts_filename" in state.env and isinstance( state.env["hosts_filename"], basestring): f = open(state.env["hosts_filename"]) selection = hostslist.select_hosts_from_file(f) f.close() else: selection = hostslist.HostSelection() # Handle --hosts, --roles, --exclude-hosts (comma separated string => # list) for key in ['hosts', 'roles', 'exclude_hosts']: if key in state.env and isinstance(state.env[key], basestring): state.env[key] = state.env[key].split(',') # Inject Hosts read from file for host in state.env["hosts"]: selection.parse_cmd(host) for host in state.env["exclude_hosts"]: selection.parse_cmd("!" + host) del state.env["exclude_hosts"] state.env["hosts"] = selection.flatten() print "Selected Hosts:", state.env["hosts"] # Feed the env.tasks : tasks that are asked to be executed. state.env['tasks'] = arguments # Handle output control level show/hide update_output_levels(show=options.show, hide=options.hide) # Handle version number option if options.show_version: print("Fabric %s" % state.env.version) print("Paramiko %s" % ssh.__version__) sys.exit(0) # Load settings from user settings file, into shared env dict. state.env.update(load_settings(state.env.rcfile)) # Find local fabfile path or abort fabfile = find_fabfile(fabfile_locations) if not fabfile and not remainder_arguments: abort("""Couldn't find any fabfiles! Remember that -f can be used to specify fabfile path, and use -h for help.""") # Store absolute path to fabfile in case anyone needs it state.env.real_fabfile = fabfile # Load fabfile (which calls its module-level code, including # tweaks to env values) and put its commands in the shared commands # dict default = None if fabfile: docstring, callables, default = load_fabfile(fabfile) state.commands.update(callables) # Handle case where we were called bare, i.e. just "fab", and print # a help message. actions = (options.list_commands, options.shortlist, options.display, arguments, remainder_arguments, default) if not any(actions): parser.print_help() sys.exit(1) # Abort if no commands found if not state.commands and not remainder_arguments: abort("Fabfile didn't contain any commands!") # Now that we're settled on a fabfile, inform user. if state.output.debug: if fabfile: print("Using fabfile '%s'" % fabfile) else: print("No fabfile loaded -- remainder command only") # Shortlist is now just an alias for the "short" list format; # it overrides use of --list-format if somebody were to specify both if options.shortlist: options.list_format = 'short' options.list_commands = True # List available commands if options.list_commands: show_commands(docstring, options.list_format) # Handle show (command-specific help) option if options.display: display_command(options.display) # If user didn't specify any commands to run, show help if not (arguments or remainder_arguments or default): parser.print_help() sys.exit(0) # Or should it exit with error (1)? # Parse arguments into commands to run (plus args/kwargs/hosts) commands_to_run = parse_arguments(arguments) # Parse remainders into a faux "command" to execute remainder_command = parse_remainder(remainder_arguments) # Figure out if any specified task names are invalid unknown_commands = [] for tup in commands_to_run: if crawl(tup[0], state.commands) is None: unknown_commands.append(tup[0]) # Abort if any unknown commands were specified if unknown_commands: warn("Command(s) not found:\n%s" \ % indent(unknown_commands)) show_commands(None, options.list_format, 1) # Generate remainder command and insert into commands, commands_to_run if remainder_command: r = '<remainder>' state.commands[r] = lambda: api.run(remainder_command) commands_to_run.append((r, [], {}, [], [], [])) # Ditto for a default, if found if not commands_to_run and default: commands_to_run.append((default.name, [], {}, [], [], [])) # Initial password prompt, if requested if options.initial_password_prompt: prompt = "Initial value for env.password: "******", ".join(x[0] for x in commands_to_run) print("Commands to run: %s" % names) # At this point all commands must exist, so execute them in order. for name, args, kwargs, arg_hosts, arg_roles, arg_exclude_hosts in commands_to_run: execute(name, hosts=arg_hosts, roles=arg_roles, exclude_hosts=arg_exclude_hosts, *args, **kwargs) # If we got here, no errors occurred, so print a final note. if state.output.status: print("\nDone.") except SystemExit: # a number of internal functions might raise this one. raise except KeyboardInterrupt: if state.output.status: sys.stderr.write("\nStopped.\n") sys.exit(1) except: sys.excepthook(*sys.exc_info()) # we might leave stale threads if we don't explicitly exit() sys.exit(1) finally: disconnect_all() sys.exit(0)