Example #1
0
def test_merge_dicts():
    # Example taken from python-anyconfig/anyconfig/__init__.py
    a = {'b': [{'c': 0}, {'c': 2}], 'd': {'e': 'aaa', 'f': 3}}
    b = {'a': 1, 'b': [{'c': 3}], 'd': {'e': 'bbb'}}
    expected = {'a': 1,
                'b': [{'c': 0}, {'c': 2}, {'c': 3}],
                'd': {'e': "bbb",
                      'f': 3}}
    result = util.merge_dicts(a, b)

    assert expected == result
Example #2
0
    def _reget_config(self):
        """
        Perform the same prioritized recursive merge from `get_config`.

        Interpolates the ``keep_string`` left behind in the original
        ``get_config`` call.  This is probably __very__ bad.

        :return: dict
        """
        env = util.merge_dicts(os.environ, self.env)
        env = set_env_from_file(env, self.env_file)

        return self._combine(env=env)
Example #3
0
def validate(c):
    """Perform schema validation."""
    schema = base_schema

    # Dependency
    if c['dependency']['name'] == 'shell':
        schema = util.merge_dicts(schema, dependency_command_nullable_schema)

    # Driver
    if c['driver']['name'] == 'docker':
        schema = util.merge_dicts(schema, platforms_docker_schema)
    elif c['driver']['name'] == 'podman':
        schema = util.merge_dicts(schema, platforms_podman_schema)

    # Verifier
    schema = util.merge_dicts(schema,
                              api.verifiers()[c['verifier']['name']].schema())

    v = Validator(allow_unknown=True)
    v.validate(c, schema)

    return v.errors
Example #4
0
    def default_env(self):
        env = util.merge_dicts(os.environ.copy(), self._config.env)
        env = util.merge_dicts(
            env, {
                'ANSIBLE_CONFIG':
                self._config.provisioner.config_file,
                'ANSIBLE_ROLES_PATH':
                ':'.join([
                    util.abs_path(
                        os.path.join(self._config.scenario.ephemeral_directory,
                                     'roles')),
                    util.abs_path(
                        os.path.join(self._config.project_directory,
                                     os.path.pardir)),
                ]),
                'ANSIBLE_LIBRARY':
                ':'.join([
                    self._get_libraries_directory(),
                    util.abs_path(
                        os.path.join(self._config.scenario.ephemeral_directory,
                                     'library')),
                    util.abs_path(
                        os.path.join(self._config.project_directory,
                                     'library')),
                ]),
                'ANSIBLE_FILTER_PLUGINS':
                ':'.join([
                    self._get_filter_plugin_directory(),
                    util.abs_path(
                        os.path.join(self._config.scenario.ephemeral_directory,
                                     'plugins', 'filters')),
                    util.abs_path(
                        os.path.join(self._config.project_directory, 'plugins',
                                     'filters')),
                ]),
            })
        env = util.merge_dicts(env, self._config.env)

        return env
Example #5
0
def validate(c):
    """Perform schema validation."""
    schema = base_schema

    # Dependency
    if c["dependency"]["name"] == "shell":
        schema = util.merge_dicts(schema, dependency_command_nullable_schema)

    # Driver
    if c["driver"]["name"] == "docker":
        schema = util.merge_dicts(schema, platforms_docker_schema)
    elif c["driver"]["name"] == "podman":
        schema = util.merge_dicts(schema, platforms_podman_schema)

    # Verifier
    schema = util.merge_dicts(schema,
                              api.verifiers()[c["verifier"]["name"]].schema())

    v = Validator(allow_unknown=True)
    v.validate(c, schema)

    return v.errors
Example #6
0
 def default_options(self):
     general = super(Roles, self).default_options
     specific = util.merge_dicts(
         general,
         {
             "role-file":
             os.path.join(self._config.scenario.directory,
                          "requirements.yml"),
             "roles-path":
             os.path.join(self._config.scenario.ephemeral_directory,
                          "roles"),
         },
     )
     return specific
Example #7
0
def _config(_molecule_file, request):
    with open(_molecule_file) as f:
        d = util.safe_load(f)
    if hasattr(request, "param"):
        if isinstance(request.getfixturevalue(request.param), str):
            d2 = util.safe_load(request.getfixturevalue(request.param))
        else:
            d2 = request.getfixturevalue(request.param)
        # print(100, d)
        # print(200, d2)
        d = util.merge_dicts(d, d2)
        # print(300, d)

    return d
Example #8
0
def molecule_data(
        _molecule_dependency_galaxy_section_data,
        _molecule_driver_section_data, _molecule_lint_section_data,
        _molecule_platforms_section_data, _molecule_provisioner_section_data,
        _molecule_scenario_section_data, _molecule_verifier_section_data):

    fixtures = [
        _molecule_dependency_galaxy_section_data,
        _molecule_driver_section_data, _molecule_lint_section_data,
        _molecule_platforms_section_data, _molecule_provisioner_section_data,
        _molecule_scenario_section_data, _molecule_verifier_section_data
    ]

    return functools.reduce(lambda x, y: util.merge_dicts(x, y), fixtures)
Example #9
0
    def execute(self, exit=True):
        ansible = ansible_playbook.AnsiblePlaybook(
            self._molecule.config.config['ansible'], _env=self._molecule._env)

        testinfra_options = util.merge_dicts(
            self._molecule._driver.testinfra_args,
            self._molecule.config.config['testinfra'])
        testinfra_options['env'] = ansible.env
        testinfra_options['debug'] = self._molecule._args.get('--debug', False)
        testinfra_options['sudo'] = self._molecule._args.get('--sudo', False)

        tests_glob = self._get_tests()
        if len(tests_glob) > 0:
            self._testinfra(tests_glob, **testinfra_options)
Example #10
0
def config_instance(
    molecule_file_fixture: str, molecule_data, request
) -> Generator[config.Config, None, None]:
    mdc = copy.deepcopy(molecule_data)
    if hasattr(request, "param"):
        mdc = util.merge_dicts(mdc, request.getfixturevalue(request.param))
    write_molecule_file(molecule_file_fixture, mdc)

    _environ = dict(os.environ)
    c = config.Config(molecule_file_fixture)
    c.command_args = {"subcommand": "test"}
    yield c
    # restore environ which can be modified by Config()
    os.environ.clear()
    os.environ.update(_environ)
Example #11
0
    def execute(self, exit=True):
        ansible = ansible_playbook.AnsiblePlaybook(
            self._molecule.config.config['ansible'],
            _env=self._molecule._env)

        testinfra_options = util.merge_dicts(
            self._molecule._driver.testinfra_args,
            self._molecule.config.config['testinfra'])
        testinfra_options['env'] = ansible.env
        testinfra_options['debug'] = self._molecule._args.get('--debug', False)
        testinfra_options['sudo'] = self._molecule._args.get('--sudo', False)

        tests_glob = self._get_tests()
        if len(tests_glob) > 0:
            self._testinfra(tests_glob, **testinfra_options)
Example #12
0
    def bake(self):
        """
        Bake an ``ansible-playbook`` command so it's ready to execute and \
        returns ``None``.

        :return: None
        """
        if not self._playbook:
            return

        # Pass a directory as inventory to let Ansible merge the multiple
        # inventory sources located under
        self.add_cli_arg("inventory",
                         self._config.provisioner.inventory_directory)
        options = util.merge_dicts(self._config.provisioner.options, self._cli)
        verbose_flag = util.verbose_flag(options)
        if self._playbook != self._config.provisioner.playbooks.converge:
            if options.get("become"):
                del options["become"]

        # We do not pass user-specified Ansible arguments to the create and
        # destroy invocations because playbooks involved in those two
        # operations are not always provided by end users. And in those cases,
        # custom Ansible arguments can break the creation and destruction
        # processes.
        #
        # If users need to modify the creation of deletion, they can supply
        # custom playbooks and specify them in the scenario configuration.
        if self._config.action not in ["create", "destroy"]:
            ansible_args = list(self._config.provisioner.ansible_args) + list(
                self._config.ansible_args)
        else:
            ansible_args = []

        self._ansible_command = util.BakedCommand(
            cmd=[
                "ansible-playbook",
                *util.dict2args(options),
                *util.bool2args(verbose_flag),
                *ansible_args,
                self._playbook,  # must always go last
            ],
            cwd=self._config.scenario.directory,
            env=self._env,
        )
Example #13
0
    def bake(self):
        """
        Bake an ``ansible-playbook`` command so it's ready to execute and \
        returns ``None``.

        :return: None
        """
        if not self._playbook:
            return

        # Pass a directory as inventory to let Ansible merge the multiple
        # inventory sources located under
        self.add_cli_arg("inventory",
                         self._config.provisioner.inventory_directory)
        options = util.merge_dicts(self._config.provisioner.options, self._cli)
        verbose_flag = util.verbose_flag(options)
        if self._playbook != self._config.provisioner.playbooks.converge:
            if options.get("become"):
                del options["become"]

        ansible_args = list(self._config.provisioner.ansible_args) + list(
            self._config.ansible_args)

        # if ansible_args:
        #     if self._config.action not in ["create", "destroy"]:
        #         # inserts ansible_args at index 1
        #         self._ansible_command.cmd.extend(ansible_args)

        self._ansible_command = util.BakedCommand(
            cmd=[
                "ansible-playbook",
                *util.dict2args(options),
                *util.bool2args(verbose_flag),
                *ansible_args,
                self._playbook,  # must always go last
            ],
            cwd=self._config.scenario.directory,
            env=self._env,
            stdout=self._out,
            stderr=self._err,
        )
Example #14
0
    def bake(self):
        """
        Bake ansible-galaxy command so it's ready to execute.

        :return: None
        """
        requirements_file = self._config['ansible']['requirements_file']
        roles_path = os.path.join(self._config['molecule']['molecule_dir'],
                                  'roles')
        galaxy_default_options = {
            'force': True,
            'role-file': requirements_file,
            'roles-path': roles_path
        }
        galaxy_options = util.merge_dicts(galaxy_default_options,
                                          self._config['ansible']['galaxy'])

        self._galaxy = sh.ansible_galaxy.bake('install',
                                              _env=self.env,
                                              _out=self.out,
                                              _err=self.err,
                                              **galaxy_options)
Example #15
0
    def _combine(self):
        """
        Perform a prioritized recursive merge of the `molecule_file` with
        defaults, interpolate the result with environment variables, and
        returns a new dict.

        :return: dict
        """
        i = interpolation.Interpolator(interpolation.TemplateWithDefaults,
                                       os.environ)

        base = self._get_defaults()
        with util.open_file(self.molecule_file) as stream:
            try:
                interpolated_config = i.interpolate(stream.read())
                base = util.merge_dicts(base,
                                        util.safe_load(interpolated_config))
            except interpolation.InvalidInterpolation as e:
                msg = ("parsing config file '{}'.\n\n"
                       '{}\n{}'.format(self.molecule_file, e.place, e.string))
                util.sysexit_with_message(msg)

        return base
Example #16
0
 def ansible_connection_options(self, instance_name):
     try:
         d = self._get_instance_config(instance_name)
         plat_conn_opts = next(
             (item for item in self._config.config.get("platforms", [])
              if item["name"] == instance_name),
             {},
         ).get("connection_options", {})
         conn_opts = util.merge_dicts(
             {
                 "ansible_user":
                 d["user"],
                 "ansible_host":
                 d["address"],
                 "ansible_port":
                 d["port"],
                 "ansible_private_key_file":
                 d["identity_file"],
                 "connection":
                 "ssh",
                 "ansible_ssh_common_args":
                 " ".join(self.ssh_connection_options),
             },
             plat_conn_opts,
         )
         if conn_opts.get("ansible_connection") == "winrm" and (
                 not conn_opts.get("ansible_password")):
             conn_opts[
                 "ansible_password"] = self._get_windows_instance_pass(
                     d["instance_ids"][0], d["identity_file"])
         return conn_opts
     except StopIteration:
         return {}
     except IOError:
         # Instance has yet to be provisioned , therefore the
         # instance_config is not on disk.
         return {}
Example #17
0
    def bake(self):
        """
        Bake an ``ansible-playbook`` command so it's ready to execute and \
        returns ``None``.

        :return: None
        """
        if not self._playbook:
            return

        # Pass a directory as inventory to let Ansible merge the multiple
        # inventory sources located under
        self.add_cli_arg("inventory",
                         self._config.provisioner.inventory_directory)
        options = util.merge_dicts(self._config.provisioner.options, self._cli)
        verbose_flag = util.verbose_flag(options)
        if self._playbook != self._config.provisioner.playbooks.converge:
            if options.get("become"):
                del options["become"]

        self._ansible_command = sh.ansible_playbook.bake(
            options,
            self._playbook,
            *verbose_flag,
            _cwd=self._config.scenario.directory,
            _env=self._env,
            _out=self._out,
            _err=self._err)

        ansible_args = list(self._config.provisioner.ansible_args) + list(
            self._config.ansible_args)

        if ansible_args:
            if self._config.action not in ["create", "destroy"]:
                self._ansible_command = self._ansible_command.bake(
                    ansible_args)
Example #18
0
 def env(self):
     return util.merge_dicts(
         self.default_env, self._config.config['verifier']['env']
     )
Example #19
0
 def options(self):
     return util.merge_dicts(
         self.default_options, self._config.config['verifier']['options']
     )
Example #20
0
def test_merge_dicts(a, b, x):
    assert x == util.merge_dicts(a, b)
Example #21
0
 def env(self):
     return util.merge_dicts(self.default_env,
                             self._config.config['dependency']['env'])
Example #22
0
 def options(self):
     return util.merge_dicts(self.default_options,
                             self._config.config['dependency']['options'])
Example #23
0
    def default_env(self):
        env = util.merge_dicts(os.environ.copy(), self._config.env)
        env = util.merge_dicts(env, self._config.provisioner.env)

        return env
Example #24
0
    def connection_options(self, instance_name):
        d = self._config.driver.ansible_connection_options(instance_name)

        return util.merge_dicts(
            d, self._config.config["provisioner"]["connection_options"]
        )
Example #25
0
 def config_options(self):
     return util.merge_dicts(
         self.default_config_options,
         self._config.config["provisioner"]["config_options"],
     )
Example #26
0
def validate(c):
    schema = copy.deepcopy(base_schema)

    # Dependency
    if c['dependency']['name'] == 'shell':
        util.merge_dicts(schema, dependency_command_nullable_schema)

    # Driver
    util.merge_dicts(schema, platforms_base_schema)
    if c['driver']['name'] == 'docker':
        util.merge_dicts(schema, platforms_docker_schema)
    elif c['driver']['name'] == 'vagrant':
        util.merge_dicts(schema, driver_vagrant_provider_section_schema)
        util.merge_dicts(schema, platforms_vagrant_schema)
    else:
        util.merge_dicts(schema, platforms_base_schema)

    # Verifier
    if c['verifier']['name'] == 'goss':
        util.merge_dicts(schema, verifier_options_readonly_schema)
        util.merge_dicts(schema, verifier_goss_mutually_exclusive_schema)
    elif c['verifier']['name'] == 'inspec':
        util.merge_dicts(schema, verifier_options_readonly_schema)
        util.merge_dicts(schema, verifier_inspec_mutually_exclusive_schema)
    elif c['verifier']['name'] == 'testinfra':
        util.merge_dicts(schema, verifier_testinfra_mutually_exclusive_schema)

    v = Validator(allow_unknown=True)
    v.validate(c, schema)

    return v.errors
Example #27
0
def _config(_molecule_file, request):
    d = util.safe_load(open(_molecule_file))
    if hasattr(request, 'param'):
        d = util.merge_dicts(d, request.getfixturevalue(request.param))

    return d
Example #28
0
 def options(self):
     return util.merge_dicts(self.default_options,
                             self._config.config["dependency"]["options"])
Example #29
0
 def default_env(self):
     return util.merge_dicts(os.environ.copy(), self._config.env)
Example #30
0
def molecule_docker_config(molecule_section_data, docker_section_data,
                           ansible_section_data):
    return reduce(
        lambda x, y: util.merge_dicts(x, y),
        [molecule_section_data, docker_section_data, ansible_section_data])
Example #31
0
    def login_options(self, instance_name):
        d = {'instance': instance_name}

        return util.merge_dicts(d, self._get_instance_config(instance_name))
Example #32
0
def molecule_openstack_config(molecule_section_data, openstack_section_data,
                              ansible_section_data):
    return reduce(
        lambda x, y: util.merge_dicts(x, y),
        [molecule_section_data, openstack_section_data, ansible_section_data])
Example #33
0
 def env(self):
     return util.merge_dicts(self.default_env,
                             self._config.config["dependency"]["env"])
Example #34
0
 def env(self):
     return util.merge_dicts(self._config.env, os.environ)