def test_get_from_config(self): config = Config(SUDO="config-value") inventory = Inventory((("somehost", ), {})) state = State(config=config, inventory=inventory) kwargs, keys = pop_global_arguments( {}, state=state, host=inventory.get_host("somehost")) assert kwargs["sudo"] == "config-value"
def test_get_from_state_deploy_kwargs(self): config = Config(SUDO="config-value") inventory = Inventory(([("somehost", {"sudo": "host-value"})], {})) somehost = inventory.get_host("somehost") state = State(config=config, inventory=inventory) somehost.current_deploy_kwargs = {"sudo": "deploy-kwarg-value"} kwargs, keys = pop_global_arguments({}, state=state, host=somehost) assert kwargs["sudo"] == "deploy-kwarg-value"
def test_create_inventory_override_data(self): default_data = { "default_data": "default_data", "override_data": "ignored" } override_data = {"override_data": "override_data"} somehost_data = {"host_data": "host_data"} inventory = Inventory( ( [("somehost", somehost_data), "anotherhost"], default_data, ), override_data=override_data, ) assert inventory.get_data() == default_data assert inventory.get_override_data() == override_data assert inventory.get_host("somehost").data.host_data == "host_data" assert inventory.get_host("anotherhost").data.get("host_data") is None assert inventory.get_host( "somehost").data.override_data == "override_data" assert inventory.get_host( "anotherhost").data.override_data == "override_data"
def __init__(self, make_names_data=make_names_data_local, general_facts={}, fail_percent=100, connect_timeout=5, ): hosts = [] groups = defaultdict(lambda: ([], {})) names_data = make_names_data() if callable( make_names_data) else make_names_data for name, data, group_names in names_data: hosts.append((name, data)) for group_name in group_names: if name not in groups[group_name][0]: groups[group_name][0].append(name) for host in hosts: for fact_name, fact in general_facts.items(): host[1][fact_name] = fact # First we setup some inventory we want to target # the first argument is a tuple of (list all all hosts, global/ALL data) self.inventory = Inventory((hosts, {}), **groups) # Now we create a new config (w/optional args) self.config = Config( FAIL_PERCENT=fail_percent, CONNECT_TIMEOUT=connect_timeout, ) # Setup the pyinfra state for this deploy self.state = State(self.inventory, self.config)
def make_inventory(hosts=('somehost', 'anotherhost'), **kwargs): return Inventory((hosts, {}), test_group=(['somehost'], { 'group_data': 'hello world' }), ssh_user='******', **kwargs)
def make_inventory(hosts=("somehost", "anotherhost"), **kwargs): override_data = kwargs.pop("override_data", {}) if "ssh_user" not in override_data: override_data["ssh_user"] = "******" return Inventory( (hosts, {}), override_data=override_data, test_group=( [ "somehost", ], { "group_data": "hello world", }, ), **kwargs, )
def test_create_inventory_host_data(self): default_data = {"default_data": "default_data", "host_data": "none"} somehost_data = {"host_data": "host_data"} inventory = Inventory(( [("somehost", somehost_data), "anotherhost"], default_data, ), ) assert inventory.get_data() == default_data assert inventory.get_host_data("somehost") == somehost_data assert inventory.get_host_data("anotherhost") == {} assert inventory.get_host("anotherhost").data.host_data == "none"
def __init__(self): self.inventory = Inventory(([], {})) self.config = Config()
def test_create_inventory(self): inventory = Inventory((["somehost", "anotherhost", "anotherotherhost"], {})) assert len(inventory) == 3
logging.basicConfig(level=logging.CRITICAL) # Make our hosts and groups data (using the Vagrant connector in this case) print("Loading Vagrant config...") hosts = [] groups = defaultdict(lambda: ([], {})) for name, data, group_names in make_names_data(): hosts.append((name, data)) for group_name in group_names: if name not in groups[group_name][0]: groups[group_name][0].append(name) # First we setup some inventory we want to target # the first argument is a tuple of (list all all hosts, global/ALL data) inventory = Inventory((hosts, {}), **groups) # Now we create a new config (w/optional args) config = Config( FAIL_PERCENT=81, CONNECT_TIMEOUT=5, ) # Setup the pyinfra state for this deploy state = State(inventory, config) state.add_callback_handler(StateCallback()) # Connect to all the hosts print("Connecting...") connect_all(state)
def make_inventory(inventory_filename, deploy_dir=None, limit=None, ssh_user=None, ssh_key=None, ssh_key_password=None, ssh_port=None, ssh_password=None): ''' Builds a ``pyinfra.api.Inventory`` from the filesystem. If the file does not exist and doesn't contain a / attempts to use that as the only hostname. ''' if ssh_port is not None: ssh_port = int(ssh_port) file_groupname = None try: attrs = exec_file(inventory_filename, return_locals=True) groups = { key: value for key, value in six.iteritems(attrs) if key.isupper() } # Used to set all the hosts to an additional group - that of the filename # ie inventories/dev.py means all the hosts are in the dev group, if not present file_groupname = path.basename(inventory_filename).split( '.')[0].upper() except IOError as e: # If a /, definitely not a hostname if '/' in inventory_filename: raise CliError('{0}: {1}'.format(e.strerror, inventory_filename)) # Otherwise we assume the inventory is actually a hostname or list of hostnames groups = {'ALL': inventory_filename.split(',')} all_data = {} if 'ALL' in groups: all_hosts = groups.pop('ALL') if isinstance(all_hosts, tuple): all_hosts, all_data = all_hosts # Build ALL out of the existing hosts if not defined else: all_hosts = [] for hosts in groups.values(): # Groups can be a list of hosts or tuple of (hosts, data) hosts = hosts[0] if isinstance(hosts, tuple) else hosts for host in hosts: # Hosts can be a hostname or tuple of (hostname, data) hostname = host[0] if isinstance(host, tuple) else host if hostname not in all_hosts: all_hosts.append(hostname) groups['ALL'] = (all_hosts, all_data) # Apply the filename group if not already defined if file_groupname and file_groupname not in groups: groups[file_groupname] = all_hosts # In pyinfra an inventory is a combination of (hostnames + data). However, in CLI # mode we want to be define this in separate files (inventory / group data). The # issue is we want inventory access within the group data files - but at this point # we're not ready to make an Inventory. So here we just create a fake one, and attach # it to pseudo_inventory while we import the data files. fake_groups = { # In API mode groups *must* be tuples of (hostnames, data) name: group if isinstance(group, tuple) else (group, {}) for name, group in six.iteritems(groups) } fake_inventory = Inventory((all_hosts, all_data), **fake_groups) pseudo_inventory.set(fake_inventory) # For each group load up any data for name, hosts in six.iteritems(groups): data = {} if isinstance(hosts, tuple): hosts, data = hosts data_filename = path.join(deploy_dir, 'group_data', '{0}.py'.format(name.lower())) logger.debug('Looking for group data: {0}'.format(data_filename)) if path.exists(data_filename): # Read the files locals into a dict attrs = exec_file(data_filename, return_locals=True) data.update({ key: value for key, value in six.iteritems(attrs) if isinstance(value, ALLOWED_DATA_TYPES) and not key.startswith('_') and key.islower() }) # Attach to group object groups[name] = (hosts, data) # Reset the pseudo inventory pseudo_inventory.reset() # Apply any limit to all_hosts if limit: # Limits can be groups limit_groupname = limit.upper() if limit_groupname in groups: all_hosts = [ host[0] if isinstance(host, tuple) else host for host in groups[limit_groupname][0] ] # Or hostnames w/*wildcards else: all_hosts = [ host for host in all_hosts if (isinstance(host, tuple) and fnmatch(host[0], limit)) or (isinstance(host, six.string_types) and fnmatch(host, limit)) ] # Reassign the ALL group w/limit groups['ALL'] = (all_hosts, all_data) return Inventory(groups.pop('ALL'), ssh_user=ssh_user, ssh_key=ssh_key, ssh_key_password=ssh_key_password, ssh_port=ssh_port, ssh_password=ssh_password, **groups), file_groupname and file_groupname.lower()
logging.basicConfig(level=logging.WARNING) logging.getLogger('pyinfra').setLevel(logging.INFO) # Make our hosts and groups data (using the Vagrant connector in this case) hosts = [] groups = defaultdict(lambda: ([], {})) for name, data, group_names in make_names_data(): hosts.append((name, data)) for group_name in group_names: if name not in groups[group_name][0]: groups[group_name][0].append(name) # First we setup some inventory we want to target # the first argument is a tuple of (list all all hosts, global/ALL data) inventory = Inventory((hosts, {}), **groups) # Now we create a new config (w/optional args) config = Config( FAIL_PERCENT=81, CONNECT_TIMEOUT=5, ) # Setup the pyinfra state for this deploy state = State(inventory, config) # Connect to all the hosts print('Connecting...') connect_all(state) # Start adding operations
logging.basicConfig(level=logging.WARNING) logging.getLogger('pyinfra').setLevel(logging.INFO) # First we setup some inventory we want to target # the first argument is a tuple of (list all all hosts, global/ALL data) inventory = Inventory( ( [ 'centos6.pyinfra', # Host-specific data can be attached in inventory ('centos7.pyinfra', { 'systemd': True }), 'ubuntu14.pyinfra', 'debian7.pyinfra', 'openbsd58.pyinfra' ], {}), bsd=( ['openbsd57.pyinfra'], { # Group-specific data can be attached like so 'app_dir': '/opt/pyinfra/bsd' }), centos=(['centos6.pyinfra', 'centos7.pyinfra'], {}), ssh_user='******', ssh_key='./files/insecure_private_key') # Now we create a new config (w/optional args) config = Config(FAIL_PERCENT=50, TIMEOUT=1) # Setup the pyinfra state for this deploy
def test_create_inventory_data(self): default_data = {"default_data": "default_data"} inventory = Inventory((["somehost"], default_data)) assert inventory.get_data() == default_data assert inventory.get_host_data("somehost") == {}
def test_context_inventory_iter(self): inventory_obj = Inventory(("host", "anotherhost")) ctx_inventory.set(inventory_obj) assert ctx_inventory.isset() is True assert list(iter(inventory)) == list(iter(inventory_obj))
def test_context_inventory_len(self): inventory_obj = Inventory(("host", "anotherhost")) ctx_inventory.set(inventory_obj) assert ctx_inventory.isset() is True assert len(inventory) == len(inventory_obj)
def test_pseudo_inventory_iter(self): inventory = Inventory(('host', 'anotherhost')) pseudo_inventory.set(inventory) assert pseudo_inventory.isset() is True assert list(iter(pseudo_inventory)) == list(iter(inventory))
def test_pseudo_inventory_len(self): inventory = Inventory(('host', 'anotherhost')) pseudo_inventory.set(inventory) assert pseudo_inventory.isset() is True assert len(pseudo_inventory) == len(inventory)