Example #1
0
    def main(self):
        if not os.path.exists(self.config.config['molecule']['molecule_dir']):
            os.makedirs(self.config.config['molecule']['molecule_dir'])

        self._state = state.State(
            state_file=self.config.config.get('molecule').get('state_file'))

        try:
            self._provisioner = self.get_provisioner()
        except baseprovisioner.InvalidProviderSpecified:
            LOG.error("Invalid provider '{}'".format(self._args['--provider']))
            self._args['--provider'] = None
            self._args['--platform'] = None
            self._provisioner = self.get_provisioner()
            self._print_valid_providers()
            utilities.sysexit()
        except baseprovisioner.InvalidPlatformSpecified:
            LOG.error("Invalid platform '{}'".format(self._args['--platform']))
            self._args['--provider'] = None
            self._args['--platform'] = None
            self._provisioner = self.get_provisioner()
            self._print_valid_platforms()
            utilities.sysexit()

        # updates instances config with full machine names
        self.config.populate_instance_names(self._provisioner.platform)

        if self._args.get('--debug'):
            utilities.debug('RUNNING CONFIG',
                            yaml.dump(self.config.config,
                                      default_flow_style=False,
                                      indent=2))
        self._add_or_update_vars('group_vars')
        self._add_or_update_vars('host_vars')
        self._symlink_vars()
Example #2
0
    def main(self):
        # load molecule defaults
        self._config.load_defaults_file()

        # merge in any molecule config files found (eg: ~/.configs/molecule/config.yml)
        self._config.merge_molecule_config_files()

        # init command doesn't need to load molecule.yml
        if self._args.get('<command>') == 'init':
            return  # exits program

        # merge in molecule.yml
        self._config.merge_molecule_file()

        # concatentate file names and paths within config so they're more convenient to use
        self._config.build_easy_paths()

        # get defaults for inventory/ansible.cfg from molecule if none are specified
        self._config.update_ansible_defaults()

        self._state = self._load_state_file()

        try:
            self._provisioner = provisioners.get_provisioner(self)
        except provisioners.InvalidProviderSpecified:
            print("\n{}Invalid provider '{}'\n".format(
                colorama.Fore.RED, self._args['--provider'],
                colorama.Fore.RESET))
            self._args['--provider'] = None
            self._args['--platform'] = None
            self._provisioner = provisioners.get_provisioner(self)
            self._print_valid_providers()
            sys.exit(1)
        except provisioners.InvalidPlatformSpecified:
            print("\n{}Invalid platform '{}'\n".format(
                colorama.Fore.RED, self._args['--platform'],
                colorama.Fore.RESET))
            self._args['--provider'] = None
            self._args['--platform'] = None
            self._provisioner = provisioners.get_provisioner(self)
            self._print_valid_platforms()
            sys.exit(1)

        if not os.path.exists(self._config.config['molecule']['molecule_dir']):
            os.makedirs(self._config.config['molecule']['molecule_dir'])

        # updates instances config with full machine names
        self._config.populate_instance_names(self._env['MOLECULE_PLATFORM'])
        if self._args.get('--debug'):
            utilities.debug(
                'RUNNING CONFIG',
                yaml.dump(self._config.config,
                          default_flow_style=False,
                          indent=2))

        self._write_state_file()
Example #3
0
    def main(self):
        # load molecule defaults
        self._config.load_defaults_file()

        # merge in any molecule config files found (eg: ~/.configs/molecule/config.yml)
        self._config.merge_molecule_config_files()

        # init command doesn't need to load molecule.yml
        if self._args.get('<command>') == 'init':
            return  # exits program

        # merge in molecule.yml
        self._config.merge_molecule_file()

        # concatentate file names and paths within config so they're more convenient to use
        self._config.build_easy_paths()

        # get defaults for inventory/ansible.cfg from molecule if none are specified
        self._config.update_ansible_defaults()

        self._state = self._load_state_file()

        try:
            self._provisioner = provisioners.get_provisioner(self)
        except provisioners.InvalidProviderSpecified:
            print("\n{}Invalid provider '{}'\n".format(
                colorama.Fore.RED, self._args['--provider'],
                colorama.Fore.RESET))
            self._args['--provider'] = None
            self._args['--platform'] = None
            self._provisioner = provisioners.get_provisioner(self)
            self._print_valid_providers()
            sys.exit(1)
        except provisioners.InvalidPlatformSpecified:
            print("\n{}Invalid platform '{}'\n".format(
                colorama.Fore.RED, self._args['--platform'],
                colorama.Fore.RESET))
            self._args['--provider'] = None
            self._args['--platform'] = None
            self._provisioner = provisioners.get_provisioner(self)
            self._print_valid_platforms()
            sys.exit(1)

        if not os.path.exists(self._config.config['molecule']['molecule_dir']):
            os.makedirs(self._config.config['molecule']['molecule_dir'])

        # updates instances config with full machine names
        self._config.populate_instance_names(self._env['MOLECULE_PLATFORM'])
        if self._args.get('--debug'):
            utilities.debug('RUNNING CONFIG',
                            yaml.dump(self._config.config,
                                      default_flow_style=False,
                                      indent=2))

        self._write_state_file()
Example #4
0
def test_debug(capsys):
    utilities.debug('test_title', 'test_data')
    result_title, _ = capsys.readouterr()

    print(''.join([colorama.Back.WHITE, colorama.Style.BRIGHT,
                   colorama.Fore.BLACK, 'DEBUG: ' + 'test_title',
                   colorama.Fore.RESET, colorama.Back.RESET,
                   colorama.Style.RESET_ALL]))
    print(''.join([colorama.Fore.BLACK, colorama.Style.BRIGHT, 'test_data',
                   colorama.Style.RESET_ALL, colorama.Fore.RESET]))
    expected_title, _ = capsys.readouterr()

    assert expected_title == result_title
Example #5
0
    def main(self):
        if self._args.get('<command>') == 'init':
            return  # exits program

        # ensure the .molecule directory exists
        if not os.path.isdir(os.path.join(os.curdir, self._config.config[
                'molecule']['molecule_dir'])):
            os.mkdir(os.path.join(os.curdir, self._config.config['molecule'][
                'molecule_dir']))

        # concatentate file names and paths within config so they're more convenient to use
        self._config.build_easy_paths()

        # get defaults for inventory/ansible.cfg from molecule if none are specified
        self._config.update_ansible_defaults()

        self._state = state.State(
            state_file=self._config.config.get('molecule').get('state_file'))

        try:
            self._provisioner = self.get_provisioner()
        except baseprovisioner.InvalidProviderSpecified:
            utilities.logger.error("\nInvalid provider '{}'\n".format(
                self._args['--provider']))
            self._args['--provider'] = None
            self._args['--platform'] = None
            self._provisioner = self.get_provisioner()
            self._print_valid_providers()
            utilities.sysexit()
        except baseprovisioner.InvalidPlatformSpecified:
            utilities.logger.error("\nInvalid platform '{}'\n".format(
                self._args['--platform']))
            self._args['--provider'] = None
            self._args['--platform'] = None
            self._provisioner = self.get_provisioner()
            self._print_valid_platforms()
            utilities.sysexit()

        if not os.path.exists(self._config.config['molecule']['molecule_dir']):
            os.makedirs(self._config.config['molecule']['molecule_dir'])

        # updates instances config with full machine names
        self._config.populate_instance_names(self._env['MOLECULE_PLATFORM'])

        if self._args.get('--debug'):
            utilities.debug('RUNNING CONFIG',
                            yaml.dump(self._config.config,
                                      default_flow_style=False,
                                      indent=2))
Example #6
0
    def execute(self,
                idempotent=False,
                create_instances=True,
                create_inventory=True,
                exit=True,
                hide_errors=True):
        """
        :param idempotent: Optionally provision servers quietly so output can be parsed for idempotence
        :param create_inventory: Toggle inventory creation
        :param create_instances: Toggle instance creation
        :return: Provisioning output
        """
        if self.molecule._state.get('created'):
            create_instances = False

        if self.molecule._state.get('converged'):
            create_inventory = False

        if self.static:
            create_instances = False
            create_inventory = False

        if create_instances and not idempotent:
            command_args, args = utilities.remove_args(self.command_args,
                                                       self.args, ['--tags'])
            c = Create(command_args, args, self.molecule)
            c.execute()

        if create_inventory:
            self.molecule._create_inventory_file()

        # install role dependencies only during `molecule converge`
        if not idempotent and 'requirements_file' in self.molecule._config.config[
                'ansible']:
            print('{}Installing role dependencies ...{}'.format(
                colorama.Fore.CYAN, colorama.Fore.RESET))
            galaxy_install = AnsibleGalaxyInstall(self.molecule._config.config[
                'ansible']['requirements_file'])
            galaxy_install.add_env_arg(
                'ANSIBLE_CONFIG',
                self.molecule._config.config['ansible']['config_file'])
            galaxy_install.bake()
            output = galaxy_install.execute()

        ansible = AnsiblePlaybook(self.molecule._config.config['ansible'])

        # params to work with provisioner
        for k, v in self.molecule._provisioner.ansible_connection_params.items(
        ):
            ansible.add_cli_arg(k, v)

        # target tags passed in via CLI
        if self.molecule._args.get('--tags'):
            ansible.add_cli_arg('tags', self.molecule._args['--tags'].pop(0))

        if idempotent:
            ansible.remove_cli_arg('_out')
            ansible.remove_cli_arg('_err')
            ansible.add_env_arg('ANSIBLE_NOCOLOR', 'true')
            ansible.add_env_arg('ANSIBLE_FORCE_COLOR', 'false')

            # Save the previous callback plugin if any.
            callback_plugin = ansible.env.get('ANSIBLE_CALLBACK_PLUGINS', '')

            # Set the idempotence plugin.
            if callback_plugin:
                ansible.add_env_arg(
                    'ANSIBLE_CALLBACK_PLUGINS',
                    callback_plugin + ':' + os.path.join(
                        sys.prefix,
                        'share/molecule/ansible/plugins/callback/idempotence'))
            else:
                ansible.add_env_arg('ANSIBLE_CALLBACK_PLUGINS', os.path.join(
                    sys.prefix,
                    'share/molecule/ansible/plugins/callback/idempotence'))

        ansible.bake()
        if self.molecule._args.get('--debug'):
            ansible_env = {k: v
                           for (k, v) in ansible.env.items() if 'ANSIBLE' in k}
            other_env = {k: v
                         for (k, v) in ansible.env.items()
                         if 'ANSIBLE' not in k}
            utilities.debug('OTHER ENVIRONMENT',
                            yaml.dump(other_env,
                                      default_flow_style=False,
                                      indent=2))
            utilities.debug('ANSIBLE ENVIRONMENT',
                            yaml.dump(ansible_env,
                                      default_flow_style=False,
                                      indent=2))
            utilities.debug('ANSIBLE PLAYBOOK', str(ansible.ansible))

        status, output = ansible.execute(hide_errors=hide_errors)
        if status is not None:
            if exit:
                sys.exit(status)
            return status, None

        if not self.molecule._state.get('converged'):
            self.molecule._state['converged'] = True
            self.molecule._write_state_file()

        return None, output
Example #7
0
    def execute(self,
                idempotent=False,
                create_instances=True,
                create_inventory=True,
                exit=True,
                hide_errors=True):
        """
        :param idempotent: Optionally provision servers quietly so output can be parsed for idempotence
        :param create_inventory: Toggle inventory creation
        :param create_instances: Toggle instance creation
        :return: Provisioning output
        """
        if self.molecule._state.get('created'):
            create_instances = False

        if self.molecule._state.get('converged'):
            create_inventory = False

        if self.static:
            create_instances = False
            create_inventory = False

        if create_instances and not idempotent:
            command_args, args = utilities.remove_args(self.command_args,
                                                       self.args, ['--tags'])
            c = Create(command_args, args, self.molecule)
            c.execute()

        if create_inventory:
            self.molecule._create_inventory_file()

        # install role dependencies only during `molecule converge`
        if not idempotent and 'requirements_file' in self.molecule._config.config[
                'ansible']:
            print('{}Installing role dependencies ...{}'.format(
                Fore.CYAN, Fore.RESET))
            galaxy_install = AnsibleGalaxyInstall(
                self.molecule._config.config['ansible']['requirements_file'])
            galaxy_install.add_env_arg(
                'ANSIBLE_CONFIG',
                self.molecule._config.config['ansible']['config_file'])
            galaxy_install.bake()
            output = galaxy_install.execute()

        ansible = AnsiblePlaybook(self.molecule._config.config['ansible'])

        # target tags passed in via CLI
        if self.molecule._args.get('--tags'):
            ansible.add_cli_arg('tags', self.molecule._args['--tags'].pop(0))

        if idempotent:
            ansible.remove_cli_arg('_out')
            ansible.remove_cli_arg('_err')
            ansible.add_env_arg('ANSIBLE_NOCOLOR', 'true')
            ansible.add_env_arg('ANSIBLE_FORCE_COLOR', 'false')

            # Save the previous callback plugin if any.
            callback_plugin = ansible.env.get('ANSIBLE_CALLBACK_PLUGINS', '')

            # Set the idempotence plugin.
            if callback_plugin:
                ansible.add_env_arg(
                    'ANSIBLE_CALLBACK_PLUGINS',
                    callback_plugin + ':' + os.path.join(
                        sys.prefix,
                        'share/molecule/ansible/plugins/callback/idempotence'))
            else:
                ansible.add_env_arg(
                    'ANSIBLE_CALLBACK_PLUGINS',
                    os.path.join(
                        sys.prefix,
                        'share/molecule/ansible/plugins/callback/idempotence'))

        ansible.bake()
        if self.molecule._args.get('--debug'):
            ansible_env = {
                k: v
                for (k, v) in ansible.env.items() if 'ANSIBLE' in k
            }
            other_env = {
                k: v
                for (k, v) in ansible.env.items() if 'ANSIBLE' not in k
            }
            utilities.debug(
                'OTHER ENVIRONMENT',
                yaml.dump(other_env, default_flow_style=False, indent=2))
            utilities.debug(
                'ANSIBLE ENVIRONMENT',
                yaml.dump(ansible_env, default_flow_style=False, indent=2))
            utilities.debug('ANSIBLE PLAYBOOK', str(ansible.ansible))

        status, output = ansible.execute(hide_errors=hide_errors)
        if status is not None:
            if exit:
                sys.exit(status)
            return status, None

        if not self.molecule._state.get('converged'):
            self.molecule._state['converged'] = True
            self.molecule._write_state_file()

        return None, output
Example #8
0
    def execute(self, idempotent=False, create_instances=True, create_inventory=True):
        """
        Provisions all instances using ansible-playbook.

        :param idempotent: Optionally provision servers quietly so output can be parsed for idempotence
        :param create_inventory: Toggle inventory creation
        :param create_instances: Toggle instance creation
        :return: Provisioning output
        """

        if self.molecule._state.get('created'):
            create_instances = False

        if self.molecule._state.get('converged'):
            create_inventory = False

        if self.static:
            create_instances = False
            create_inventory = False

        if create_instances and not idempotent:
            c = Create(self.args, self.molecule)
            c.execute()

        if create_inventory:
            self.molecule._create_inventory_file()

        ansible = AnsiblePlaybook(self.molecule._config.config['ansible'])

        # target tags passed in via CLI
        ansible.add_cli_arg('tags', self.molecule._args.get('--tags'))

        if idempotent:
            ansible.remove_cli_arg('_out')
            ansible.remove_cli_arg('_err')
            ansible.add_env_arg('ANSIBLE_NOCOLOR', 'true')
            ansible.add_env_arg('ANSIBLE_FORCE_COLOR', 'false')

            # Save the previous callback plugin if any.
            callback_plugin = ansible.env.get('ANSIBLE_CALLBACK_PLUGINS', '')

            # Set the idempotence plugin.
            if callback_plugin:
                ansible.add_env_arg('ANSIBLE_CALLBACK_PLUGINS', callback_plugin + ':' + os.path.join(
                    sys.prefix, 'share/molecule/ansible/plugins/callback/idempotence'))
            else:
                ansible.add_env_arg('ANSIBLE_CALLBACK_PLUGINS',
                                    os.path.join(sys.prefix, 'share/molecule/ansible/plugins/callback/idempotence'))

        ansible.bake()
        if self.molecule._args['--debug']:
            ansible_env = {k: v for (k, v) in ansible.env.items() if 'ANSIBLE' in k}
            other_env = {k: v for (k, v) in ansible.env.items() if 'ANSIBLE' not in k}
            utilities.debug('OTHER ENVIRONMENT', yaml.dump(other_env, default_flow_style=False, indent=2))
            utilities.debug('ANSIBLE ENVIRONMENT', yaml.dump(ansible_env, default_flow_style=False, indent=2))
            utilities.debug('ANSIBLE PLAYBOOK', str(ansible.ansible))

        output = ansible.execute()

        if not self.molecule._state.get('converged'):
            self.molecule._state['converged'] = True
            self.molecule._write_state_file()

        return output