OS::Nova::Server: Extend addresses attr to include subnets
This change adds 'subnets' to the addresses attribute of the OS::Nova::Server resource. This enables resolving the subnet properties for the server resource which brings parity with OS::Neutron::Port's 'subnets' attribute. Story: 1766946 Task: 19689 Change-Id: I6927f1e142e83df7258e259bffc86819e4cbe881
This commit is contained in:
parent
970bc3bdf4
commit
46ac3932f9
|
@ -629,13 +629,23 @@ class Server(server_base.BaseServer, sh.SchedulerHintsMixin,
|
||||||
type=attributes.Schema.STRING
|
type=attributes.Schema.STRING
|
||||||
),
|
),
|
||||||
ADDRESSES: attributes.Schema(
|
ADDRESSES: attributes.Schema(
|
||||||
_('A dict of all network addresses with corresponding port_id. '
|
_('A dict of all network addresses with corresponding port_id and '
|
||||||
'Each network will have two keys in dict, they are network '
|
'subnets. Each network will have two keys in dict, they are '
|
||||||
'name and network id. '
|
'network name and network id. The port ID may be obtained '
|
||||||
'The port ID may be obtained through the following expression: '
|
'through the following expression: ``{get_attr: [<server>, '
|
||||||
'"{get_attr: [<server>, addresses, <network name_or_id>, 0, '
|
'addresses, <network name_or_id>, 0, port]}``. The subnets may '
|
||||||
'port]}".'),
|
'be obtained trough the following expression: ``{get_attr: '
|
||||||
type=attributes.Schema.MAP
|
'[<server>, addresses, <network name_or_id>, 0, subnets]}``.'),
|
||||||
|
type=attributes.Schema.MAP,
|
||||||
|
support_status=support.SupportStatus(
|
||||||
|
version='11.0.0',
|
||||||
|
status=support.SUPPORTED,
|
||||||
|
message=_('The attribute was extended to include subnets with '
|
||||||
|
'version 11.0.0.'),
|
||||||
|
previous_status=support.SupportStatus(
|
||||||
|
status=support.SUPPORTED
|
||||||
|
)
|
||||||
|
)
|
||||||
),
|
),
|
||||||
NETWORKS_ATTR: attributes.Schema(
|
NETWORKS_ATTR: attributes.Schema(
|
||||||
_('A dict of assigned network addresses of the form: '
|
_('A dict of assigned network addresses of the form: '
|
||||||
|
@ -929,8 +939,8 @@ class Server(server_base.BaseServer, sh.SchedulerHintsMixin,
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def _get_live_networks(self, server, props):
|
def _get_live_networks(self, server, props):
|
||||||
reality_nets = self._add_port_for_address(server,
|
reality_nets = self._add_attrs_for_address(server,
|
||||||
extend_networks=False)
|
extend_networks=False)
|
||||||
reality_net_ids = {}
|
reality_net_ids = {}
|
||||||
client_plugin = self.client_plugin('neutron')
|
client_plugin = self.client_plugin('neutron')
|
||||||
for net_key in reality_nets:
|
for net_key in reality_nets:
|
||||||
|
@ -1078,10 +1088,28 @@ class Server(server_base.BaseServer, sh.SchedulerHintsMixin,
|
||||||
|
|
||||||
return bdm_v2_list
|
return bdm_v2_list
|
||||||
|
|
||||||
def _add_port_for_address(self, server, extend_networks=True):
|
def _get_port_subnets_attr(self, port_id):
|
||||||
"""Method adds port id to list of addresses.
|
subnets = []
|
||||||
|
try:
|
||||||
|
fixed_ips = self.client('neutron').show_port(
|
||||||
|
port_id)['port']['fixed_ips']
|
||||||
|
for fixed_ip in fixed_ips:
|
||||||
|
if fixed_ip.get('subnet_id'):
|
||||||
|
subnets.append(self.client('neutron').show_subnet(
|
||||||
|
fixed_ip['subnet_id'])['subnet'])
|
||||||
|
except Exception as ex:
|
||||||
|
LOG.warning("Failed to fetch resource attributes: %s", ex)
|
||||||
|
return
|
||||||
|
return subnets
|
||||||
|
|
||||||
|
def _add_attrs_for_address(self, server, extend_networks=True):
|
||||||
|
"""Method adds port id and subnets attributes to list of addresses.
|
||||||
|
|
||||||
This method is used only for resolving attributes.
|
This method is used only for resolving attributes.
|
||||||
|
:param server: The server resource
|
||||||
|
:param extend_networks: When False the network is not extended, i.e
|
||||||
|
the net is returned without replacing name on
|
||||||
|
id.
|
||||||
"""
|
"""
|
||||||
nets = copy.deepcopy(server.addresses) or {}
|
nets = copy.deepcopy(server.addresses) or {}
|
||||||
ifaces = server.interface_list()
|
ifaces = server.interface_list()
|
||||||
|
@ -1092,6 +1120,13 @@ class Server(server_base.BaseServer, sh.SchedulerHintsMixin,
|
||||||
for addr in nets[net_name]:
|
for addr in nets[net_name]:
|
||||||
addr['port'] = ip_mac_mapping_on_port_id.get(
|
addr['port'] = ip_mac_mapping_on_port_id.get(
|
||||||
(addr['addr'], addr['OS-EXT-IPS-MAC:mac_addr']))
|
(addr['addr'], addr['OS-EXT-IPS-MAC:mac_addr']))
|
||||||
|
# _get_live_networks() uses this method to get reality_nets.
|
||||||
|
# We don't need to get subnets and network in that case. Only
|
||||||
|
# do the external calls if extend_networks is true, i.e called
|
||||||
|
# from _resolve_attribute()
|
||||||
|
if extend_networks:
|
||||||
|
addr['subnets'] = self._get_port_subnets_attr(addr['port'])
|
||||||
|
|
||||||
if extend_networks:
|
if extend_networks:
|
||||||
return self._extend_networks(nets)
|
return self._extend_networks(nets)
|
||||||
else:
|
else:
|
||||||
|
@ -1134,7 +1169,7 @@ class Server(server_base.BaseServer, sh.SchedulerHintsMixin,
|
||||||
self.client_plugin().ignore_not_found(e)
|
self.client_plugin().ignore_not_found(e)
|
||||||
return ''
|
return ''
|
||||||
if name == self.ADDRESSES:
|
if name == self.ADDRESSES:
|
||||||
return self._add_port_for_address(server)
|
return self._add_attrs_for_address(server)
|
||||||
if name == self.NETWORKS_ATTR:
|
if name == self.NETWORKS_ATTR:
|
||||||
return self._extend_networks(server.networks)
|
return self._extend_networks(server.networks)
|
||||||
if name == self.INSTANCE_NAME:
|
if name == self.INSTANCE_NAME:
|
||||||
|
|
|
@ -250,6 +250,11 @@ class ServersTest(common.HeatTestCase):
|
||||||
self.patchobject(glance.GlanceClientPlugin, 'find_image_by_name_or_id',
|
self.patchobject(glance.GlanceClientPlugin, 'find_image_by_name_or_id',
|
||||||
side_effect=image_side_effect)
|
side_effect=image_side_effect)
|
||||||
|
|
||||||
|
self.port_show = self.patchobject(neutronclient.Client,
|
||||||
|
'show_port')
|
||||||
|
self.subnet_show = self.patchobject(neutronclient.Client,
|
||||||
|
'show_subnet')
|
||||||
|
|
||||||
def _limits_absolute(self):
|
def _limits_absolute(self):
|
||||||
max_personality = mock.Mock()
|
max_personality = mock.Mock()
|
||||||
max_personality.name = 'maxPersonality'
|
max_personality.name = 'maxPersonality'
|
||||||
|
@ -431,6 +436,26 @@ class ServersTest(common.HeatTestCase):
|
||||||
self.patchobject(return_server, 'interface_list',
|
self.patchobject(return_server, 'interface_list',
|
||||||
return_value=interfaces)
|
return_value=interfaces)
|
||||||
self.patchobject(self.fc.servers, 'tag_list', return_value=['test'])
|
self.patchobject(self.fc.servers, 'tag_list', return_value=['test'])
|
||||||
|
|
||||||
|
self.port_show.return_value = {
|
||||||
|
'port': {'id': '1234',
|
||||||
|
'fixed_ips': [{
|
||||||
|
'ip_address': '4.5.6.7',
|
||||||
|
'subnet_id': 'the_subnet'}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
subnet_dict = {
|
||||||
|
'subnet': {
|
||||||
|
'name': 'subnet_name',
|
||||||
|
'cidr': '10.0.0.0/24',
|
||||||
|
'allocation_pools': [{'start': '10.0.0.2',
|
||||||
|
'end': u'10.0.0.254'}],
|
||||||
|
'gateway_ip': '10.0.0.1',
|
||||||
|
'id': 'the_subnet'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.subnet_show.return_value = subnet_dict
|
||||||
|
|
||||||
public_ip = return_server.networks['public'][0]
|
public_ip = return_server.networks['public'][0]
|
||||||
self.assertEqual('1234',
|
self.assertEqual('1234',
|
||||||
server.FnGetAtt('addresses')['public'][0]['port'])
|
server.FnGetAtt('addresses')['public'][0]['port'])
|
||||||
|
@ -446,6 +471,8 @@ class ServersTest(common.HeatTestCase):
|
||||||
server.FnGetAtt('addresses')['private'][0]['port'])
|
server.FnGetAtt('addresses')['private'][0]['port'])
|
||||||
self.assertEqual(private_ip,
|
self.assertEqual(private_ip,
|
||||||
server.FnGetAtt('addresses')['private'][0]['addr'])
|
server.FnGetAtt('addresses')['private'][0]['addr'])
|
||||||
|
self.assertEqual([subnet_dict['subnet']],
|
||||||
|
server.FnGetAtt('addresses')['private'][0]['subnets'])
|
||||||
self.assertEqual(private_ip,
|
self.assertEqual(private_ip,
|
||||||
server.FnGetAtt('networks')['private'][0])
|
server.FnGetAtt('networks')['private'][0])
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
Adds ``subnets`` to the ``addresses`` attribute of
|
||||||
|
``OS::Nova::Server`` resource. This enables resolving the subnet
|
||||||
|
properties for the server resource which brings parity with
|
||||||
|
``OS::Neutron::Port``'s ``subnets`` attribute.
|
||||||
|
|
Loading…
Reference in New Issue