Implement update for neutron subnet resources
This change allows any updatable properties to be updated on an existing subnet without replacement. Documentation is limited on what properties are updatable, so discovery was manual. Change-Id: Ia585d1b7d24900f2789f2127a76dd272aa7fb850
This commit is contained in:
parent
f3ee60e7b5
commit
62124c4530
@ -36,20 +36,28 @@ class Subnet(neutron.NeutronResource):
|
|||||||
'cidr': {'Type': 'String',
|
'cidr': {'Type': 'String',
|
||||||
'Required': True},
|
'Required': True},
|
||||||
'value_specs': {'Type': 'Map',
|
'value_specs': {'Type': 'Map',
|
||||||
'Default': {}},
|
'Default': {},
|
||||||
'name': {'Type': 'String'},
|
'UpdateAllowed': True},
|
||||||
|
'name': {'Type': 'String',
|
||||||
|
'UpdateAllowed': True},
|
||||||
'ip_version': {'Type': 'Integer',
|
'ip_version': {'Type': 'Integer',
|
||||||
'AllowedValues': [4, 6],
|
'AllowedValues': [4, 6],
|
||||||
'Default': 4},
|
'Default': 4},
|
||||||
'dns_nameservers': {'Type': 'List'},
|
'dns_nameservers': {'Type': 'List',
|
||||||
'gateway_ip': {'Type': 'String'},
|
'UpdateAllowed': True,
|
||||||
'enable_dhcp': {'Type': 'Boolean'},
|
'Default': []},
|
||||||
|
'gateway_ip': {'Type': 'String',
|
||||||
|
'UpdateAllowed': True},
|
||||||
|
'enable_dhcp': {'Type': 'Boolean',
|
||||||
|
'UpdateAllowed': True,
|
||||||
|
'Default': True},
|
||||||
'allocation_pools': {'Type': 'List',
|
'allocation_pools': {'Type': 'List',
|
||||||
'Schema': {
|
'Schema': {
|
||||||
'Type': 'Map',
|
'Type': 'Map',
|
||||||
'Schema': allocation_schema
|
'Schema': allocation_schema
|
||||||
}},
|
}},
|
||||||
'tenant_id': {'Type': 'String'}}
|
'tenant_id': {'Type': 'String'}}
|
||||||
|
|
||||||
attributes_schema = {
|
attributes_schema = {
|
||||||
"name": _("Friendly name of the subnet."),
|
"name": _("Friendly name of the subnet."),
|
||||||
"network_id": _("Parent network of the subnet."),
|
"network_id": _("Parent network of the subnet."),
|
||||||
@ -65,6 +73,8 @@ class Subnet(neutron.NeutronResource):
|
|||||||
"show": _("All attributes."),
|
"show": _("All attributes."),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
update_allowed_keys = ('Properties',)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _null_gateway_ip(props):
|
def _null_gateway_ip(props):
|
||||||
if 'gateway_ip' not in props:
|
if 'gateway_ip' not in props:
|
||||||
@ -100,6 +110,11 @@ class Subnet(neutron.NeutronResource):
|
|||||||
def _show_resource(self):
|
def _show_resource(self):
|
||||||
return self.neutron().show_subnet(self.resource_id)['subnet']
|
return self.neutron().show_subnet(self.resource_id)['subnet']
|
||||||
|
|
||||||
|
def handle_update(self, json_snippet, tmpl_diff, prop_diff):
|
||||||
|
props = self.prepare_update_properties(json_snippet)
|
||||||
|
self.neutron().update_subnet(
|
||||||
|
self.resource_id, {'subnet': props})
|
||||||
|
|
||||||
|
|
||||||
def resource_mapping():
|
def resource_mapping():
|
||||||
if clients.neutronclient is None:
|
if clients.neutronclient is None:
|
||||||
|
@ -388,6 +388,7 @@ class NeutronSubnetTest(HeatTestCase):
|
|||||||
self.m.StubOutWithMock(neutronclient.Client, 'create_subnet')
|
self.m.StubOutWithMock(neutronclient.Client, 'create_subnet')
|
||||||
self.m.StubOutWithMock(neutronclient.Client, 'delete_subnet')
|
self.m.StubOutWithMock(neutronclient.Client, 'delete_subnet')
|
||||||
self.m.StubOutWithMock(neutronclient.Client, 'show_subnet')
|
self.m.StubOutWithMock(neutronclient.Client, 'show_subnet')
|
||||||
|
self.m.StubOutWithMock(neutronclient.Client, 'update_subnet')
|
||||||
self.m.StubOutWithMock(clients.OpenStackClients, 'keystone')
|
self.m.StubOutWithMock(clients.OpenStackClients, 'keystone')
|
||||||
utils.setup_dummy_db()
|
utils.setup_dummy_db()
|
||||||
|
|
||||||
@ -411,7 +412,8 @@ class NeutronSubnetTest(HeatTestCase):
|
|||||||
{'start': u'10.0.3.20', 'end': u'10.0.3.150'}],
|
{'start': u'10.0.3.20', 'end': u'10.0.3.150'}],
|
||||||
'ip_version': 4,
|
'ip_version': 4,
|
||||||
'cidr': u'10.0.3.0/24',
|
'cidr': u'10.0.3.0/24',
|
||||||
'tenant_id': 'c1210485b2424d48804aad5d39c61b8f'
|
'tenant_id': 'c1210485b2424d48804aad5d39c61b8f',
|
||||||
|
'enable_dhcp': True
|
||||||
}
|
}
|
||||||
}).AndReturn({
|
}).AndReturn({
|
||||||
"subnet": {
|
"subnet": {
|
||||||
@ -453,6 +455,17 @@ class NeutronSubnetTest(HeatTestCase):
|
|||||||
neutronclient.Client.show_subnet(
|
neutronclient.Client.show_subnet(
|
||||||
'91e47a57-7508-46fe-afc9-fc454e8580e1').AndReturn(sn)
|
'91e47a57-7508-46fe-afc9-fc454e8580e1').AndReturn(sn)
|
||||||
|
|
||||||
|
# Update script
|
||||||
|
neutronclient.Client.update_subnet(
|
||||||
|
'91e47a57-7508-46fe-afc9-fc454e8580e1',
|
||||||
|
{'subnet': {
|
||||||
|
'dns_nameservers': ['8.8.8.8', '192.168.1.254'],
|
||||||
|
'name': 'mysubnet',
|
||||||
|
'enable_dhcp': True
|
||||||
|
}}
|
||||||
|
)
|
||||||
|
|
||||||
|
# Delete script
|
||||||
neutronclient.Client.delete_subnet(
|
neutronclient.Client.delete_subnet(
|
||||||
'91e47a57-7508-46fe-afc9-fc454e8580e1'
|
'91e47a57-7508-46fe-afc9-fc454e8580e1'
|
||||||
).AndReturn(None)
|
).AndReturn(None)
|
||||||
@ -485,8 +498,20 @@ class NeutronSubnetTest(HeatTestCase):
|
|||||||
self.assertIn(stack['port'], stack.dependencies[stack['subnet']])
|
self.assertIn(stack['port'], stack.dependencies[stack['subnet']])
|
||||||
self.assertIn(stack['port2'], stack.dependencies[stack['subnet']])
|
self.assertIn(stack['port2'], stack.dependencies[stack['subnet']])
|
||||||
|
|
||||||
self.assertRaises(resource.UpdateReplace,
|
update_snippet = {
|
||||||
rsrc.handle_update, {}, {}, {})
|
"Type": "OS::Neutron::Subnet",
|
||||||
|
"Properties": {
|
||||||
|
"name": 'mysubnet',
|
||||||
|
"network_id": {"Ref": "network"},
|
||||||
|
"tenant_id": "c1210485b2424d48804aad5d39c61b8f",
|
||||||
|
"ip_version": 4,
|
||||||
|
"cidr": "10.0.3.0/24",
|
||||||
|
"allocation_pools": [
|
||||||
|
{"start": "10.0.3.20", "end": "10.0.3.150"}],
|
||||||
|
"dns_nameservers": ["8.8.8.8", "192.168.1.254"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rsrc.handle_update(update_snippet, {}, {})
|
||||||
|
|
||||||
self.assertEqual(scheduler.TaskRunner(rsrc.delete)(), None)
|
self.assertEqual(scheduler.TaskRunner(rsrc.delete)(), None)
|
||||||
rsrc.state_set(rsrc.CREATE, rsrc.COMPLETE, 'to delete again')
|
rsrc.state_set(rsrc.CREATE, rsrc.COMPLETE, 'to delete again')
|
||||||
|
Loading…
Reference in New Issue
Block a user