Beispiel #1
0
    def post(self, transfer_plan):
        """Creates a new plan.

        :param transfer_plan: data submitted by the user
        :type  transfer_plan:
            tuskar.api.controllers.v1.models.Plan

        :return: created plan
        :rtype:  tuskar.api.controllers.v1.models.Plan

        :raises: tuskar.common.exception.PlanExists: if a plan
                 with the given name exists
        """
        LOG.debug('Creating plan: %s' % transfer_plan)

        # We don't want the wsme types bleed into the rest of Tuskar, so
        # explicitly set to None if it wasn't specified.
        description = transfer_plan.description
        if isinstance(description, UnsetType):
            description = None

        manager = PlansManager()
        try:
            created = manager.create_plan(transfer_plan.name,
                                          description)
        except storage_exceptions.NameAlreadyUsed:
            LOG.exception('Plan already exists with this name')
            raise exception.PlanExists(transfer_plan.name)
        transfer = models.Plan.from_tuskar_model(created)
        return transfer
Beispiel #2
0
    def post(self, transfer_plan):
        """Creates a new plan.

        :param transfer_plan: data submitted by the user
        :type  transfer_plan:
            tuskar.api.controllers.v1.models.Plan

        :return: created plan
        :rtype:  tuskar.api.controllers.v1.models.Plan

        :raises: tuskar.common.exception.PlanExists: if a plan
                 with the given name exists
        """
        LOG.debug('Creating plan: %s' % transfer_plan)

        # We don't want the wsme types bleed into the rest of Tuskar, so
        # explicitly set to None if it wasn't specified.
        description = transfer_plan.description
        if isinstance(description, UnsetType):
            description = None

        manager = PlansManager()
        try:
            created = manager.create_plan(transfer_plan.name, description)
        except storage_exceptions.NameAlreadyUsed:
            LOG.exception('Plan already exists with this name')
            raise exception.PlanExists(transfer_plan.name)
        transfer = models.Plan.from_tuskar_model(created)
        return transfer
Beispiel #3
0
    def post(self, plan_uuid, role):
        """Adds a new role to plan.

        :param plan_uuid: identifies the plan
        :type  plan_uuid: str

        :param role: identifies the role to add
        :type  role: tuskar.api.controllers.v2.models.Role

        :return: modified plan
        :rtype:  tuskar.api.controllers.v2.models.Plan

        :raises: tuskar.common.exception.PlanAlreadyHasRole if the role has
            already been added to the plan.
        """
        LOG.debug('Adding role: %s' % role.uuid)
        manager = PlansManager()
        try:
            updated_plan = manager.add_role_to_plan(plan_uuid, role.uuid)
        except ValueError:
            LOG.debug('The role has already been added to the plan.')
            raise exception.PlanAlreadyHasRole(
                plan_uuid=plan_uuid,
                role_uuid=role.uuid
            )
        except storage_exceptions.UnknownUUID as e:
            LOG.debug(('Either the plan UUID {0} or role UUID {1} could not be'
                       'found').format(plan_uuid, role.uuid))
            raise exception.NotFound(
                message=str(e))
        transfer_plan = models.Plan.from_tuskar_model(updated_plan)
        return transfer_plan
Beispiel #4
0
    def post(self, plan_uuid, role):
        """Adds a new role to plan.

        :param plan_uuid: identifies the plan
        :type  plan_uuid: str

        :param role: identifies the role to add
        :type  role: tuskar.api.controllers.v2.models.Role

        :return: modified plan
        :rtype:  tuskar.api.controllers.v2.models.Plan

        :raises: tuskar.common.exception.PlanAlreadyHasRole if the role has
            already been added to the plan.
        """
        LOG.debug('Adding role: %(role_uuid)s to plan: %(plan_uuid)s' %
                  {'role_uuid': role.uuid, 'plan_uuid': plan_uuid})
        manager = PlansManager()
        try:
            updated_plan = manager.add_role_to_plan(plan_uuid, role.uuid)
        except ValueError:
            LOG.debug('The role has already been added to the plan.')
            raise exception.PlanAlreadyHasRole(
                plan_uuid=plan_uuid,
                role_uuid=role.uuid
            )
        except storage_exceptions.UnknownUUID as e:
            LOG.debug(('Either the plan UUID {0} or role UUID {1} could not be'
                       'found').format(plan_uuid, role.uuid))
            raise exception.NotFound(
                message=str(e))
        transfer_plan = models.Plan.from_tuskar_model(updated_plan)
        return transfer_plan
Beispiel #5
0
    def setUp(self):
        super(PlansManagerTestCase, self).setUp()
        self.plans_manager = PlansManager()

        self.plan_store = DeploymentPlanStore()
        self.template_store = TemplateStore()
        self.seed_store = MasterSeedStore()
        self.registry_store = ResourceRegistryStore()
Beispiel #6
0
    def patch(self, plan_uuid, param_list):
        """Patches existing plan.

        :return: patched plan
        :rtype:  tuskar.api.controllers.v1.models.Plan
        """
        manager = PlansManager()
        params = [p.to_tuskar_model() for p in param_list]
        updated_plan = manager.set_parameter_values(plan_uuid, params)
        transfer_plan = models.Plan.from_tuskar_model(updated_plan)
        return transfer_plan
Beispiel #7
0
    def get_all(self):
        """Returns all plans.

        An empty list is returned if no plans are present.

        :return: list of plans; empty list if none are found
        :rtype:  list of tuskar.api.controllers.v2.models.Plan
        """
        LOG.debug('Retrieving all plans')
        manager = PlansManager()
        all_plans = manager.list_plans()
        transfer_plans = [models.Plan.from_tuskar_model(p) for p in all_plans]
        return transfer_plans
Beispiel #8
0
    def delete(self, plan_uuid, role_uuid):
        """Removes a role from given plan.

        :param plan_uuid: identifies the plan
        :type  plan_uuid: str

        :param role_uuid: identifies the role to be deleted from plan
        :type  role_uuid: str
        """
        manager = PlansManager()
        updated_plan = manager.remove_role_from_plan(plan_uuid, role_uuid)
        transfer_plan = models.Plan.from_tuskar_model(updated_plan)
        return transfer_plan
Beispiel #9
0
    def get_all(self):
        """Returns all plans.

        An empty list is returned if no plans are present.

        :return: list of plans; empty list if none are found
        :rtype:  list of tuskar.api.controllers.v2.models.Plan
        """
        LOG.debug('Retrieving all plans')
        manager = PlansManager()
        all_plans = manager.list_plans()
        transfer_plans = [models.Plan.from_tuskar_model(p)
                          for p in all_plans]
        return transfer_plans
Beispiel #10
0
def _check_roles_in_use(role_ids):
    manager = PlansManager()
    plan_list = manager.list_plans()
    plan_store = DeploymentPlanStore()
    for plan in plan_list:
        db_plan = plan_store.retrieve(plan.uuid)
        environment = parser.parse_environment(
            db_plan.environment_file.contents)
        roles_in_use = ([
            role.uuid for role in manager._find_roles(environment)
        ])
        intersection = set(roles_in_use) & set(role_ids)
        if intersection:
            raise OvercloudRoleInUse(name=", ".join(intersection))
Beispiel #11
0
def _check_roles_in_use(role_ids):
    manager = PlansManager()
    plan_list = manager.list_plans()
    plan_store = DeploymentPlanStore()
    for plan in plan_list:
        db_plan = plan_store.retrieve(plan.uuid)
        environment = parser.parse_environment(
            db_plan.environment_file.contents
        )
        roles_in_use = (
            [role.uuid for role in manager._find_roles(environment)])
        intersection = set(roles_in_use) & set(role_ids)
        if intersection:
            raise OvercloudRoleInUse(name=", ".join(intersection))
Beispiel #12
0
    def patch(self, plan_uuid, param_list):
        """Patches existing plan.

        :return: patched plan
        :rtype:  tuskar.api.controllers.v1.models.Plan
        """
        manager = PlansManager()
        params = [p.to_tuskar_model() for p in param_list]
        try:
            updated_plan = manager.set_parameter_values(plan_uuid, params)
        except storage_exceptions.UnknownUUID:
            LOG.exception('Could not patch plan: %s' % plan_uuid)
            raise exception.PlanNotFound()
        transfer_plan = models.Plan.from_tuskar_model(updated_plan)
        return transfer_plan
Beispiel #13
0
    def patch(self, plan_uuid, param_list):
        """Patches existing plan.

        :return: patched plan
        :rtype:  tuskar.api.controllers.v1.models.Plan
        """
        manager = PlansManager()
        params = [p.to_tuskar_model() for p in param_list]
        try:
            updated_plan = manager.set_parameter_values(plan_uuid, params)
        except storage_exceptions.UnknownUUID:
            LOG.exception('Could not patch plan: %s' % plan_uuid)
            raise exception.PlanNotFound()
        transfer_plan = models.Plan.from_tuskar_model(updated_plan)
        return transfer_plan
Beispiel #14
0
    def delete(self, plan_uuid):
        """Deletes the given plan.

        :param plan_uuid: identifies the plan being deleted
        :type  plan_uuid: str

        :raises: tuskar.common.exception.PlanNotFound if there
                 is no plan with the given UUID
        """

        LOG.debug('Deleting plan with UUID: %s' % plan_uuid)
        manager = PlansManager()
        try:
            manager.delete_plan(plan_uuid)
        except storage_exceptions.UnknownUUID:
            LOG.exception('Could not delete plan: %s' % plan_uuid)
            raise exception.PlanNotFound()
Beispiel #15
0
    def delete(self, plan_uuid):
        """Deletes the given plan.

        :param plan_uuid: identifies the plan being deleted
        :type  plan_uuid: str

        :raises: tuskar.common.exception.PlanNotFound if there
                 is no plan with the given UUID
        """

        LOG.debug('Deleting plan with UUID: %s' % plan_uuid)
        manager = PlansManager()
        try:
            manager.delete_plan(plan_uuid)
        except storage_exceptions.UnknownUUID:
            LOG.exception('Could not delete plan: %s' % plan_uuid)
            raise exception.PlanNotFound()
Beispiel #16
0
    def templates(self, plan_uuid):
        """Returns the template files for a given plan.

        :return: dictionary of filenames to contents for each template file
                 involved in the plan
        :rtype:  dict
        """
        LOG.debug('Retrieving templates for plan: %s' % plan_uuid)

        manager = PlansManager()
        try:
            templates = manager.package_templates(plan_uuid)
        except storage_exceptions.UnknownUUID:
            LOG.exception('Could not retrieve templates for plan: %s' %
                          plan_uuid)
            raise exception.PlanNotFound()

        return templates
Beispiel #17
0
    def setUp(self):
        super(PlansManagerTestCase, self).setUp()
        self.plans_manager = PlansManager()

        self.plan_store = DeploymentPlanStore()
        self.template_store = TemplateStore()
        self.seed_store = MasterSeedStore()
        self.registry_store = ResourceRegistryStore()
        self.registry_mapping_store = ResourceRegistryMappingStore()
Beispiel #18
0
    def templates(self, plan_uuid):
        """Returns the template files for a given plan.

        :return: dictionary of filenames to contents for each template file
                 involved in the plan
        :rtype:  dict
        """
        LOG.debug('Retrieving templates for plan: %s' % plan_uuid)

        manager = PlansManager()
        try:
            templates = manager.package_templates(plan_uuid)
        except storage_exceptions.UnknownUUID:
            LOG.exception('Could not retrieve templates for plan: %s' %
                          plan_uuid)
            raise exception.PlanNotFound()

        return templates
Beispiel #19
0
    def delete(self, plan_uuid, role_uuid):
        """Removes a role from given plan.

        :param plan_uuid: identifies the plan
        :type  plan_uuid: str

        :param role_uuid: identifies the role to be deleted from plan
        :type  role_uuid: str
        """
        LOG.debug('Removing role: %(role_uuid)s from plan: %(plan_uuid)s' %
                  {'role_uuid': role_uuid, 'plan_uuid': plan_uuid})
        manager = PlansManager()
        try:
            updated_plan = manager.remove_role_from_plan(plan_uuid, role_uuid)
        except storage_exceptions.UnknownUUID as e:
            LOG.debug(('Either the plan UUID {0} or role UUID {1} could not be'
                       'found').format(plan_uuid, role_uuid))
            raise exception.NotFound(
                message=str(e))
        transfer_plan = models.Plan.from_tuskar_model(updated_plan)
        return transfer_plan
Beispiel #20
0
    def get_one(self, plan_uuid):
        """Returns a specific plan.

        An exception is raised if no plan is found with the
        given UUID.

        :param plan_uuid: identifies the plan being fetched
        :type  plan_uuid: str

        :return: matching plan
        :rtype:  tuskar.api.controllers.v2.models.Plan

        :raises: tuskar.common.exception.PlanNotFound if there
                 is no plan with the given UUID
        """
        LOG.debug('Retrieving plan with UUID: %s' % plan_uuid)
        manager = PlansManager()
        try:
            found = manager.retrieve_plan(plan_uuid)
        except storage_exceptions.UnknownUUID:
            LOG.exception('Could not retrieve plan: %s' % plan_uuid)
            raise exception.PlanNotFound()
        transfer = models.Plan.from_tuskar_model(found)
        return transfer
Beispiel #21
0
    def get_one(self, plan_uuid):
        """Returns a specific plan.

        An exception is raised if no plan is found with the
        given UUID.

        :param plan_uuid: identifies the plan being fetched
        :type  plan_uuid: str

        :return: matching plan
        :rtype:  tuskar.api.controllers.v2.models.Plan

        :raises: tuskar.common.exception.PlanNotFound if there
                 is no plan with the given UUID
        """
        LOG.debug('Retrieving plan with UUID: %s' % plan_uuid)
        manager = PlansManager()
        try:
            found = manager.retrieve_plan(plan_uuid)
        except storage_exceptions.UnknownUUID:
            LOG.exception('Could not retrieve plan: %s' % plan_uuid)
            raise exception.PlanNotFound()
        transfer = models.Plan.from_tuskar_model(found)
        return transfer
Beispiel #22
0
class PlansManagerTestCase(TestCase):
    def setUp(self):
        super(PlansManagerTestCase, self).setUp()
        self.plans_manager = PlansManager()

        self.plan_store = DeploymentPlanStore()
        self.template_store = TemplateStore()
        self.seed_store = MasterSeedStore()
        self.registry_store = ResourceRegistryStore()
        self.registry_mapping_store = ResourceRegistryMappingStore()

    def test_create_plan(self):
        # Tests
        created = self.plans_manager.create_plan('p1', 'desc-1')

        # Verify
        self.assertTrue(created is not None)
        self.assertTrue(isinstance(created, DeploymentPlan))
        self.assertTrue(created.uuid is not None)
        self.assertEqual('p1', created.name)
        self.assertEqual('desc-1', created.description)
        self.assertEqual(0, len(created.roles))
        self.assertEqual(0, len(created.parameters))

        found = self.plans_manager.retrieve_plan(created.uuid)
        self.assertTrue(found is not None)

    def test_delete_plan(self):
        # Setup
        created = self.plans_manager.create_plan('p1', 'desc-1')
        db_plan = self.plan_store.retrieve(created.uuid)

        # Test
        self.plans_manager.delete_plan(created.uuid)

        # Verify
        self.assertRaises(UnknownUUID, self.plans_manager.retrieve_plan,
                          created.uuid)

        env_store = EnvironmentFileStore()
        self.assertRaises(UnknownUUID, env_store.retrieve,
                          db_plan.environment_file.uuid)

        master_store = MasterTemplateStore()
        self.assertRaises(UnknownUUID, master_store.retrieve,
                          db_plan.master_template.uuid)

    def test_add_role_to_plan(self):
        # Setup
        test_role = self._add_test_role()
        test_plan = self.plans_manager.create_plan('p1', 'd1')

        # Test
        self.plans_manager.add_role_to_plan(test_plan.uuid, test_role.uuid)

        # Verify
        db_plan = self.plan_store.retrieve(test_plan.uuid)
        parsed_plan = parser.parse_template(db_plan.master_template.contents)
        self.assertEqual(1, len(parsed_plan.resources))

    def test_add_role_to_seeded_plan(self):
        # Setup
        self.seed_store.create(MASTER_SEED_NAME, TEST_SEED)
        self.registry_store.create(RESOURCE_REGISTRY_NAME, RESOURCE_REGISTRY)
        # more setup (this is normally called in load_roles)
        self.registry_mapping_store.create('required_file.yaml',
                                           'some fake template data')
        test_role = self._add_test_role()
        test_plan = self.plans_manager.create_plan('p1', 'd1')

        # Test
        self.plans_manager.add_role_to_plan(test_plan.uuid, test_role.uuid)

        # Verify
        db_plan = self.plan_store.retrieve(test_plan.uuid)
        parsed_plan = parser.parse_template(db_plan.master_template.contents)
        self.assertEqual(2, len(parsed_plan.resources))

        # The role generated in the plan has a different name:
        my_role = parsed_plan.find_resource_by_id('r1')
        self.assertIsNot(my_role, None)

        # The reference to the role in some_config should be updated:
        some_config = parsed_plan.find_resource_by_id('some_config')
        self.assertIsNot(some_config, None)
        config_property = some_config.find_property_by_name('config')
        self.assertIsNot(config_property, None)
        self.assertEqual(config_property.value,
                         {'ip_addresses': {
                             'get_attr': ['r1', 'foo_ip']
                         }})

        # verify both entries are present from RESOURCE_REGISTRY
        parsed_env = parser.parse_environment(
            db_plan.environment_file.contents)
        self.assertEqual(2, len(parsed_env.registry_entries))

    def test_add_unknown_role_to_seeded_plan(self):
        # Setup
        self.seed_store.create(MASTER_SEED_NAME, TEST_SEED)
        self.registry_store.create(RESOURCE_REGISTRY_NAME, RESOURCE_REGISTRY)
        test_role = self.template_store.create('unknown_role', TEST_TEMPLATE)
        test_plan = self.plans_manager.create_plan('p1', 'd1')

        # Test
        self.assertRaises(ValueError, self.plans_manager.add_role_to_plan,
                          test_plan.uuid, test_role.uuid)

    def test_add_role_of_unknown_type_to_seeded_plan(self):
        # Setup
        self.seed_store.create(MASTER_SEED_NAME, TEST_SEED)
        self.registry_store.create(RESOURCE_REGISTRY_NAME,
                                   RESOURCE_REGISTRY_WRONG_TYPE)
        test_role = self._add_test_role()
        test_plan = self.plans_manager.create_plan('p1', 'd1')

        # Test
        self.assertRaises(ValueError, self.plans_manager.add_role_to_plan,
                          test_plan.uuid, test_role.uuid)

    def test_add_role_to_seeded_plan_without_registry(self):
        # Setup
        self.seed_store.create(MASTER_SEED_NAME, TEST_SEED)
        test_role = self._add_test_role()
        test_plan = self.plans_manager.create_plan('p1', 'd1')

        # Resource registry is missing, adding role should fail
        self.assertRaises(UnknownName, self.plans_manager.add_role_to_plan,
                          test_plan.uuid, test_role.uuid)

    def test_remove_role_from_plan(self):
        # Setup
        test_role = self._add_test_role()
        test_plan = self.plans_manager.create_plan('p1', 'd1')
        self.plans_manager.add_role_to_plan(test_plan.uuid, test_role.uuid)

        # Test
        self.plans_manager.remove_role_from_plan(test_plan.uuid,
                                                 test_role.uuid)

        # Verify
        db_plan = self.plan_store.retrieve(test_plan.uuid)
        parsed_plan = parser.parse_template(db_plan.master_template.contents)
        self.assertEqual(0, len(parsed_plan.resources))

    def test_retrieve_plan(self):
        # Setup
        test_role = self._add_test_role()
        test_plan = self.plans_manager.create_plan('p1', 'd1')
        self.plans_manager.add_role_to_plan(test_plan.uuid, test_role.uuid)

        # Test
        found = self.plans_manager.retrieve_plan(test_plan.uuid)

        # Verify
        self.assertTrue(found is not None)
        self.assertTrue(isinstance(found, DeploymentPlan))
        self.assertEqual(test_plan.uuid, found.uuid)
        self.assertEqual('p1', found.name)
        self.assertEqual('d1', found.description)
        self.assertEqual(1, len(found.roles))
        self.assertTrue(isinstance(found.roles[0], Role))
        self.assertEqual(4, len(found.parameters))  # 3 + 1 for scaling
        self.assertTrue(isinstance(found.parameters[0], PlanParameter))

    def test_list_plans(self):
        # Setup
        self.plans_manager.create_plan('p1', 'd1')
        self.plans_manager.create_plan('p2', 'd2')

        # Test
        all_plans = self.plans_manager.list_plans()

        # Verify
        self.assertEqual(2, len(all_plans))
        all_plans.sort(key=lambda x: x.name)
        self.assertEqual('p1', all_plans[0].name)
        self.assertEqual('p2', all_plans[1].name)

    def test_set_parameter_values(self):
        # Setup
        test_role = self._add_test_role()
        test_plan = self.plans_manager.create_plan('p1', 'd1')
        self.plans_manager.add_role_to_plan(test_plan.uuid, test_role.uuid)

        # Test
        ns = name_utils.generate_role_namespace(test_role.name,
                                                test_role.version)
        update_us = [
            ParameterValue(ns_utils.apply_template_namespace(ns, 'key_name'),
                           'test-key'),
            ParameterValue(ns_utils.apply_template_namespace(ns, 'image_id'),
                           'test-image'),
        ]
        updated_plan = self.plans_manager.set_parameter_values(
            test_plan.uuid, update_us)

        # Verify
        self.assertTrue(updated_plan is not None)
        self.assertTrue(isinstance(updated_plan, DeploymentPlan))

        # Pull it from the database again to make sure it was saved
        found = self.plans_manager.retrieve_plan(test_plan.uuid)
        found_params = sorted(found.parameters, key=lambda x: x.name)
        self.assertEqual(4, len(found_params))  # 3 + 1 for scaling
        self.assertEqual(found_params[0].value, '1')
        self.assertEqual(found_params[1].value, 'test-image')
        self.assertEqual(found_params[2].value, 'm1.small')
        self.assertEqual(found_params[3].value, 'test-key')

    def test_set_non_existent_parameters(self):
        # Setup
        test_role = self._add_test_role()
        test_plan = self.plans_manager.create_plan('p1', 'd1')
        self.plans_manager.add_role_to_plan(test_plan.uuid, test_role.uuid)

        # Test
        ns = name_utils.generate_role_namespace(test_role.name,
                                                test_role.version)
        not_present_in_role_1_name = ns_utils.apply_template_namespace(
            ns, 'not_present_in_role_1')
        not_present_in_role_2_name = ns_utils.apply_template_namespace(
            ns, 'not_present_in_role_2')
        update_us = [
            ParameterValue(ns_utils.apply_template_namespace(ns, 'key_name'),
                           'test-key'),
            ParameterValue(ns_utils.apply_template_namespace(ns, 'image_id'),
                           'test-image'),
            ParameterValue(not_present_in_role_1_name,
                           'not-present-in-role-1-value'),
            ParameterValue(not_present_in_role_2_name,
                           'not-present-in-role-2-value'),
        ]

        # Verify
        exc = self.assertRaises(exception.PlanParametersNotExist,
                                self.plans_manager.set_parameter_values,
                                test_plan.uuid, update_us)
        self.assertIn(not_present_in_role_1_name, str(exc))
        self.assertIn(not_present_in_role_2_name, str(exc))

        # Pull it from the database to make sure it was modified
        found = self.plans_manager.retrieve_plan(test_plan.uuid)
        found_params = sorted(found.parameters, key=lambda x: x.name)
        self.assertEqual(4, len(found_params))  # 3 + 1 for scaling
        self.assertEqual(found_params[0].value, '1')
        self.assertEqual(found_params[1].value,
                         '3e6270da-fbf7-4aef-bc78-6d0cfc3ad11b')
        self.assertEqual(found_params[2].value, 'm1.small')
        self.assertEqual(found_params[3].value, '')

    def test_package_templates(self):
        # Setup
        test_role = self._add_test_role()
        test_plan = self.plans_manager.create_plan('p1', 'd1')
        self.plans_manager.add_role_to_plan(test_plan.uuid, test_role.uuid)

        # Test
        templates = self.plans_manager.package_templates(test_plan.uuid)

        # Verify
        self.assertTrue(isinstance(templates, dict))
        self.assertEqual(3, len(templates))

        self.assertTrue('plan.yaml' in templates)
        parsed_plan = parser.parse_template(templates['plan.yaml'])
        self.assertEqual(parsed_plan.description, 'd1')

        self.assertTrue('environment.yaml' in templates)
        parsed_env = parser.parse_environment(templates['environment.yaml'])
        self.assertEqual(1, len(parsed_env.registry_entries))

        role_filename = name_utils.role_template_filename('r1', '1', None)
        self.assertTrue(role_filename in templates)
        parsed_role = parser.parse_template(templates[role_filename])
        self.assertEqual(parsed_role.description, 'Test provider resource foo')

    def test_package_templates_seeded_plan(self):
        # Setup
        self.seed_store.create(MASTER_SEED_NAME, TEST_SEED)
        self.registry_store.create(RESOURCE_REGISTRY_NAME, RESOURCE_REGISTRY)
        # more setup (this is normally called in load_roles)
        self.registry_mapping_store.create('required_file.yaml',
                                           'some fake template data')

        test_role = self._add_test_role()
        test_plan = self.plans_manager.create_plan('p1', 'd1')
        self.plans_manager.add_role_to_plan(test_plan.uuid, test_role.uuid)

        # Test
        templates = self.plans_manager.package_templates(test_plan.uuid)

        # Verify
        self.assertTrue(isinstance(templates, dict))
        self.assertEqual(4, len(templates))

        self.assertTrue('plan.yaml' in templates)
        parsed_plan = parser.parse_template(templates['plan.yaml'])
        self.assertEqual(parsed_plan.description, 'd1')

        self.assertTrue('environment.yaml' in templates)
        self.assertTrue('required_file.yaml' in templates)
        parsed_env = parser.parse_environment(templates['environment.yaml'])
        self.assertEqual(2, len(parsed_env.registry_entries))

        role_filename = name_utils.role_template_filename('r1', '1', None)
        self.assertTrue(role_filename in templates)
        parsed_role = parser.parse_template(templates[role_filename])
        self.assertEqual(parsed_role.description, 'Test provider resource foo')

    def test_find_roles(self):
        # Setup
        self.seed_store.create(MASTER_SEED_NAME, TEST_SEED)
        self.registry_store.create(RESOURCE_REGISTRY_NAME, RESOURCE_REGISTRY)
        # more setup (this is normally called in load_roles)
        self.registry_mapping_store.create('required_file.yaml',
                                           'some fake template data')
        test_role = self._add_test_role()
        test_plan = self.plans_manager.create_plan('p1', 'd1')

        # Test
        self.plans_manager.add_role_to_plan(test_plan.uuid, test_role.uuid)

        # Verify only one role is found
        db_plan = self.plan_store.retrieve(test_plan.uuid)
        parsed_env = parser.parse_environment(
            db_plan.environment_file.contents)
        roles = self.plans_manager._find_roles(parsed_env)
        self.assertEqual(1, len(roles))

    def _add_test_role(self):
        return self.template_store.create('r1',
                                          TEST_TEMPLATE,
                                          registry_path='r1.yaml')
Beispiel #23
0
class PlansManagerTestCase(TestCase):

    def setUp(self):
        super(PlansManagerTestCase, self).setUp()
        self.plans_manager = PlansManager()

        self.plan_store = DeploymentPlanStore()
        self.template_store = TemplateStore()
        self.seed_store = MasterSeedStore()
        self.registry_store = ResourceRegistryStore()
        self.registry_mapping_store = ResourceRegistryMappingStore()

    def test_create_plan(self):
        # Tests
        created = self.plans_manager.create_plan('p1', 'desc-1')

        # Verify
        self.assertTrue(created is not None)
        self.assertTrue(isinstance(created, DeploymentPlan))
        self.assertTrue(created.uuid is not None)
        self.assertEqual('p1', created.name)
        self.assertEqual('desc-1', created.description)
        self.assertEqual(0, len(created.roles))
        self.assertEqual(0, len(created.parameters))

        found = self.plans_manager.retrieve_plan(created.uuid)
        self.assertTrue(found is not None)

    def test_delete_plan(self):
        # Setup
        created = self.plans_manager.create_plan('p1', 'desc-1')
        db_plan = self.plan_store.retrieve(created.uuid)

        # Test
        self.plans_manager.delete_plan(created.uuid)

        # Verify
        self.assertRaises(UnknownUUID,
                          self.plans_manager.retrieve_plan,
                          created.uuid)

        env_store = EnvironmentFileStore()
        self.assertRaises(UnknownUUID, env_store.retrieve,
                          db_plan.environment_file.uuid)

        master_store = MasterTemplateStore()
        self.assertRaises(UnknownUUID, master_store.retrieve,
                          db_plan.master_template.uuid)

    def test_add_role_to_plan(self):
        # Setup
        test_role = self._add_test_role()
        test_plan = self.plans_manager.create_plan('p1', 'd1')

        # Test
        self.plans_manager.add_role_to_plan(test_plan.uuid, test_role.uuid)

        # Verify
        db_plan = self.plan_store.retrieve(test_plan.uuid)
        parsed_plan = parser.parse_template(db_plan.master_template.contents)
        self.assertEqual(1, len(parsed_plan.resources))

    def test_add_role_to_seeded_plan(self):
        # Setup
        self.seed_store.create(MASTER_SEED_NAME, TEST_SEED)
        self.registry_store.create(RESOURCE_REGISTRY_NAME, RESOURCE_REGISTRY)
        # more setup (this is normally called in load_roles)
        self.registry_mapping_store.create('required_file.yaml',
                                           'some fake template data')
        test_role = self._add_test_role()
        test_plan = self.plans_manager.create_plan('p1', 'd1')

        # Test
        self.plans_manager.add_role_to_plan(test_plan.uuid, test_role.uuid)

        # Verify
        db_plan = self.plan_store.retrieve(test_plan.uuid)
        parsed_plan = parser.parse_template(db_plan.master_template.contents)
        self.assertEqual(2, len(parsed_plan.resources))

        # The role generated in the plan has a different name:
        my_role = parsed_plan.find_resource_by_id('r1')
        self.assertIsNot(my_role, None)

        # The reference to the role in some_config should be updated:
        some_config = parsed_plan.find_resource_by_id('some_config')
        self.assertIsNot(some_config, None)
        config_property = some_config.find_property_by_name('config')
        self.assertIsNot(config_property, None)
        self.assertEqual(config_property.value,
                         {'ip_addresses':
                          {'get_attr': ['r1', 'foo_ip']}})

        # verify both entries are present from RESOURCE_REGISTRY
        parsed_env = parser.parse_environment(
            db_plan.environment_file.contents
        )
        self.assertEqual(2, len(parsed_env.registry_entries))

    def test_add_unknown_role_to_seeded_plan(self):
        # Setup
        self.seed_store.create(MASTER_SEED_NAME, TEST_SEED)
        self.registry_store.create(RESOURCE_REGISTRY_NAME, RESOURCE_REGISTRY)
        test_role = self.template_store.create('unknown_role', TEST_TEMPLATE)
        test_plan = self.plans_manager.create_plan('p1', 'd1')

        # Test
        self.assertRaises(ValueError, self.plans_manager.add_role_to_plan,
                          test_plan.uuid, test_role.uuid)

    def test_add_role_of_unknown_type_to_seeded_plan(self):
        # Setup
        self.seed_store.create(MASTER_SEED_NAME, TEST_SEED)
        self.registry_store.create(RESOURCE_REGISTRY_NAME,
                                   RESOURCE_REGISTRY_WRONG_TYPE)
        test_role = self._add_test_role()
        test_plan = self.plans_manager.create_plan('p1', 'd1')

        # Test
        self.assertRaises(ValueError, self.plans_manager.add_role_to_plan,
                          test_plan.uuid, test_role.uuid)

    def test_add_role_to_seeded_plan_without_registry(self):
        # Setup
        self.seed_store.create(MASTER_SEED_NAME, TEST_SEED)
        test_role = self._add_test_role()
        test_plan = self.plans_manager.create_plan('p1', 'd1')

        # Resource registry is missing, adding role should fail
        self.assertRaises(UnknownName,
                          self.plans_manager.add_role_to_plan,
                          test_plan.uuid, test_role.uuid)

    def test_remove_role_from_plan(self):
        # Setup
        test_role = self._add_test_role()
        test_plan = self.plans_manager.create_plan('p1', 'd1')
        self.plans_manager.add_role_to_plan(test_plan.uuid, test_role.uuid)

        # Test
        self.plans_manager.remove_role_from_plan(test_plan.uuid,
                                                 test_role.uuid)

        # Verify
        db_plan = self.plan_store.retrieve(test_plan.uuid)
        parsed_plan = parser.parse_template(db_plan.master_template.contents)
        self.assertEqual(0, len(parsed_plan.resources))

    def test_retrieve_plan(self):
        # Setup
        test_role = self._add_test_role()
        test_plan = self.plans_manager.create_plan('p1', 'd1')
        self.plans_manager.add_role_to_plan(test_plan.uuid, test_role.uuid)

        # Test
        found = self.plans_manager.retrieve_plan(test_plan.uuid)

        # Verify
        self.assertTrue(found is not None)
        self.assertTrue(isinstance(found, DeploymentPlan))
        self.assertEqual(test_plan.uuid, found.uuid)
        self.assertEqual('p1', found.name)
        self.assertEqual('d1', found.description)
        self.assertEqual(1, len(found.roles))
        self.assertTrue(isinstance(found.roles[0], Role))
        self.assertEqual(4, len(found.parameters))  # 3 + 1 for scaling
        self.assertTrue(isinstance(found.parameters[0], PlanParameter))

    def test_list_plans(self):
        # Setup
        self.plans_manager.create_plan('p1', 'd1')
        self.plans_manager.create_plan('p2', 'd2')

        # Test
        all_plans = self.plans_manager.list_plans()

        # Verify
        self.assertEqual(2, len(all_plans))
        all_plans.sort(key=lambda x: x.name)
        self.assertEqual('p1', all_plans[0].name)
        self.assertEqual('p2', all_plans[1].name)

    def test_set_parameter_values(self):
        # Setup
        test_role = self._add_test_role()
        test_plan = self.plans_manager.create_plan('p1', 'd1')
        self.plans_manager.add_role_to_plan(test_plan.uuid, test_role.uuid)

        # Test
        ns = name_utils.generate_role_namespace(test_role.name,
                                                test_role.version)
        update_us = [
            ParameterValue(ns_utils.apply_template_namespace(ns, 'key_name'),
                           'test-key'),
            ParameterValue(ns_utils.apply_template_namespace(ns, 'image_id'),
                           'test-image'),
        ]
        updated_plan = self.plans_manager.set_parameter_values(test_plan.uuid,
                                                               update_us)

        # Verify
        self.assertTrue(updated_plan is not None)
        self.assertTrue(isinstance(updated_plan, DeploymentPlan))

        # Pull it from the database again to make sure it was saved
        found = self.plans_manager.retrieve_plan(test_plan.uuid)
        found_params = sorted(found.parameters, key=lambda x: x.name)
        self.assertEqual(4, len(found_params))  # 3 + 1 for scaling
        self.assertEqual(found_params[0].value, '1')
        self.assertEqual(found_params[1].value, 'test-image')
        self.assertEqual(found_params[2].value, 'm1.small')
        self.assertEqual(found_params[3].value, 'test-key')

    def test_set_non_existent_parameters(self):
        # Setup
        test_role = self._add_test_role()
        test_plan = self.plans_manager.create_plan('p1', 'd1')
        self.plans_manager.add_role_to_plan(test_plan.uuid, test_role.uuid)

        # Test
        ns = name_utils.generate_role_namespace(test_role.name,
                                                test_role.version)
        not_present_in_role_1_name = ns_utils.apply_template_namespace(
            ns, 'not_present_in_role_1')
        not_present_in_role_2_name = ns_utils.apply_template_namespace(
            ns, 'not_present_in_role_2')
        update_us = [
            ParameterValue(ns_utils.apply_template_namespace(ns, 'key_name'),
                           'test-key'),
            ParameterValue(ns_utils.apply_template_namespace(ns, 'image_id'),
                           'test-image'),
            ParameterValue(not_present_in_role_1_name,
                           'not-present-in-role-1-value'),
            ParameterValue(not_present_in_role_2_name,
                           'not-present-in-role-2-value'),
        ]

        # Verify
        exc = self.assertRaises(exception.PlanParametersNotExist,
                                self.plans_manager.set_parameter_values,
                                test_plan.uuid,
                                update_us)
        self.assertIn(not_present_in_role_1_name, str(exc))
        self.assertIn(not_present_in_role_2_name, str(exc))

        # Pull it from the database to make sure it was modified
        found = self.plans_manager.retrieve_plan(test_plan.uuid)
        found_params = sorted(found.parameters, key=lambda x: x.name)
        self.assertEqual(4, len(found_params))  # 3 + 1 for scaling
        self.assertEqual(found_params[0].value, '1')
        self.assertEqual(found_params[1].value,
                         '3e6270da-fbf7-4aef-bc78-6d0cfc3ad11b')
        self.assertEqual(found_params[2].value, 'm1.small')
        self.assertEqual(found_params[3].value, '')

    def test_package_templates(self):
        # Setup
        test_role = self._add_test_role()
        test_plan = self.plans_manager.create_plan('p1', 'd1')
        self.plans_manager.add_role_to_plan(test_plan.uuid, test_role.uuid)

        # Test
        templates = self.plans_manager.package_templates(test_plan.uuid)

        # Verify
        self.assertTrue(isinstance(templates, dict))
        self.assertEqual(3, len(templates))

        self.assertTrue('plan.yaml' in templates)
        parsed_plan = parser.parse_template(templates['plan.yaml'])
        self.assertEqual(parsed_plan.description, 'd1')

        self.assertTrue('environment.yaml' in templates)
        parsed_env = parser.parse_environment(templates['environment.yaml'])
        self.assertEqual(1, len(parsed_env.registry_entries))

        role_filename = name_utils.role_template_filename('r1', '1', None)
        self.assertTrue(role_filename in templates)
        parsed_role = parser.parse_template(templates[role_filename])
        self.assertEqual(parsed_role.description, 'Test provider resource foo')

    def test_package_templates_seeded_plan(self):
        # Setup
        self.seed_store.create(MASTER_SEED_NAME, TEST_SEED)
        self.registry_store.create(RESOURCE_REGISTRY_NAME, RESOURCE_REGISTRY)
        # more setup (this is normally called in load_roles)
        self.registry_mapping_store.create('required_file.yaml',
                                           'some fake template data')

        test_role = self._add_test_role()
        test_plan = self.plans_manager.create_plan('p1', 'd1')
        self.plans_manager.add_role_to_plan(test_plan.uuid, test_role.uuid)

        # Test
        templates = self.plans_manager.package_templates(test_plan.uuid)

        # Verify
        self.assertTrue(isinstance(templates, dict))
        self.assertEqual(4, len(templates))

        self.assertTrue('plan.yaml' in templates)
        parsed_plan = parser.parse_template(templates['plan.yaml'])
        self.assertEqual(parsed_plan.description, 'd1')

        self.assertTrue('environment.yaml' in templates)
        self.assertTrue('required_file.yaml' in templates)
        parsed_env = parser.parse_environment(templates['environment.yaml'])
        self.assertEqual(2, len(parsed_env.registry_entries))

        role_filename = name_utils.role_template_filename('r1', '1', None)
        self.assertTrue(role_filename in templates)
        parsed_role = parser.parse_template(templates[role_filename])
        self.assertEqual(parsed_role.description, 'Test provider resource foo')

    def test_find_roles(self):
        # Setup
        self.seed_store.create(MASTER_SEED_NAME, TEST_SEED)
        self.registry_store.create(RESOURCE_REGISTRY_NAME, RESOURCE_REGISTRY)
        # more setup (this is normally called in load_roles)
        self.registry_mapping_store.create('required_file.yaml',
                                           'some fake template data')
        test_role = self._add_test_role()
        test_plan = self.plans_manager.create_plan('p1', 'd1')

        # Test
        self.plans_manager.add_role_to_plan(test_plan.uuid, test_role.uuid)

        # Verify only one role is found
        db_plan = self.plan_store.retrieve(test_plan.uuid)
        parsed_env = parser.parse_environment(
            db_plan.environment_file.contents
        )
        roles = self.plans_manager._find_roles(parsed_env)
        self.assertEqual(1, len(roles))

    def _add_test_role(self):
        return self.template_store.create('r1', TEST_TEMPLATE,
                                          registry_path='r1.yaml')