Beispiel #1
0
def role(
    ctx,
    dependency_name,
    driver_name,
    lint_name,
    provisioner_name,
    role_name,
    verifier_name,
):  # pragma: no cover
    """ Initialize a new role for use with Molecule. """
    command_args = {
        'dependency_name': dependency_name,
        'driver_name': driver_name,
        'lint_name': lint_name,
        'provisioner_name': provisioner_name,
        'role_name': role_name,
        'scenario_name': command_base.MOLECULE_DEFAULT_SCENARIO_NAME,
        'subcommand': __name__,
        'verifier_name': verifier_name,
    }

    command_args['verifier_lint_name'] = api.verifiers()[verifier_name].default_linter

    r = Role(command_args)
    r.execute()
Beispiel #2
0
def scenario(
    ctx,
    dependency_name,
    driver_name,
    lint_name,
    provisioner_name,
    role_name,
    scenario_name,
    verifier_name,
    driver_template,
):  # pragma: no cover
    """Initialize a new scenario for use with Molecule."""
    command_args = {
        'dependency_name': dependency_name,
        'driver_name': driver_name,
        'lint_name': lint_name,
        'provisioner_name': provisioner_name,
        'role_name': role_name,
        'scenario_name': scenario_name,
        'subcommand': __name__,
        'verifier_name': verifier_name,
    }

    command_args['verifier_lint_name'] = api.verifiers(
    )[verifier_name].default_linter

    driver_template = driver_template or os.environ.get(
        'MOLECULE_SCENARIO_DRIVER_TEMPLATE', None)
    if driver_template:
        command_args['driver_template'] = driver_template

    s = Scenario(command_args)
    s.execute()
Beispiel #3
0
def validate(c):
    schema = copy.deepcopy(base_schema)

    util.merge_dicts(schema, base_schema)

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

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

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

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

    return v.errors
Beispiel #4
0
    def execute(self):
        """
        Execute the actions necessary to perform a `molecule init scenario` and \
        returns None.

        :return: None
        """
        scenario_name = self._command_args["scenario_name"]
        role_name = os.getcwd().split(os.sep)[-1]
        role_directory = util.abs_path(os.path.join(os.getcwd(), os.pardir))

        msg = "Initializing new scenario {}...".format(scenario_name)
        LOG.info(msg)
        molecule_directory = config.molecule_directory(
            os.path.join(role_directory, role_name)
        )
        scenario_directory = os.path.join(molecule_directory, scenario_name)

        if os.path.isdir(scenario_directory):
            msg = (
                "The directory molecule/{} exists. " "Cannot create new scenario."
            ).format(scenario_name)
            util.sysexit_with_message(msg)

        driver_template = api.drivers()[
            self._command_args["driver_name"]
        ].template_dir()
        if "driver_template" in self._command_args:
            self._validate_template_dir(self._command_args["driver_template"])
            cli_driver_template = "{driver_template}/{driver_name}".format(
                **self._command_args
            )
            if os.path.isdir(cli_driver_template):
                driver_template = cli_driver_template
            else:
                LOG.warning(
                    "Driver not found in custom template directory({}), "
                    "using the default template instead".format(cli_driver_template)
                )
        scenario_base_directory = os.path.join(role_directory, role_name)
        templates = [
            driver_template,
            api.verifiers()[self._command_args["verifier_name"]].template_dir(),
        ]
        self._process_templates("molecule", self._command_args, role_directory)
        for template in templates:
            self._process_templates(
                template, self._command_args, scenario_base_directory
            )

        role_directory = os.path.join(role_directory, role_name)
        msg = "Initialized scenario in {} successfully.".format(scenario_directory)
        LOG.success(msg)
Beispiel #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)

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

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

    return v.errors
Beispiel #6
0
    def execute(self):
        """
        Execute the actions necessary to perform a `molecule init role` and
        returns None.

        :return: None
        """

        role_name = self._command_args['role_name']
        role_directory = os.getcwd()
        msg = 'Initializing new role {}...'.format(role_name)
        LOG.info(msg)

        if os.path.isdir(role_name):
            msg = ('The directory {} exists. ' 'Cannot create new role.').format(
                role_name
            )
            util.sysexit_with_message(msg)

        try:
            cmd = ["ansible-galaxy", "init", "-v", "--offline", role_name]
            subprocess.check_output(
                cmd, stderr=subprocess.STDOUT, universal_newlines=True
            )
        except Exception as e:
            util.sysexit_with_message(
                "Galaxy failed to create role: %s: %s" % (e, e.output)
            )

        scenario_base_directory = os.path.join(role_directory, role_name)
        templates = [
            api.drivers()[self._command_args['driver_name']].template_dir(),
            api.verifiers()[self._command_args['verifier_name']].template_dir(),
        ]
        for template in templates:
            self._process_templates(
                template, self._command_args, scenario_base_directory
            )
        self._process_templates('molecule', self._command_args, role_directory)

        role_directory = os.path.join(role_directory, role_name)
        msg = 'Initialized role in {} successfully.'.format(role_directory)
        LOG.success(msg)
Beispiel #7
0
def validate(c):
    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
Beispiel #8
0
    def execute(self):
        """
        Execute the actions necessary to perform a `molecule init role` and \
        returns None.

        :return: None
        """
        role_name = self._command_args["role_name"]
        role_directory = os.getcwd()
        msg = "Initializing new role {}...".format(role_name)
        LOG.info(msg)

        if os.path.isdir(role_name):
            msg = ("The directory {} exists. " "Cannot create new role.").format(
                role_name
            )
            util.sysexit_with_message(msg)

        cmd = ["ansible-galaxy", "init", "-v", "--offline", role_name]
        result = util.run_command(cmd)

        if result.returncode != 0:
            util.sysexit_with_message(
                "Galaxy failed to create role, returned %s" % result.returncode
            )

        scenario_base_directory = os.path.join(role_directory, role_name)
        templates = [
            api.drivers()[self._command_args["driver_name"]].template_dir(),
            api.verifiers()[self._command_args["verifier_name"]].template_dir(),
        ]
        self._process_templates("molecule", self._command_args, role_directory)
        for template in templates:
            self._process_templates(
                template, self._command_args, scenario_base_directory
            )

        role_directory = os.path.join(role_directory, role_name)
        msg = "Initialized role in {} successfully.".format(role_directory)
        LOG.success(msg)
Beispiel #9
0
    def execute(self):
        """
        Execute the actions necessary to perform a `molecule init role` and
        returns None.

        :return: None
        """

        role_name = self._command_args['role_name']
        role_directory = os.getcwd()
        msg = 'Initializing new role {}...'.format(role_name)
        LOG.info(msg)

        if os.path.isdir(role_name):
            msg = ('The directory {} exists. '
                   'Cannot create new role.').format(role_name)
            util.sysexit_with_message(msg)

        template_directory = ''
        if 'template' in self._command_args.keys():
            template_directory = self._command_args['template']
        else:
            template_directory = 'role'
        self._process_templates(template_directory, self._command_args,
                                role_directory)
        scenario_base_directory = os.path.join(role_directory, role_name)
        templates = [
            'scenario/driver/{driver_name}'.format(**self._command_args),
            api.verifiers()[
                self._command_args['verifier_name']].template_dir(),
        ]
        for template in templates:
            self._process_templates(template, self._command_args,
                                    scenario_base_directory)
        self._process_templates('molecule', self._command_args, role_directory)

        role_directory = os.path.join(role_directory, role_name)
        msg = 'Initialized role in {} successfully.'.format(role_directory)
        LOG.success(msg)
Beispiel #10
0
def pre_validate_base_schema(env, keep_string):
    return {
        'dependency': {
            'type': 'dict',
            'schema': {
                'name': {
                    'type': 'string',
                    'molecule_env_var': True,
                    'allowed': ['galaxy', 'gilt', 'shell'],
                }
            },
        },
        'driver': {
            'type': 'dict',
            'schema': {
                'name': {
                    'type': 'string',
                    'molecule_env_var': True,
                    'allowed': api.drivers(),
                    # NOTE(retr0h): Some users use an environment variable to
                    # change the driver name.  May add this coercion to rest of
                    # config using allowed validation.
                    'coerce': (str, functools.partial(coerce_env, env, keep_string)),
                }
            },
        },
        'lint': {
            'type': 'dict',
            'schema': {
                'name': {
                    'type': 'string',
                    'molecule_env_var': True,
                    'allowed': ['yamllint'],
                }
            },
        },
        'platforms': {
            'type': 'list',
            'schema': {
                'type': 'dict',
                'schema': {
                    'registry': {
                        'type': 'dict',
                        'schema': {
                            'credentials': {
                                'type': 'dict',
                                'schema': {'password': {'type': 'string'}},
                            }
                        },
                    }
                },
            },
        },
        'provisioner': {
            'type': 'dict',
            'schema': {
                'name': {
                    'type': 'string',
                    'molecule_env_var': True,
                    'allowed': ['ansible'],
                },
                'lint': {
                    'type': 'dict',
                    'schema': {
                        'name': {
                            'type': 'string',
                            'molecule_env_var': True,
                            'allowed': ['ansible-lint'],
                        }
                    },
                },
            },
        },
        'scenario': {
            'type': 'dict',
            'schema': {'name': {'type': 'string', 'molecule_env_var': True}},
        },
        'verifier': {
            'type': 'dict',
            'schema': {
                'name': {
                    'type': 'string',
                    'molecule_env_var': True,
                    'allowed': api.verifiers(),
                },
                'lint': {
                    'type': 'dict',
                    'schema': {
                        'name': {
                            'type': 'string',
                            'molecule_env_var': True,
                            'allowed': [
                                'flake8',
                                'pre-commit',
                                'rubocop',
                                'yamllint',
                                'ansible-lint',
                            ],
                        }
                    },
                },
            },
        },
    }
Beispiel #11
0
    def execute(self):
        """
        Execute the actions necessary to perform a `molecule init role` and \
        returns None.

        :return: None
        """
        namespace = None
        role_name = self._command_args["role_name"]
        role_directory = os.getcwd()

        # outside collections our tooling needs a namespace.
        if not os.path.isfile("../galaxy.yml"):
            name_re = re.compile(r"^[a-z][a-z0-9_]+\.[a-z][a-z0-9_]+$")

            if not name_re.match(role_name):
                util.sysexit_with_message(
                    "Outside collections you must mention role "
                    "namespace like: molecule init role 'acme.myrole'. Be sure "
                    "you use only lowercase characters and underlines. See https://galaxy.ansible.com/docs/contributing/creating_role.html"
                )
            namespace, role_name = role_name.split(".")

        msg = f"Initializing new role {role_name}..."
        LOG.info(msg)

        if os.path.isdir(role_name):
            msg = f"The directory {role_name} exists. Cannot create new role."
            util.sysexit_with_message(msg)

        cmd = ["ansible-galaxy", "init", "-v", "--offline", role_name]
        result = util.run_command(cmd)

        if result.returncode != 0:
            util.sysexit_with_message(
                f"Galaxy failed to create role, returned {result.returncode!s}"
            )

        if namespace:
            # we need to inject namespace info into meta/main.yml
            cmd = [
                "ansible",
                "localhost",
                "-o",  # one line output
                "-m",
                "lineinfile",
                "-a",
                f'path={role_name}/meta/main.yml line="  namespace: {namespace}" insertafter="  author: your name"',
            ]
            util.run_command(cmd, check=True)

        scenario_base_directory = os.path.join(role_directory, role_name)
        templates = [
            api.drivers()[self._command_args["driver_name"]].template_dir(),
            api.verifiers()[
                self._command_args["verifier_name"]].template_dir(),
        ]
        self._process_templates("molecule", {
            **self._command_args, "role_name": role_name
        }, role_directory)
        for template in templates:
            self._process_templates(template, self._command_args,
                                    scenario_base_directory)

        role_directory = os.path.join(role_directory, role_name)
        msg = f"Initialized role in {role_directory} successfully."
        LOG.info(msg)
Beispiel #12
0
 def verifier(self):
     return api.verifiers(self).get(self.config["verifier"]["name"], None)
Beispiel #13
0
def test_api_verifiers():
    x = ["testinfra", "ansible"]

    assert all(elem in api.verifiers() for elem in x)
Beispiel #14
0
def test_api_verifiers():
    x = ['testinfra', 'ansible']

    assert all(elem in api.verifiers() for elem in x)
Beispiel #15
0
@click.option(
    "--lint-name",
    type=click.Choice(["yamllint"]),
    default="yamllint",
    help="Name of lint to initialize. (yamllint)",
)
@click.option(
    "--provisioner-name",
    type=click.Choice(["ansible"]),
    default="ansible",
    help="Name of provisioner to initialize. (ansible)",
)
@click.argument("ROLE-NAME", required=True)
@click.option(
    "--verifier-name",
    type=click.Choice([str(s) for s in api.verifiers()]),
    default="ansible",
    help="Name of verifier to initialize. (ansible)",
)
def role(
    ctx,
    dependency_name,
    driver_name,
    lint_name,
    provisioner_name,
    role_name,
    verifier_name,
):  # pragma: no cover
    """Initialize a new role for use with Molecule."""
    command_args = {
        "dependency_name": dependency_name,
Beispiel #16
0
 def verifier(self):
     return api.verifiers(self).get(self.config['verifier']['name'], None)
Beispiel #17
0
def pre_validate_base_schema(env: MutableMapping, keep_string: str):
    """Pre-validate base schema."""
    return {
        "dependency": {
            "type": "dict",
            "schema": {
                "name": {
                    "type": "string",
                    "molecule_env_var": True,
                    "allowed": ["galaxy", "shell"],
                }
            },
        },
        "driver": {
            "type": "dict",
            "schema": {
                "name": {
                    "type": "string",
                    "molecule_env_var": True,
                    "allowed": api.drivers(),
                    # NOTE(retr0h): Some users use an environment variable to
                    # change the driver name.  May add this coercion to rest of
                    # config using allowed validation.
                    "coerce": (str, functools.partial(coerce_env, env, keep_string)),
                }
            },
        },
        "lint": {"type": "string"},
        "platforms": {
            "type": "list",
            "schema": {
                "type": "dict",
                "schema": {
                    "registry": {
                        "type": "dict",
                        "schema": {
                            "credentials": {
                                "type": "dict",
                                "schema": {"password": {"type": "string"}},
                            }
                        },
                    }
                },
            },
        },
        "provisioner": {
            "type": "dict",
            "schema": {
                "name": {
                    "type": "string",
                    "molecule_env_var": True,
                    "allowed": ["ansible"],
                },
            },
        },
        "scenario": {"type": "dict", "schema": {"name": {"molecule_env_var": True}}},
        "verifier": {
            "type": "dict",
            "schema": {
                "name": {
                    "type": "string",
                    "molecule_env_var": True,
                    "allowed": api.verifiers(),
                },
            },
        },
    }