Example #1
0
    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"
Example #2
0
    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"
Example #3
0
    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"
Example #4
0
    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)
Example #5
0
def make_inventory(hosts=('somehost', 'anotherhost'), **kwargs):
    return Inventory((hosts, {}),
                     test_group=(['somehost'], {
                         'group_data': 'hello world'
                     }),
                     ssh_user='******',
                     **kwargs)
Example #6
0
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,
    )
Example #7
0
    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"
Example #8
0
 def __init__(self):
     self.inventory = Inventory(([], {}))
     self.config = Config()
Example #9
0
 def test_create_inventory(self):
     inventory = Inventory((["somehost", "anotherhost",
                             "anotherotherhost"], {}))
     assert len(inventory) == 3
Example #10
0
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)
Example #11
0
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()
Example #12
0
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
Example #13
0
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
Example #14
0
 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") == {}
Example #15
0
    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))
Example #16
0
    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)