From 7d2cd4162897333adcaab4bd83361bbd369fcf17 Mon Sep 17 00:00:00 2001 From: Ahmad Musa <53178237+ahmadiesa-abu@users.noreply.github.com> Date: Mon, 6 Mar 2023 17:02:59 +0200 Subject: [PATCH] CYBL-1527-Add-Flavor-ExtraSpecs-Access (#432) --- CHANGELOG.txt | 1 + examples/local/flavor_with_extra_specs.yaml | 75 +++++++++++++++++++ openstack_plugin/resources/compute/flavor.py | 7 ++ openstack_plugin/tests/compute/test_flavor.py | 61 +++++++++++++++ openstack_sdk/resources/compute.py | 17 +++++ plugin.yaml | 2 +- plugin_1_4.yaml | 2 +- v2_plugin.yaml | 2 +- 8 files changed, 164 insertions(+), 3 deletions(-) create mode 100644 examples/local/flavor_with_extra_specs.yaml diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 38842a96..cbcf52f4 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,3 +1,4 @@ +3.3.5: add extra_specs and tenant access to flavor type. 3.3.4: support dsl 1_4 and redhat 8 wagons. 3.3.3: Bump openstacksdk to 0.53.0 to to fix server_groups attribute error 3.3.2: Re-releasing 3.3.1 for adding to bundle. diff --git a/examples/local/flavor_with_extra_specs.yaml b/examples/local/flavor_with_extra_specs.yaml new file mode 100644 index 00000000..e80eeac2 --- /dev/null +++ b/examples/local/flavor_with_extra_specs.yaml @@ -0,0 +1,75 @@ +tosca_definitions_version: cloudify_dsl_1_3 + +imports: + - http://www.getcloudify.org/spec/cloudify/4.5.5/types.yaml + - plugin:cloudify-openstack-plugin + +inputs: + + auth_url: + type: string + default: {get_secret: openstack_auth_url} + + username: + type: string + default: {get_secret: openstack_username} + + password: + type: string + default: {get_secret: openstack_password} + + region_name: + type: string + default: {get_secret: region} + + project_name: + type: string + default: 'default' + + domain_name: + type: string + default: 'default' + + flavor_config: + default: + name: { concat: [ { get_input: name_prefix }, 'flavor' ] } + ram: 2048 + disk: 8 + vcpus: 2 + is_public: true + + name_prefix: + type: string + default: compute- + + user_domain_id: + type: string + default: default + + flavor_extra_spec: + default: + "hw:cpu_policy": 'dedicated' + "hw:cpu_threads_policy": 'isolate' + + flavor_tenants: + default: ['cfy_test_project'] + +dsl_definitions: + + client_config: &client_config + auth_url: { get_input: auth_url } + username: { get_input: username } + password: { get_input: password } + region_name: { get_input: region_name } + user_domain_name: { get_input: domain_name } + project_domain_name: { get_input: project_name } + +node_templates: + + example-flavor: + type: cloudify.nodes.openstack.Flavor + properties: + client_config: *client_config + resource_config: { get_input: flavor_config } + extra_specs: { get_input: flavor_extra_spec } + tenants: { get_input: flavor_tenants } diff --git a/openstack_plugin/resources/compute/flavor.py b/openstack_plugin/resources/compute/flavor.py index cc55d9cd..40f43e5b 100644 --- a/openstack_plugin/resources/compute/flavor.py +++ b/openstack_plugin/resources/compute/flavor.py @@ -35,6 +35,13 @@ def create(openstack_resource): """ created_resource = openstack_resource.create() ctx.instance.runtime_properties[RESOURCE_ID] = created_resource.id + extra_specs = ctx.node.properties.get('extra_specs', {}) + tenants = ctx.node.properties.get('tenants', []) + if extra_specs: + openstack_resource.set_flavor_specs(created_resource.id, extra_specs) + if tenants: + for tenant in tenants: + openstack_resource.add_flavor_access(created_resource.id, tenant) @with_compat_node diff --git a/openstack_plugin/tests/compute/test_flavor.py b/openstack_plugin/tests/compute/test_flavor.py index 4feccd09..20c833a8 100644 --- a/openstack_plugin/tests/compute/test_flavor.py +++ b/openstack_plugin/tests/compute/test_flavor.py @@ -73,6 +73,67 @@ def test_create(self, mock_connection): self._ctx.instance.runtime_properties[OPENSTACK_TYPE_PROPERTY], FLAVOR_OPENSTACK_TYPE) + mock_connection().compute.create_flavor_extra_specs.assert_not_called() + + mock_connection().compute.flavor_add_tenant_access.assert_not_called() + + def test_create_extra_specs_access(self, mock_connection): + # Prepare the context for create operation + self._prepare_context_for_operation( + test_name='FlavorTestCaseExtraSpecsAcess', + test_properties={ + 'client_config': self.client_config, + 'resource_config': { + 'name': 'test_flavor', + 'ram': 2048, + 'disk': 8, + 'vcpus': 2, + 'is_public': False + }, + 'extra_specs': { + 'hw:cpu_policy': 'dedicated', + 'hw:cpu_threads_policy': 'isolate' + }, + 'tenants': ['cfy_test_project'] + }, + ctx_operation_name='cloudify.interfaces.lifecycle.create') + + flavor_instance = openstack.compute.v2.flavor.Flavor(**{ + 'id': 'a95b5509-c122-4c2f-823e-884bb559afe8', + 'name': 'test_flavor', + 'links': '2', + 'os-flavor-access:is_public': False, + 'ram': 2048, + 'vcpus': 2, + 'disk': 8 + }) + + mock_connection().compute.create_flavor = \ + mock.MagicMock(return_value=flavor_instance) + + mock_connection().compute.create_flavor_extra_specs = \ + mock.Mock() + + mock_connection().identity.find_project = \ + mock.Mock() + + mock_connection().compute.flavor_add_tenant_access = \ + mock.Mock() + + # Call create flavor + flavor.create(openstack_resource=None) + + self.assertEqual(self._ctx.instance.runtime_properties[RESOURCE_ID], + 'a95b5509-c122-4c2f-823e-884bb559afe8') + + self.assertEqual( + self._ctx.instance.runtime_properties[OPENSTACK_NAME_PROPERTY], + 'test_flavor') + + mock_connection().compute.create_flavor_extra_specs.assert_called() + + mock_connection().compute.flavor_add_tenant_access.assert_called() + def test_delete(self, mock_connection): # Prepare the context for delete operation self._prepare_context_for_operation( diff --git a/openstack_sdk/resources/compute.py b/openstack_sdk/resources/compute.py index 6ee36bd3..93410512 100644 --- a/openstack_sdk/resources/compute.py +++ b/openstack_sdk/resources/compute.py @@ -487,3 +487,20 @@ def delete(self): self.logger.debug( 'Deleted flavor with this result: {0}'.format(result)) return result + + def set_flavor_specs(self, flavor_id, extra_specs): + self.logger.debug( + 'Attempting to set flavor {0} specs with these args: {1}'.format( + flavor_id, extra_specs)) + + self.connection.compute.create_flavor_extra_specs(flavor_id, + extra_specs) + + def add_flavor_access(self, flavor_id, tenant): + self.logger.debug( + 'Attempting to set flavor {0} access with these args: {1}'.format( + flavor_id, tenant)) + project = self.connection.identity.find_project(tenant, + ignore_missing=False) + self.connection.compute.flavor_add_tenant_access(flavor_id, + project.id) diff --git a/plugin.yaml b/plugin.yaml index 9b76b28d..9c8f91a1 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -3,7 +3,7 @@ plugins: openstack: executor: central_deployment_agent package_name: cloudify-openstack-plugin - package_version: '3.3.4' + package_version: '3.3.5' dsl_definitions: diff --git a/plugin_1_4.yaml b/plugin_1_4.yaml index c1d03527..a8a65897 100644 --- a/plugin_1_4.yaml +++ b/plugin_1_4.yaml @@ -3,7 +3,7 @@ plugins: openstack: executor: central_deployment_agent package_name: cloudify-openstack-plugin - package_version: '3.3.4' + package_version: '3.3.5' dsl_definitions: diff --git a/v2_plugin.yaml b/v2_plugin.yaml index c1d03527..a8a65897 100644 --- a/v2_plugin.yaml +++ b/v2_plugin.yaml @@ -3,7 +3,7 @@ plugins: openstack: executor: central_deployment_agent package_name: cloudify-openstack-plugin - package_version: '3.3.4' + package_version: '3.3.5' dsl_definitions: