Exemple #1
0
    def test_compose_environment(self):
        # Test
        sample = self._sample_environment()
        composed = composer.compose_environment(sample)

        # Verify
        self.assertTrue(isinstance(composed, str))

        # Check that it can both be parsed back as YAML and use the resulting
        # dict in the assertions
        template = yaml.safe_load(composed)

        # Verify Overall Structure
        self.assertEqual(2, len(template))
        self.assertTrue('parameters' in template)
        self.assertTrue('resource_registry' in template)

        # Verify Parameters
        self.assertEqual(2, len(template['parameters']))

        self.assertTrue('n1' in template['parameters'])
        self.assertEqual('v1', template['parameters']['n1'])

        self.assertTrue('n2' in template['parameters'])
        self.assertEqual('v2', template['parameters']['n2'])

        # Verify Resource Registry
        self.assertEqual(2, len(template['resource_registry']))

        self.assertTrue('a1' in template['resource_registry'])
        self.assertEqual('f1', template['resource_registry']['a1'])

        self.assertTrue('a2' in template['resource_registry'])
        self.assertEqual('f2', template['resource_registry']['a2'])
Exemple #2
0
    def test_compose_environment(self):
        # Test
        sample = self._sample_environment()
        composed = composer.compose_environment(sample)

        # Verify
        self.assertTrue(isinstance(composed, str))

        # Check that it can both be parsed back as YAML and use the resulting
        # dict in the assertions
        template = yaml.safe_load(composed)

        # Verify Overall Structure
        self.assertEqual(2, len(template))
        self.assertTrue('parameters' in template)
        self.assertTrue('resource_registry' in template)

        # Verify Parameters
        self.assertEqual(2, len(template['parameters']))

        self.assertTrue('n1' in template['parameters'])
        self.assertEqual('v1', template['parameters']['n1'])

        self.assertTrue('n2' in template['parameters'])
        self.assertEqual('v2', template['parameters']['n2'])

        # Verify Resource Registry
        self.assertEqual(2, len(template['resource_registry']))

        self.assertTrue('a1' in template['resource_registry'])
        self.assertEqual('f1', template['resource_registry']['a1'])

        self.assertTrue('a2' in template['resource_registry'])
        self.assertEqual('f2', template['resource_registry']['a2'])
Exemple #3
0
    def set_parameter_values(self, plan_uuid, params):
        """Sets the values for a plan's parameters.

        :type plan_uuid: str
        :type params: [tuskar.manager.models.ParameterValue]

        :return: plan instance with the updated values
        :rtype:  tuskar.manager.models.DeploymentPlan
        """

        # Load the plan from the database.
        db_plan = self.plan_store.retrieve(plan_uuid)

        # Save the values to the parsed environment.
        environment = parser.parse_environment(
            db_plan.environment_file.contents
        )

        for param_value in params:
            p = environment.find_parameter_by_name(param_value.name)
            p.value = param_value.value

        # Save the updated environment.
        env_contents = composer.compose_environment(environment)
        self.plan_store.update_environment(plan_uuid, env_contents)

        updated_plan = self.retrieve_plan(plan_uuid)
        return updated_plan
Exemple #4
0
    def _save_updated_plan(self, plan_uuid, deployment_plan):
        new_template_contents = composer.compose_template(
            deployment_plan.master_template)
        new_env_contents = composer.compose_environment(
            deployment_plan.environment)

        self.plan_store.update_master_template(plan_uuid,
                                               new_template_contents)
        self.plan_store.update_environment(plan_uuid, new_env_contents)

        # Retrieve and return the updated plan
        updated_plan = self.retrieve_plan(plan_uuid)
        return updated_plan
Exemple #5
0
    def _save_updated_plan(self, plan_uuid, deployment_plan):
        new_template_contents = composer.compose_template(
            deployment_plan.master_template
        )
        new_env_contents = composer.compose_environment(
            deployment_plan.environment
        )

        self.plan_store.update_master_template(plan_uuid,
                                               new_template_contents)
        self.plan_store.update_environment(plan_uuid,
                                           new_env_contents)

        # Retrieve and return the updated plan
        updated_plan = self.retrieve_plan(plan_uuid)
        return updated_plan
Exemple #6
0
    def create_plan(self, name, description):
        """Creates a new plan, persisting it to Tuskar's storage backend.

        :type name: str
        :type description: str
        :return: domain model instance of the created plan
        :rtype: tuskar.manager.models.DeploymentPlan
        :raises tuskar.storage.exceptions.NameAlreadyUsed: if there is a plan
                with the given name
        """

        # Create the plan using the template generation code first to
        # stub out the master template and environment files correctly.
        new_plan = plan.DeploymentPlan(description=description)

        # Save the newly created master template and environment to the
        # storage layer so they can be associated with the plan.
        master_template_contents = composer.compose_template(
            new_plan.master_template
        )
        master_template_file = self.master_template_store.create(
            name_utils.master_template_filename(name),
            master_template_contents,
        )

        environment_contents = composer.compose_environment(
            new_plan.environment
        )
        environment_file = self.environment_store.create(
            environment_contents
        )

        # Create the plan in storage, seeding it with the stored files for
        # the template and environment.
        db_plan = self.plan_store.create(
            name,
            master_template_uuid=master_template_file.uuid,
            environment_uuid=environment_file.uuid,
        )

        # Return the created plan.
        created_plan = self.retrieve_plan(db_plan.uuid)
        return created_plan
Exemple #7
0
    def set_parameter_values(self, plan_uuid, params):
        """Sets the values for a plan's parameters.

        :type plan_uuid: str
        :type params: [tuskar.manager.models.ParameterValue]

        :return: plan instance with the updated values
        :rtype:  tuskar.manager.models.DeploymentPlan
        """

        # Load the plan from the database.
        db_plan = self.plan_store.retrieve(plan_uuid)

        # Save the values to the parsed environment.
        environment = parser.parse_environment(
            db_plan.environment_file.contents
        )

        non_existent_params = []
        for param_value in params:
            p = environment.find_parameter_by_name(param_value.name)
            if p:
                p.value = param_value.value
            else:
                non_existent_params.append(param_value.name)

        if non_existent_params:
            param_names = ', '.join(non_existent_params)
            LOG.error(
                'There are no parameters named %(param_names)s'
                ' in plan %(plan_uuid)s.' %
                {'param_names': param_names, 'plan_uuid': plan_uuid})
            raise exception.PlanParametersNotExist(
                plan_uuid=plan_uuid,
                param_names=param_names
            )

        # Save the updated environment.
        env_contents = composer.compose_environment(environment)
        self.plan_store.update_environment(plan_uuid, env_contents)

        updated_plan = self.retrieve_plan(plan_uuid)
        return updated_plan
Exemple #8
0
    def create_plan(self, name, description):
        """Creates a new plan, persisting it to Tuskar's storage backend.

        :type name: str
        :type description: str
        :return: domain model instance of the created plan
        :rtype: tuskar.manager.models.DeploymentPlan
        :raises tuskar.storage.exceptions.NameAlreadyUsed: if there is a plan
                with the given name
        """

        # Create the plan using the template generation code first to
        # stub out the master template and environment files correctly.
        new_plan = plan.DeploymentPlan(description=description)

        # Save the newly created master template and environment to the
        # storage layer so they can be associated with the plan.
        master_template_contents = composer.compose_template(
            new_plan.master_template
        )
        master_template_file = self.master_template_store.create(
            name_utils.master_template_filename(name),
            master_template_contents,
        )

        environment_contents = composer.compose_environment(
            new_plan.environment
        )
        environment_file = self.environment_store.create(
            environment_contents
        )

        # Create the plan in storage, seeding it with the stored files for
        # the template and environment.
        db_plan = self.plan_store.create(
            name,
            master_template_uuid=master_template_file.uuid,
            environment_uuid=environment_file.uuid,
        )

        # Return the created plan.
        created_plan = self.retrieve_plan(db_plan.uuid)
        return created_plan
Exemple #9
0
    def set_parameter_values(self, plan_uuid, params):
        """Sets the values for a plan's parameters.

        :type plan_uuid: str
        :type params: [tuskar.manager.models.ParameterValue]

        :return: plan instance with the updated values
        :rtype:  tuskar.manager.models.DeploymentPlan
        """

        # Load the plan from the database.
        db_plan = self.plan_store.retrieve(plan_uuid)

        # Save the values to the parsed environment.
        environment = parser.parse_environment(
            db_plan.environment_file.contents
        )

        non_existent_params = []
        for param_value in params:
            p = environment.find_parameter_by_name(param_value.name)
            if p:
                p.value = param_value.value
            else:
                non_existent_params.append(param_value.name)

        if non_existent_params:
            param_names = ', '.join(non_existent_params)
            LOG.error(
                'There are no parameters named %(param_names)s'
                ' in plan %(plan_uuid)s.' %
                {'param_names': param_names, 'plan_uuid': plan_uuid})
            raise exception.PlanParametersNotExist(
                plan_uuid=plan_uuid,
                param_names=param_names
            )

        # Save the updated environment.
        env_contents = composer.compose_environment(environment)
        self.plan_store.update_environment(plan_uuid, env_contents)

        updated_plan = self.retrieve_plan(plan_uuid)
        return updated_plan
Exemple #10
0
    def package_templates(self, plan_uuid):
        """Packages and returns all of the templates related to the given plan.
        The returned dictionary is keyed by filename and contains the contents
        of that file (a template or an environment file).

        :type plan_uuid: str

        :return: mapping of filename to contents for each file in the plan
        :rtype:  dict

        :raises tuskar.storage.exceptions.UnknownUUID: if there is no plan
                with the given UUID
        """

        # Load and parse the plan.
        db_plan = self.plan_store.retrieve(plan_uuid)
        master_template = parser.parse_template(
            db_plan.master_template.contents
        )
        environment = parser.parse_environment(
            db_plan.environment_file.contents
        )

        # Compose the plan files and all plan roles and package them into
        # a single dictionary.
        plan_contents = composer.compose_template(master_template)
        env_contents = composer.compose_environment(environment)

        files_dict = {
            'plan.yaml': plan_contents,
            'environment.yaml': env_contents,
        }

        plan_roles = self._find_roles(environment)

        for role in plan_roles:
            contents = composer.compose_template(role.template)
            filename = name_utils.role_template_filename(role.name,
                                                         role.version)
            files_dict[filename] = contents

        return files_dict
Exemple #11
0
    def package_templates(self, plan_uuid):
        """Packages and returns all of the templates related to the given plan.
        The returned dictionary is keyed by filename and contains the contents
        of that file (a template or an environment file).

        :type plan_uuid: str

        :return: mapping of filename to contents for each file in the plan
        :rtype:  dict

        :raises tuskar.storage.exceptions.UnknownUUID: if there is no plan
                with the given UUID
        """

        # Load and parse the plan.
        db_plan = self.plan_store.retrieve(plan_uuid)
        master_template = parser.parse_template(
            db_plan.master_template.contents
        )
        environment = parser.parse_environment(
            db_plan.environment_file.contents
        )

        # Compose the plan files and all plan roles and package them into
        # a single dictionary.
        plan_contents = composer.compose_template(master_template)
        env_contents = composer.compose_environment(environment)

        files_dict = {
            'plan.yaml': plan_contents,
            'environment.yaml': env_contents,
        }

        plan_roles = self._find_roles(environment)

        for role in plan_roles:
            contents = composer.compose_template(role.template)
            filename = name_utils.role_template_filename(role.name,
                                                         role.version)
            files_dict[filename] = contents

        return files_dict
Exemple #12
0
    def package_templates(self, plan_uuid):
        """Packages and returns all of the templates related to the given plan.
        The returned dictionary is keyed by filename and contains the contents
        of that file (a template or an environment file).

        :type plan_uuid: str

        :return: mapping of filename to contents for each file in the plan
        :rtype:  dict

        :raises tuskar.storage.exceptions.UnknownUUID: if there is no plan
                with the given UUID
        """

        # Load and parse the plan.
        db_plan = self.plan_store.retrieve(plan_uuid)
        master_template = parser.parse_template(
            db_plan.master_template.contents
        )
        environment = parser.parse_environment(
            db_plan.environment_file.contents
        )

        # Compose the plan files and all plan roles and package them into
        # a single dictionary.
        plan_contents = composer.compose_template(master_template)
        env_contents = composer.compose_environment(environment)

        files_dict = {
            'plan.yaml': plan_contents,
            'environment.yaml': env_contents,
        }

        plan_roles = self._find_roles(environment)
        manager = RoleManager()
        for role in plan_roles:
            contents = composer.compose_template(role.template)
            filename = name_utils.role_template_filename(role.name,
                                                         role.version,
                                                         role.relative_path)
            files_dict[filename] = contents

        def _add_template_extra_data_for(templates, template_store):
            template_extra_data = manager.retrieve_db_role_extra()
            for template in templates:
                db_template = template_store.retrieve_by_name(template.name)
                prefix = os_path.split(db_template.name)[0]
                template_extra_paths = utils.resolve_template_extra_data(
                    db_template, template_extra_data)
                extra_data_output = manager.template_extra_data_for_output(
                    template_extra_paths, prefix)
                files_dict.update(extra_data_output)

        # also grab any extradata files for the role
        _add_template_extra_data_for(plan_roles, self.template_store)

        # in addition to provider roles above, return non-role template files
        reg_mapping = self.registry_mapping_store.list()
        for entry in reg_mapping:
            if os_path.splitext(entry.name)[1] in ('.yaml', '.yml'):
                # if entry is an alias, don't include it
                files_dict[entry.name] = entry.contents

        # similarly, also grab extradata files for the non role templates
        _add_template_extra_data_for(reg_mapping, self.registry_mapping_store)

        return files_dict
Exemple #13
0
    def package_templates(self, plan_uuid):
        """Packages and returns all of the templates related to the given plan.
        The returned dictionary is keyed by filename and contains the contents
        of that file (a template or an environment file).

        :type plan_uuid: str

        :return: mapping of filename to contents for each file in the plan
        :rtype:  dict

        :raises tuskar.storage.exceptions.UnknownUUID: if there is no plan
                with the given UUID
        """

        # Load and parse the plan.
        db_plan = self.plan_store.retrieve(plan_uuid)
        master_template = parser.parse_template(
            db_plan.master_template.contents)
        environment = parser.parse_environment(
            db_plan.environment_file.contents)

        # Compose the plan files and all plan roles and package them into
        # a single dictionary.
        plan_contents = composer.compose_template(master_template)
        env_contents = composer.compose_environment(environment)

        files_dict = {
            'plan.yaml': plan_contents,
            'environment.yaml': env_contents,
        }

        plan_roles = self._find_roles(environment)
        manager = RoleManager()
        for role in plan_roles:
            contents = composer.compose_template(role.template)
            filename = name_utils.role_template_filename(
                role.name, role.version, role.relative_path)
            files_dict[filename] = contents

        def _add_template_extra_data_for(templates, template_store):
            template_extra_data = manager.retrieve_db_role_extra()
            for template in templates:
                db_template = template_store.retrieve_by_name(template.name)
                prefix = os_path.split(db_template.name)[0]
                template_extra_paths = utils.resolve_template_extra_data(
                    db_template, template_extra_data)
                extra_data_output = manager.template_extra_data_for_output(
                    template_extra_paths, prefix)
                files_dict.update(extra_data_output)

        # also grab any extradata files for the role
        _add_template_extra_data_for(plan_roles, self.template_store)

        # in addition to provider roles above, return non-role template files
        reg_mapping = self.registry_mapping_store.list()
        for entry in reg_mapping:
            if os_path.splitext(entry.name)[1] in ('.yaml', '.yml'):
                # if entry is an alias, don't include it
                files_dict[entry.name] = entry.contents

        # similarly, also grab extradata files for the non role templates
        _add_template_extra_data_for(reg_mapping, self.registry_mapping_store)

        return files_dict