예제 #1
0
def test_api_drivers():
    results = api.drivers()

    for result in results:
        assert isinstance(result, api.Driver)

    assert 'delegated' in results
예제 #2
0
    def _get_modules_directories(self):
        """Return list of ansilbe module includes directories.

        Adds modules directory from molecule and its plugins.
        """
        paths = [util.abs_path(os.path.join(self._get_plugin_directory(), "modules"))]

        for d in drivers():
            p = d.modules_dir()
            if p:
                paths.append(p)
        paths.extend(
            [
                util.abs_path(
                    os.path.join(self._config.scenario.ephemeral_directory, "library")
                ),
                util.abs_path(os.path.join(self._config.project_directory, "library")),
                util.abs_path(
                    os.path.join(
                        os.path.expanduser("~"), ".ansible", "plugins", "modules",
                    )
                ),
                "/usr/share/ansible/plugins/modules",
            ]
        )
        return paths
예제 #3
0
파일: ansible.py 프로젝트: themr0c/molecule
    def _get_modules_directories(self) -> List[str]:
        """Return list of ansilbe module includes directories.

        Adds modules directory from molecule and its plugins.
        """
        paths: List[Optional[str]] = []
        if os.environ.get("ANSIBLE_LIBRARY"):
            paths = list(
                map(util.abs_path, os.environ["ANSIBLE_LIBRARY"].split(":")))

        paths.append(
            util.abs_path(os.path.join(self._get_plugin_directory(),
                                       "modules")))

        for d in drivers():
            p = d.modules_dir()
            if p:
                paths.append(p)
        paths.extend([
            util.abs_path(
                os.path.join(self._config.scenario.ephemeral_directory,
                             "library")),
            util.abs_path(
                os.path.join(self._config.project_directory, "library")),
            util.abs_path(
                os.path.join(
                    os.path.expanduser("~"),
                    ".ansible",
                    "plugins",
                    "modules",
                )),
            "/usr/share/ansible/plugins/modules",
        ])

        return [path for path in paths if path is not None]
예제 #4
0
    def driver(self):
        driver_name = self._get_driver_name()
        driver = None

        driver = api.drivers(config=self)[driver_name]
        driver.name = driver_name

        return driver
예제 #5
0
def reset(ctx, scenario_name):  # pragma: no cover
    """Reset molecule temporary folders."""
    args = ctx.obj.get("args")
    subcommand = base._get_subcommand(__name__)
    command_args = {"subcommand": subcommand}

    base.execute_cmdline_scenarios(scenario_name, args, command_args)
    for driver in drivers():
        driver.reset()
예제 #6
0
def drivers(ctx, format):  # pragma: no cover
    """List drivers."""
    drivers = [[x] for x in api.drivers()]

    headers = ['name']
    table_format = 'simple'
    if format == 'plain':
        headers = []
        table_format = format
    _print_tabulate_data(headers, drivers, table_format)
예제 #7
0
def drivers(ctx, format):  # pragma: no cover
    """List drivers."""
    drivers = [[x] for x in api.drivers()]

    headers = ["name"]
    table_format = "simple"
    if format == "plain":
        headers = []
        table_format = format
    _print_tabulate_data(headers, drivers, table_format)
예제 #8
0
def _version_string() -> str:

    v = pkg_resources.parse_version(molecule.__version__)
    color = "bright_yellow" if v.is_prerelease else "green"  # type: ignore
    msg = "molecule %s\n" % _colorize(molecule.__version__, color)

    details = f"    ansible:{ansible_version()} python:{sys.version_info[0]}.{sys.version_info[1]}"
    for driver in drivers():
        details += f"\n    {driver}:{driver.version} from {driver.module}"
    msg += _colorize(details, "bright_black")
    return msg
예제 #9
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)
예제 #10
0
def pytest_configure(config):

    # We hide DeprecationWarnings thrown by driver loading because these are
    # outside our control and worse: they are displayed even on projects that
    # have no molecule tests at all as pytest_configure() is called during
    # collection, causing spam.
    with warnings.catch_warnings():
        warnings.filterwarnings("ignore", category=DeprecationWarning)

        config.option.molecule = {}
        for driver in map(str, drivers()):
            config.addinivalue_line(
                "markers",
                "{0}: mark test to run only when {0} is available".format(
                    driver),
            )
            config.option.molecule[driver] = {"available": True}
            # TODO(ssbarnea): extend molecule itself to allow it to report usable drivers
            if driver == "docker":
                try:
                    import docker

                    # validate docker connectivity
                    # Default docker value is 60s but we want to fail faster
                    # With parallel execution 5s proved to give errors.
                    c = docker.from_env(timeout=10, version="auto")
                    if not c.ping():
                        raise Exception("Failed to ping docker server.")

                except Exception as e:
                    msg = "Molecule {} driver is not available due to: {}.".format(
                        driver, e)
                    if config.option.molecule_unavailable_driver:
                        msg += " We will tag scenarios using it with '{}' marker.".format(
                            config.option.molecule_unavailable_driver)
                    logging.getLogger().warning(msg)
                    config.option.molecule[driver]["available"] = False

        config.addinivalue_line(
            "markers", "molecule: mark used by all molecule scenarios")

        # validate selinux availability
        if sys.platform == "linux" and os.path.isfile("/etc/selinux/config"):
            try:
                import selinux  # noqa
            except Exception:
                logging.error(
                    "It appears that you are trying to use "
                    "molecule with a Python interpreter that does not have the "
                    "libselinux python bindings installed. These can only be "
                    "installed using your distro package manager and are specific "
                    "to each python version. Common package names: "
                    "libselinux-python python2-libselinux python3-libselinux")
예제 #11
0
def print_version(ctx, param, value):
    """Print version information."""
    if not value or ctx.resilient_parsing:
        return

    v = pkg_resources.parse_version(molecule.__version__)
    color = "bright_yellow" if v.is_prerelease else "green"
    msg = f"molecule [{color}]{v}[/] using python [repr.number]{sys.version_info[0]}.{sys.version_info[1]}[/] \n"

    msg += (
        f"    [repr.attrib_name]ansible[/][dim]:[/][repr.number]{ansible_version()}[/]"
    )
    for driver in drivers():
        msg += f"\n    [repr.attrib_name]{str(driver)}[/][dim]:[/][repr.number]{driver.version}[/][dim] from {driver.module}[/]"
    console.print(msg)

    ctx.exit()
예제 #12
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)
예제 #13
0
def print_version(ctx, param, value):
    """Print version information."""
    if not value or ctx.resilient_parsing:
        return

    v = packaging.version.Version(molecule.__version__)
    color = "bright_yellow" if v.is_prerelease else "green"
    msg = f"molecule [{color}]{v}[/] using python [repr.number]{sys.version_info[0]}.{sys.version_info[1]}[/] \n"

    runtime = Runtime()
    msg += f"    [repr.attrib_name]ansible[/][dim]:[/][repr.number]{runtime.version}[/]"
    for driver in drivers():
        msg += f"\n    [repr.attrib_name]{str(driver)}[/][dim]:[/][repr.number]{driver.version}[/][dim] from {driver.module}[/]"
        if driver.required_collections:
            msg += " requiring collections:"
            for name, version in driver.required_collections.items():
                msg += f" {name}>={version}"
    console.print(msg)

    ctx.exit()
예제 #14
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)
예제 #15
0
파일: role.py 프로젝트: anavarre/molecule
    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 = [
            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)
def test_driver_is_detected():
    """Check that driver is recognized."""
    assert "containers" in [str(d) for d in api.drivers()]
예제 #17
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',
                            ],
                        }
                    },
                },
            },
        },
    }
예제 #18
0
def pytest_configure(config):
    INTERESTING_ENV_VARS = [
        "ANSIBLE",
        "MOLECULE",
        "DOCKER",
        "PODMAN",
        "VAGRANT",
        "VIRSH",
        "ZUUL",
    ]

    # Add extra information that may be key for debugging failures
    for p in ["ansible", "molecule"]:
        config._metadata["Packages"][p] = pkg_resources.get_distribution(p).version

    # Adds interesting env vars
    env = ""
    for k, v in sorted(os.environ.items()):
        for a in INTERESTING_ENV_VARS:
            if k.startswith(a):
                env += f"{k}={v} "
    config._metadata["env"] = env

    # We hide DeprecationWarnings thrown by driver loading because these are
    # outside our control and worse: they are displayed even on projects that
    # have no molecule tests at all as pytest_configure() is called during
    # collection, causing spam.
    with warnings.catch_warnings():
        warnings.filterwarnings("ignore", category=DeprecationWarning)

        config.option.molecule = {}
        for driver in map(str, drivers()):
            config.addinivalue_line(
                "markers",
                "{0}: mark test to run only when {0} is available".format(driver),
            )
            config.option.molecule[driver] = {"available": True}
            # TODO(ssbarnea): extend molecule itself to allow it to report usable drivers
            if driver == "docker":
                try:
                    import docker

                    # validate docker connectivity
                    # Default docker value is 60s but we want to fail faster
                    # With parallel execution 5s proved to give errors.
                    c = docker.from_env(timeout=10, version="auto")
                    if not c.ping():
                        raise Exception("Failed to ping docker server.")

                except Exception as e:
                    msg = "Molecule {} driver is not available due to: {}.".format(
                        driver, e
                    )
                    if config.option.molecule_unavailable_driver:
                        msg += " We will tag scenarios using it with '{}' marker.".format(
                            config.option.molecule_unavailable_driver
                        )
                    logging.getLogger().warning(msg)
                    config.option.molecule[driver]["available"] = False

        config.addinivalue_line(
            "markers", "molecule: mark used by all molecule scenarios"
        )

        # validate selinux availability
        if sys.platform == "linux" and os.path.isfile("/etc/selinux/config"):
            try:
                import selinux  # noqa
            except Exception:
                logging.error(
                    "It appears that you are trying to use "
                    "molecule with a Python interpreter that does not have the "
                    "libselinux python bindings installed. These can only be "
                    "installed using your distro package manager and are specific "
                    "to each python version. Common package names: "
                    "libselinux-python python2-libselinux python3-libselinux"
                )
예제 #19
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)
예제 #20
0
def pytest_configure(config):
    """Pytest hook for loading our specific configuration."""
    interesting_env_vars = [
        "ANSIBLE",
        "MOLECULE",
        "DOCKER",
        "PODMAN",
        "VAGRANT",
        "VIRSH",
        "ZUUL",
    ]

    # Add extra information that may be key for debugging failures
    for package in ["molecule"]:
        config._metadata["Packages"][package] = pkg_resources.get_distribution(
            package
        ).version

    if "Tools" not in config._metadata:
        config._metadata["Tools"] = {}
    config._metadata["Tools"]["ansible"] = str(ansible_version())

    # Adds interesting env vars
    env = ""
    for key, value in sorted(os.environ.items()):
        for var_name in interesting_env_vars:
            if key.startswith(var_name):
                env += f"{key}={value} "
    config._metadata["env"] = env

    # We hide DeprecationWarnings thrown by driver loading because these are
    # outside our control and worse: they are displayed even on projects that
    # have no molecule tests at all as pytest_configure() is called during
    # collection, causing spam.
    with warnings.catch_warnings():
        warnings.filterwarnings("ignore", category=DeprecationWarning)

        config.option.molecule = {}
        for driver in map(str, drivers()):
            config.addinivalue_line(
                "markers",
                "{0}: mark test to run only when {0} is available".format(driver),
            )
            config.option.molecule[driver] = {"available": True}

        config.addinivalue_line(
            "markers",
            "no_driver: mark used for scenarios that do not contain driver info",
        )

        config.addinivalue_line(
            "markers", "molecule: mark used by all molecule scenarios"
        )

        # validate selinux availability
        if sys.platform == "linux" and os.path.isfile("/etc/selinux/config"):
            try:
                import selinux  # noqa pylint: disable=unused-import,import-error,import-outside-toplevel
            except ImportError:
                logging.error(
                    "It appears that you are trying to use "
                    "molecule with a Python interpreter that does not have the "
                    "libselinux python bindings installed. These can only be "
                    "installed using your distro package manager and are specific "
                    "to each python version. Common package names: "
                    "libselinux-python python2-libselinux python3-libselinux"
                )
예제 #21
0
def test_driver_is_detected():
    driver_name = __name__.split(".")[0].split("_")[-1]
    assert driver_name in [str(d) for d in api.drivers()]
예제 #22
0
def test_api_molecule_drivers_as_attributes():
    results = api.drivers()
    assert hasattr(results, 'delegated')
    assert isinstance(results.delegated, api.Driver)
예제 #23
0
def test_driver_is_detected():
    assert "lxd" in [str(d) for d in api.drivers()]
예제 #24
0
파일: test.py 프로젝트: themr0c/molecule
        :return: None
        """


@base.click_command_ex()
@click.pass_context
@click.option(
    "--scenario-name",
    "-s",
    default=base.MOLECULE_DEFAULT_SCENARIO_NAME,
    help=f"Name of the scenario to target. ({base.MOLECULE_DEFAULT_SCENARIO_NAME})",
)
@click.option(
    "--driver-name",
    "-d",
    type=click.Choice([str(s) for s in drivers()]),
    help=f"Name of driver to use. ({DEFAULT_DRIVER})",
)
@click.option(
    "--all/--no-all",
    "__all",
    default=False,
    help="Test all scenarios. Default is False.",
)
@click.option(
    "--destroy",
    type=click.Choice(["always", "never"]),
    default="always",
    help=("The destroy strategy used at the conclusion of a " "Molecule run (always)."),
)
@click.option(
예제 #25
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(),
                },
            },
        },
    }
예제 #26
0
def test_driver_is_detected(DRIVER):
    """Asserts that molecule recognizes the driver."""
    assert DRIVER in [str(d) for d in api.drivers()]
예제 #27
0
        util.sysexit_with_message(msg)
    return value


@click.command()
@click.pass_context
@click.option(
    '--dependency-name',
    type=click.Choice(['galaxy']),
    default='galaxy',
    help='Name of dependency to initialize. (galaxy)',
)
@click.option(
    '--driver-name',
    '-d',
    type=click.Choice(api.drivers()),
    default='docker',
    help='Name of driver to initialize. (docker)',
)
@click.option(
    '--lint-name',
    type=click.Choice(['yamllint']),
    default='yamllint',
    help='Name of lint to initialize. (ansible-lint)',
)
@click.option(
    '--provisioner-name',
    type=click.Choice(['ansible']),
    default='ansible',
    help='Name of provisioner to initialize. (ansible)',
)