From a936283a6357ef91334636cf0796bd04aa4f75da Mon Sep 17 00:00:00 2001 From: huangtianhua Date: Tue, 28 Mar 2017 11:47:48 +0800 Subject: [PATCH] Support adding tags for network Allow to set/update tags for neutron network. Change-Id: I2f214912026ee43926021a20003a108478c0b29f Blueprint: support-add-tags-for-neutron-resources --- .../engine/resources/openstack/neutron/net.py | 17 +++++++++++++-- .../resources/openstack/neutron/neutron.py | 21 +++++++++++++++++++ .../openstack/neutron/test_neutron_net.py | 20 ++++++++++++++++++ ...for-network-resource-d6f3843c546744a2.yaml | 3 +++ 4 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 releasenotes/notes/set-tags-for-network-resource-d6f3843c546744a2.yaml diff --git a/heat/engine/resources/openstack/neutron/net.py b/heat/engine/resources/openstack/neutron/net.py index 42613a48f..cbeb4f37a 100644 --- a/heat/engine/resources/openstack/neutron/net.py +++ b/heat/engine/resources/openstack/neutron/net.py @@ -32,11 +32,11 @@ class Net(neutron.NeutronResource): PROPERTIES = ( NAME, VALUE_SPECS, ADMIN_STATE_UP, TENANT_ID, SHARED, DHCP_AGENT_IDS, PORT_SECURITY_ENABLED, QOS_POLICY, - DNS_DOMAIN, + DNS_DOMAIN, TAGS, ) = ( 'name', 'value_specs', 'admin_state_up', 'tenant_id', 'shared', 'dhcp_agent_ids', 'port_security_enabled', 'qos_policy', - 'dns_domain', + 'dns_domain', 'tags', ) ATTRIBUTES = ( @@ -115,6 +115,13 @@ class Net(neutron.NeutronResource): update_allowed=True, support_status=support.SupportStatus(version='7.0.0') ), + TAGS: properties.Schema( + properties.Schema.LIST, + _('The tags to be added to the network.'), + schema=properties.Schema(properties.Schema.STRING), + update_allowed=True, + support_status=support.SupportStatus(version='9.0.0') + ), } attributes_schema = { @@ -168,6 +175,7 @@ class Net(neutron.NeutronResource): dhcp_agent_ids = props.pop(self.DHCP_AGENT_IDS, None) qos_policy = props.pop(self.QOS_POLICY, None) + tags = props.pop(self.TAGS, []) if qos_policy: props['qos_policy_id'] = self.client_plugin().get_qos_policy_id( qos_policy) @@ -178,6 +186,9 @@ class Net(neutron.NeutronResource): if dhcp_agent_ids: self._replace_dhcp_agents(dhcp_agent_ids) + if tags: + self.set_tags(tags) + def check_create_complete(self, *args): attributes = self._show_resource() return self.is_built(attributes) @@ -201,6 +212,8 @@ class Net(neutron.NeutronResource): prop_diff[ 'qos_policy_id'] = self.client_plugin().get_qos_policy_id( qos_policy) if qos_policy else None + if self.TAGS in prop_diff: + self.set_tags(prop_diff.pop(self.TAGS)) if prop_diff: self.client().update_network(self.resource_id, {'network': prop_diff}) diff --git a/heat/engine/resources/openstack/neutron/neutron.py b/heat/engine/resources/openstack/neutron/neutron.py index eb86f2ecd..5eac17fd0 100644 --- a/heat/engine/resources/openstack/neutron/neutron.py +++ b/heat/engine/resources/openstack/neutron/neutron.py @@ -26,6 +26,18 @@ class NeutronResource(resource.Resource): res_info_key = None + def get_resource_plural(self): + """Return the plural of resource type. + + The default implementation is to return self.entity + 's', + the rule is not appropriate for some special resources, + e.g. qos_policy, this method should be overridden by the + special resources if needed. + """ + if not self.entity: + return + return self.entity + 's' + def validate(self): """Validate any of the provided params.""" res = super(NeutronResource, self).validate() @@ -154,3 +166,12 @@ class NeutronResource(resource.Resource): raise exception.PhysicalResourceExists( name=self.physical_resource_name_or_FnGetRefId()) return True + + def set_tags(self, tags): + resource_plural = self.get_resource_plural() + if resource_plural: + tags = tags or [] + body = {'tags': tags} + self.client().replace_tag(resource_plural, + self.resource_id, + body) diff --git a/heat/tests/openstack/neutron/test_neutron_net.py b/heat/tests/openstack/neutron/test_neutron_net.py index 21a405544..062da92be 100644 --- a/heat/tests/openstack/neutron/test_neutron_net.py +++ b/heat/tests/openstack/neutron/test_neutron_net.py @@ -40,6 +40,9 @@ resources: - 28c25a04-3f73-45a7-a2b4-59e183943ddc port_security_enabled: False dns_domain: openstack.org. + tags: + - tag1 + - tag2 subnet: type: OS::Neutron::Subnet @@ -94,6 +97,7 @@ class NeutronNetTest(common.HeatTestCase): def test_net(self): t = template_format.parse(neutron_template) stack = utils.parse_stack(t) + resource_type = 'networks' net_info_build = {"network": { "status": "BUILD", "subnets": [], @@ -142,6 +146,9 @@ class NeutronNetTest(common.HeatTestCase): remove_dhcp_agent_mock = self.patchobject( neutronclient.Client, 'remove_network_from_dhcp_agent') + replace_tag_mock = self.patchobject( + neutronclient.Client, + 'replace_tag') show_network_mock = self.patchobject( neutronclient.Client, 'show_network') @@ -183,6 +190,12 @@ class NeutronNetTest(common.HeatTestCase): add_dhcp_agent_mock.assert_called_with( '28c25a04-3f73-45a7-a2b4-59e183943ddc', {'network_id': u'fc68ea2c-b60b-4b4f-bd82-94ec81110766'}) + replace_tag_mock.assert_called_with( + resource_type, + 'fc68ea2c-b60b-4b4f-bd82-94ec81110766', + {'tags': ['tag1', 'tag2']} + ) + # assert the implicit dependency between the gateway and the interface deps = stack.dependencies[stack['router_interface']] self.assertIn(stack['gateway'], deps) @@ -255,6 +268,13 @@ class NeutronNetTest(common.HeatTestCase): 'name': utils.PhysName(stack.name, 'test_net'), }} ) + # Update with tags=[] + rsrc.handle_update(update_snippet, {}, {'tags': []}) + replace_tag_mock.assert_called_with( + resource_type, + 'fc68ea2c-b60b-4b4f-bd82-94ec81110766', + {'tags': []} + ) # Update with empty prop_diff rsrc.handle_update(update_snippet, {}, {}) diff --git a/releasenotes/notes/set-tags-for-network-resource-d6f3843c546744a2.yaml b/releasenotes/notes/set-tags-for-network-resource-d6f3843c546744a2.yaml new file mode 100644 index 000000000..d29989095 --- /dev/null +++ b/releasenotes/notes/set-tags-for-network-resource-d6f3843c546744a2.yaml @@ -0,0 +1,3 @@ +--- +features: + - Allow to set or update the tags for OS::Neutron::Net resource.