Beispiel #1
0
    def provision(self):
        extra_vars = {
            # including blockchain-specific part of the playbook
            'blockchain_ansible_playbook':
            fs.join(self._roles_path, AnsibleBinding.BLOCKCHAIN_ROLE_NAME,
                    'tank', 'playbook.yml'),
            # saving a report of the important cluster facts
            '_cluster_ansible_report':
            self._cluster_report_file,
        }

        with self._lock:
            sh.Command("ansible-playbook")(
                "-f",
                "50",
                "-u",
                "root",
                "-i",
                self._app.terraform_inventory_run_command,
                "--extra-vars",
                self._ansible_extra_vars(extra_vars),
                "--private-key={}".format(
                    self._app.cloud_settings.provider_vars['pvt_key']),
                resource_path('ansible', 'core.yml'),
                _env=self._make_env(),
                _out=sys.stdout,
                _err=sys.stderr,
                _cwd=self._tf_plan_dir)
Beispiel #2
0
    def __init__(self, app):
        """Load or copy config file."""
        self._config_file = fs.join(app.user_dir, self.FILE_NAME)

        if not os.path.exists(self._config_file):
            copy2(resource_path('regions.yml'), self._config_file)

        self._config = yaml_load(self._config_file)
Beispiel #3
0
    def __init__(self, app):
        self._app = app

        self.config_file = fs.join(app.user_dir, 'bindings.yml')
        # TODO atomically
        if not os.path.exists(self.config_file):
            # setting up the default config
            copy2(resource_path('bindings.yml'), self.config_file)

        # TODO validate
        self._config = yaml_load(self.config_file)
Beispiel #4
0
class TestCaseValidator(object):
    """Class for validation TestCase object."""

    SCHEMA_FILE = resource_path('testcase_schema.yml')

    def __init__(self, content: dict, filename):
        """Save filename with content."""
        self._content = content
        self._filename = filename

    def validate(self):
        """Perform all validations."""
        self._validate_schema()
        self._check_reserved_names()
        self._check_counts_equality()

    def _validate_schema(self):
        """Validate via JSON schema."""
        try:
            Draft4Validator(yaml_load(self.SCHEMA_FILE)).validate(self._content)
        except ValidationError as e:
            raise TankTestCaseError('Failed to validate testcase {}'.format(self._filename), e)

    def _check_reserved_names(self):
        """Check reserved names existence."""
        reserved_names = {'count', 'monitoring'}

        for role in self._content['instances'].keys():
            if role.lower() in reserved_names:
                raise TankTestCaseError('\'{name}\' instance name is reserved'.format(name=role))

    def _check_counts_equality(self):
        """Check if total count is equal with sum of counts in regions."""
        for role, config in self._content['instances'].items():
            if isinstance(config, dict) and all(key in config for key in ['count', 'regions']):
                total_count = config['count']
                regions_count = 0

                for region, region_config in config['regions'].items():
                    if isinstance(region_config, int):
                        regions_count += region_config
                    else:
                        regions_count += region_config['count']

                if total_count != regions_count:
                    raise TankTestCaseError(
                        'The total count does not match sum of count in regions in role {}'.format(role)
                    )
Beispiel #5
0
    def new_run(cls, app, testcase: TestCase):
        run_id = namesgenerator.get_random_name()

        fs.ensure_dir_exists(cls._runs_dir(app))

        temp_dir = tempfile.mkdtemp(prefix='_{}'.format(run_id),
                                    dir=cls._runs_dir(app))
        cls._save_meta(temp_dir, testcase)

        # make a copy to make sure any alterations of the source won't affect us
        testcase.save(fs.join(temp_dir, 'testcase.yml'))

        copytree(resource_path('scripts'), temp_dir + '/scripts')

        # TODO prevent collisions
        os.rename(temp_dir, fs.join(cls._runs_dir(app), run_id))

        return cls(app, run_id)
Beispiel #6
0
    def _make_env(self) -> Dict:
        fs.ensure_dir_exists(self._tf_data_dir)
        fs.ensure_dir_exists(self._log_dir)

        env = self._app.app_env

        env["TF_LOG_PATH"] = fs.join(self._log_dir, 'terraform.log')
        env["TF_DATA_DIR"] = self._tf_data_dir
        env["TF_VAR_state_path"] = self._tf_state_file
        env["TF_VAR_blockchain_name"] = self._testcase.binding.replace(
            '_', '-')[:10]
        env["TF_VAR_setup_id"] = self._meta['setup_id']

        for k, v in self._app.cloud_settings.provider_vars.items():
            env["TF_VAR_{}".format(k)] = v

        env["ANSIBLE_ROLES_PATH"] = self._roles_path
        env["ANSIBLE_CONFIG"] = resource_path('ansible', 'ansible.cfg')

        return env
Beispiel #7
0
    def dependency(self):
        """
        Install Ansible roles from Galaxy or SCM.
        """
        with self._lock:
            ansible_deps = yaml_load(
                resource_path('ansible', 'ansible-requirements.yml'))

            ansible_deps.extend(
                AnsibleBinding(self._app,
                               self._testcase.binding).get_dependencies())

            requirements_file = fs.join(self._dir, 'ansible-requirements.yml')
            yaml_dump(requirements_file, ansible_deps)

            sh.Command("ansible-galaxy")("install",
                                         "-f",
                                         "-r",
                                         requirements_file,
                                         _env=self._make_env(),
                                         _out=sys.stdout,
                                         _err=sys.stderr)
Beispiel #8
0
 def _provider_templates(self) -> str:
     return resource_path('providers',
                          self._app.cloud_settings.provider.value)