예제 #1
0
파일: role.py 프로젝트: kireledan/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)

        self._process_templates('role', self._command_args, role_directory)
        scenario_base_directory = os.path.join(role_directory, role_name)
        templates = [
            'scenario/driver/{driver_name}'.format(**self._command_args),
            'scenario/verifier/{verifier_name}'.format(**self._command_args),
        ]
        for template in templates:
            self._process_templates(template, self._command_args,
                                    scenario_base_directory)
        self._process_templates('molecule', 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)
예제 #2
0
def _role_exists(ctx, param, value):  # pragma: no cover
    role_directory = os.path.join(os.pardir, value)
    if not os.path.exists(role_directory):
        msg = ("The role '{}' not found. "
               'Please choose the proper role name.').format(value)
        util.sysexit_with_message(msg)
    return value
예제 #3
0
def test_sysexit_with_message_and_custom_code(patched_logger_critical):
    with pytest.raises(SystemExit) as e:
        util.sysexit_with_message('foo', 2)

    assert 2 == e.value.code

    patched_logger_critical.assert_called_once_with('foo')
예제 #4
0
    def _verify_inventory(self):
        """
        Verify the inventory is valid and returns None.

        :return: None
        """
        if not self.inventory:
            msg = ("Instances missing from the 'platform' "
                   "section of molecule.yml.")
            util.sysexit_with_message(msg)
예제 #5
0
def _default_scenario_exists(ctx, param, value):  # pragma: no cover
    if value == 'default':
        return value

    default_scenario_directory = os.path.join('molecule', 'default')
    if not os.path.exists(default_scenario_directory):
        msg = ('The default scenario not found.  Please create a scenario '
               "named 'default' first.")
        util.sysexit_with_message(msg)
    return value
예제 #6
0
    def _verify(self):
        """
        Verify the specified scenario was found and returns None.

        :return: None
        """
        scenario_names = [c.scenario.name for c in self._configs]
        if self._scenario_name not in scenario_names:
            msg = ("Scenario '{}' not found.  "
                   'Exiting.').format(self._scenario_name)
            util.sysexit_with_message(msg)
예제 #7
0
    def execute(self):
        """
        Executes `ansible-playbook` and returns a string.

        :return: str
        """
        if self._ansible_command is None:
            self.bake()

        try:
            cmd = util.run_command(
                self._ansible_command, debug=self._config.debug)
            return cmd.stdout.decode('utf-8')
        except sh.ErrorReturnCode as e:
            out = e.stdout.decode('utf-8')
            util.sysexit_with_message(str(out), e.exit_code)
예제 #8
0
파일: login.py 프로젝트: kireledan/molecule
    def execute(self):
        """
        Execute the actions necessary to perform a `molecule login` and
        returns None.

        :return: None
        """
        c = self._config
        if not c.state.created and (c.driver.delegated
                                    and not c.driver.managed):
            msg = 'Instances not created.  Please create instances first.'
            util.sysexit_with_message(msg)

        hosts = [d['name'] for d in self._config.platforms.instances]
        hostname = self._get_hostname(hosts)
        self._get_login(hostname)
예제 #9
0
    def _link_or_update_vars(self):
        """
        Creates or updates the symlink to group_vars and returns None.

        :returns: None
        """
        for d, source in self.links.items():
            target = os.path.join(self._config.scenario.ephemeral_directory, d)
            source = os.path.join(self._config.scenario.ephemeral_directory,
                                  source)

            if not os.path.exists(source):
                msg = "The source path '{}' does not exist.".format(source)
                util.sysexit_with_message(msg)
            msg = "Inventory {} linked to {}".format(source, target)
            LOG.info(msg)
            os.symlink(source, target)
예제 #10
0
    def _get_driver_name(self):
        driver_from_state_file = self.state.driver
        driver_from_cli = self.command_args.get('driver_name')

        if driver_from_state_file:
            driver_name = driver_from_state_file
        elif driver_from_cli:
            driver_name = driver_from_cli
        else:
            driver_name = self.config['driver']['name']

        if driver_from_cli and (driver_from_cli != driver_name):
            msg = ("Instance(s) were created with the '{}' driver, but the "
                   "subcommand is using '{}' driver.").format(
                       driver_name, driver_from_cli)
            util.sysexit_with_message(msg)

        return driver_name
예제 #11
0
파일: base.py 프로젝트: kireledan/molecule
def _verify_configs(configs):
    """
    Verify a Molecule config was found and returns None.

    :param configs: A list containing absolute paths to Molecule config files.
    :return: None
    """
    if configs:
        scenario_names = [c.scenario.name for c in configs]
        for scenario_name, n in collections.Counter(scenario_names).items():
            if n > 1:
                msg = ("Duplicate scenario name '{}' found.  "
                       'Exiting.').format(scenario_name)
                util.sysexit_with_message(msg)

    else:
        msg = "'{}' glob failed.  Exiting.".format(MOLECULE_GLOB)
        util.sysexit_with_message(msg)
예제 #12
0
    def __init__(self, old_molecule_file, driver_name):
        self._old_molecule_file = old_molecule_file

        if not os.path.isfile(old_molecule_file):
            msg = 'Unable to find {}. Exiting.'.format(old_molecule_file)
            util.sysexit_with_message(msg)

        self._m = migrate.Migrate(old_molecule_file)
        self._old_role_dir = os.path.join(os.path.dirname(old_molecule_file))
        self._old_dot_molecule_dir = scenario.ephemeral_directory(
            self._old_role_dir)
        self._old_test_dir = os.path.join(self._old_role_dir, 'tests')
        self._old_playbook = os.path.join(self._old_role_dir, 'playbook.yml')
        self._molecule_dir = config.molecule_directory(self._old_role_dir)
        self._scenario_dir = os.path.join(self._molecule_dir, 'default')
        self._test_dir = os.path.join(self._scenario_dir, 'tests')
        self._molecule_file = config.molecule_file(self._scenario_dir)

        self._role_name = os.path.basename(
            os.path.normpath(self._old_role_dir))
예제 #13
0
파일: login.py 프로젝트: kireledan/molecule
    def _get_hostname(self, hosts):
        hostname = self._config.command_args.get('host')
        if hostname is None:
            if len(hosts) == 1:
                hostname = hosts[0]
            else:
                msg = ('There are {} running hosts. Please specify '
                       'which with --host.\n\n'
                       'Available hosts:\n{}'.format(
                           len(hosts), '\n'.join(sorted(hosts))))
                util.sysexit_with_message(msg)
        match = [x for x in hosts if x.startswith(hostname)]
        if len(match) == 0:
            msg = ("There are no hosts that match '{}'.  You "
                   'can only login to valid hosts.').format(hostname)
            util.sysexit_with_message(msg)
        elif len(match) != 1:
            # If there are multiple matches, but one of them is an exact string
            # match, assume this is the one they're looking for and use it.
            if hostname in match:
                match = [
                    hostname,
                ]
            else:
                msg = ("There are {} hosts that match '{}'. You "
                       'can only login to one at a time.\n\n'
                       'Available hosts:\n{}'.format(
                           len(match), hostname, '\n'.join(sorted(hosts))))
                util.sysexit_with_message(msg)

        return match[0]
예제 #14
0
    def execute(self):
        """
        Execute the actions necessary to perform a `molecule idempotence` and
        returns None.

        :return: None
        """
        self.print_info()
        if not self._config.state.converged:
            msg = 'Instances not converged.  Please converge instances first.'
            util.sysexit_with_message(msg)

        output = self._config.provisioner.converge(out=None, err=None)

        idempotent = self._is_idempotent(output)
        if idempotent:
            msg = 'Idempotence completed successfully.'
            LOG.success(msg)
        else:
            msg = ('Idempotence test failed because of the following tasks:\n'
                   '{}').format('\n'.join(self._non_idempotent_tasks(output)))
            util.sysexit_with_message(msg)
예제 #15
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)
        scenario_base_directory = os.path.dirname(scenario_directory)

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

        scenario_base_directory = os.path.join(role_directory, role_name)
        templates = [
            'scenario/driver/{driver_name}'.format(**self._command_args),
            'scenario/verifier/{verifier_name}'.format(**self._command_args),
        ]
        for template in templates:
            self._process_templates(template, self._command_args,
                                    scenario_base_directory)
        self._process_templates('molecule', 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)
예제 #16
0
파일: shell.py 프로젝트: corserp/greet
def _supported_ansible_version():  # pragma: no cover
    if (distutils.version.LooseVersion(_get_ansible_version()) <=
            distutils.version.LooseVersion('2.2')):
        msg = ("Ansible version '{}' not supported.  "
               'Molecule only supports Ansible versions '
               "'>= 2.2'.").format(_get_ansible_version())
        util.sysexit_with_message(msg)

    if _supported_python2_version():
        pass
    elif _supported_python3_version():
        if (distutils.version.LooseVersion(_get_ansible_version()) <
                distutils.version.LooseVersion('2.4')):
            msg = ("Ansible version '{}' not supported.  "
                   'Molecule only supports Ansible versions '
                   "'>=2.5' with Python version '{}'").format(
                       _get_ansible_version(), _get_python_version())
            util.sysexit_with_message(msg)
    else:
        msg = ("Python version '{}' not supported.  "
               'Molecule only supports Python versions '
               "'2.7' and '3.6'.").format(_get_python_version())
        util.sysexit_with_message(msg)
예제 #17
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)
예제 #18
0
 def _preflight(self, data: MutableMapping):
     env = set_env_from_file(os.environ.copy(), self.env_file)
     errors, data = schema_v3.pre_validate(data, env, MOLECULE_KEEP_STRING)
     if errors:
         msg = "Failed to pre-validate.\n\n{}".format(errors)
         util.sysexit_with_message(msg, detail=data)
예제 #19
0
            interpolated_config = self._interpolate(s, env, keep_string)
            defaults = util.merge_dicts(defaults,
<<<<<<< HEAD
>>>>>>> 0fa82e7a3daa84ebd03d8af67403c6551113d3e4:molecule/config.py
=======
=======
            try:
                interpolated_config = i.interpolate(stream.read())
                base = self.merge_dicts(base,
>>>>>>> b1eb06d375fd544a849fcf5c39f51dc334b87338:Rake/molecule/__GEMS_.py/__GEMS_.py/apt-py.git/commandinit.yaml/init.yml/config.py
>>>>>>> e91355cf081d9dcd78efe38cdcc6f0353a1aa3ac
                                        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)

        schema.validate(base)

<<<<<<< HEAD
<<<<<<< HEAD:Rake/molecule/__GEMS_.py/__GEMS_.py/apt-py.git/commandinit.yaml/init.yml/config.py
        return base
=======
=======
<<<<<<< HEAD:molecule/config.py
>>>>>>> e91355cf081d9dcd78efe38cdcc6f0353a1aa3ac
    def _interpolate(self, stream, env, keep_string):
        env = self._set_env(env)

        i = interpolation.Interpolator(interpolation.TemplateWithDefaults, env)
예제 #20
0
파일: base.py 프로젝트: corserp/greet
 def _validate_template_dir(self, template_dir):
     if not os.path.isdir(template_dir):
         util.sysexit_with_message("The specified template directory (" +
                                   str(template_dir) + ") does not exist")
예제 #21
0
파일: shell.py 프로젝트: sysgazer/molecule
def _allowed():  # pragma: no cover
    if distutils.version.LooseVersion(
            ansible.__version__) <= distutils.version.LooseVersion('2.2'):
        msg = ("Ansible version '{}' not supported.  Molecule only supports "
               'versions >= 2.2.').format(ansible.__version__)
        util.sysexit_with_message(msg)
예제 #22
0
파일: migrate.py 프로젝트: corserp/greet
 def _check_errors(self, errors):
     if errors:
         msg = "Failed to validate.\n\n{}".format(errors)
         util.sysexit_with_message(msg)
예제 #23
0
 def sanity_checks(self):
     if not which("vagrant"):
         util.sysexit_with_message("vagrant executable was not found!")
예제 #24
0
 def _preflight(self, data):
     errors = schema_v2.pre_validate(data)
     if errors:
         msg = "Failed to validate.\n\n{}".format(errors)
         util.sysexit_with_message(msg)
예제 #25
0
 def _exit_with_invalid_section(self, section, name):
     msg = "Invalid {} named '{}' configured.".format(section, name)
     util.sysexit_with_message(msg)
예제 #26
0
<<<<<<< HEAD:Rake/molecule/__GEMS_.py/__GEMS_.py/apt-py.git/commandinit.yaml/login.py
        if not c.state.created and (c.driver.delegated
                                    and not c.driver.managed):
=======
        if ((not c.state.created) and c.driver.managed):
>>>>>>> 0fa82e7a3daa84ebd03d8af67403c6551113d3e4:molecule/command/login.py
=======
<<<<<<< HEAD:molecule/command/login.py
        if ((not c.state.created) and c.driver.managed):
=======
        if not c.state.created and (c.driver.delegated
                                    and not c.driver.managed):
>>>>>>> b1eb06d375fd544a849fcf5c39f51dc334b87338:Rake/molecule/__GEMS_.py/__GEMS_.py/apt-py.git/commandinit.yaml/login.py
>>>>>>> e91355cf081d9dcd78efe38cdcc6f0353a1aa3ac
            msg = 'Instances not created.  Please create instances first.'
            util.sysexit_with_message(msg)

        hosts = [d['name'] for d in self._config.platforms.instances]
        hostname = self._get_hostname(hosts)
        self._get_login(hostname)

    def _get_hostname(self, hosts):
        hostname = self._config.command_args.get('host')
        if hostname is None:
            if len(hosts) == 1:
                hostname = hosts[0]
            else:
                msg = ('There are {} running hosts. Please specify '
                       'which with --host.\n\n'
                       'Available hosts:\n{}'.format(
                           len(hosts), '\n'.join(sorted(hosts))))
예제 #27
0
파일: shell.py 프로젝트: kireledan/molecule
def _allowed():  # pragma: no cover
    if distutils.version.LooseVersion(
            ansible.__version__) <= distutils.version.LooseVersion('2.2'):
        msg = ("Ansible version '{}' not supported.  Molecule only supports "
               'versions >= 2.2.').format(ansible.__version__)
        util.sysexit_with_message(msg)