Support create profile with subnet

This patch allow to define subnet in profile,
Default network port will find a random subnet to create port on, user can define specific subnet.

Change-Id: I8a29dcb7c8b92c8bd1b8c9111134c3ace6ea9a76
This commit is contained in:
Bui Doan Dang 2023-04-19 13:41:36 +07:00
parent 79d0d1f5f9
commit 6eee2f4153
4 changed files with 55 additions and 14 deletions

View File

@ -32,9 +32,13 @@ LOG = logging.getLogger(__name__)
class ServerProfile(base.Profile):
"""Profile for an OpenStack Nova server."""
VERSION = '1.1'
VERSIONS = {
'1.0': [
{'status': consts.SUPPORTED, 'since': '2016.04'}
],
'1.1': [
{'status': consts.SUPPORTED, 'since': '2023.04'}
]
}
@ -65,10 +69,10 @@ class ServerProfile(base.Profile):
NETWORK_KEYS = (
PORT, VNIC_TYPE, FIXED_IP, NETWORK, PORT_SECURITY_GROUPS,
FLOATING_NETWORK, FLOATING_IP,
FLOATING_NETWORK, FLOATING_IP, SUBNET
) = (
'port', 'vnic_type', 'fixed_ip', 'network', 'security_groups',
'floating_network', 'floating_ip',
'floating_network', 'floating_ip', 'subnet'
)
PERSONALITY_KEYS = (
@ -203,6 +207,10 @@ class ServerProfile(base.Profile):
_('The floating IP address to be associated with '
'this port.'),
),
SUBNET: schema.String(
_('Subnet in which to allocate the IP address for '
'this port.'),
),
},
),
updatable=True,
@ -531,6 +539,25 @@ class ServerProfile(base.Profile):
except exc.InternalError as ex:
return str(ex)
def _check_subnet(self, nc, subnet, result):
"""Check the specified subnet.
:param nc: network driver connection.
:param subnet: the name or ID of subnet to check.
:param result: the result that is used as return value.
:returns: None if succeeded or an error message if things go wrong.
"""
if subnet is None:
return
try:
net_obj = nc.subnet_get(subnet)
if net_obj is None:
return _("The specified subnet %s could not be found."
) % subnet
result[self.SUBNET] = net_obj.id
except exc.InternalError as ex:
return str(ex)
def _check_port(self, nc, port, result):
"""Check the specified port.
@ -614,6 +641,11 @@ class ServerProfile(base.Profile):
error = self._check_network(nc, net, result)
_verify(error)
# check subnet
subnet_net = net_spec.get(self.SUBNET)
error = self._check_subnet(nc, subnet_net, result)
_verify(error)
# check port
port = net_spec.get(self.PORT)
error = self._check_port(nc, port, result)
@ -667,9 +699,15 @@ class ServerProfile(base.Profile):
port_attr = {
'network_id': net_spec.get(self.NETWORK),
}
fixed_ips = {}
fixed_ip = net_spec.get(self.FIXED_IP, None)
if fixed_ip:
port_attr['fixed_ips'] = [fixed_ip]
fixed_ips['fixed_ip'] = fixed_ip
subnet = net_spec.get(self.SUBNET, None)
if subnet:
fixed_ips['subnet_id'] = subnet
if fixed_ips:
port_attr['fixed_ips'] = [fixed_ips]
security_groups = net_spec.get(self.PORT_SECURITY_GROUPS, [])
if security_groups:
port_attr['security_groups'] = security_groups
@ -1414,7 +1452,8 @@ class ServerProfile(base.Profile):
self._nw_compare(n, nw, 'port') and
self._nw_compare(n, nw, 'fixed_ip') and
self._nw_compare(n, nw, 'floating_network') and
self._nw_compare(n, nw, 'floating_ip'))]
self._nw_compare(n, nw, 'floating_ip') and
self._nw_compare(n, nw, 'subnet'))]
for n in sg_create_nw:
# don't create networks with only security group changes
LOG.debug("Network %s only has security group changes, "

View File

@ -437,7 +437,8 @@ class TestNovaServerBasic(base.SenlinTestCase):
'fixed_ip': None,
'floating_ip': None,
'port': None,
'security_groups': None
'security_groups': None,
'subnet': None
}
mock_net.assert_called_once_with(
node_obj, expect_params, 'create')

View File

@ -1317,37 +1317,37 @@ class TestNovaServerUpdate(base.SenlinTestCase):
networks_create = [
{'floating_network': None, 'network': 'net1', 'fixed_ip': 'ip2',
'floating_ip': None, 'port': None, 'vnic_type': None,
'security_groups': None},
'security_groups': None, 'subnet': None},
{'floating_network': None, 'network': 'net2', 'fixed_ip': None,
'floating_ip': None, 'port': None, 'vnic_type': None,
'security_groups': None},
'security_groups': None, 'subnet': None},
{'floating_network': None, 'network': None, 'fixed_ip': None,
'floating_ip': None, 'port': 'port4', 'vnic_type': None,
'security_groups': None}
'security_groups': None, 'subnet': None}
]
mock_create.assert_called_once_with(obj, networks_create)
networks_delete = [
{'floating_network': None, 'network': 'net1', 'fixed_ip': 'ip1',
'floating_ip': None, 'port': None, 'vnic_type': None,
'security_groups': None},
'security_groups': None, 'subnet': None},
{'floating_network': None, 'network': 'net1', 'fixed_ip': None,
'floating_ip': None, 'port': None, 'vnic_type': None,
'security_groups': None},
'security_groups': None, 'subnet': None},
{'floating_network': None, 'network': None, 'fixed_ip': None,
'floating_ip': None, 'port': 'port3', 'vnic_type': None,
'security_groups': None}
'security_groups': None, 'subnet': None}
]
mock_delete.assert_called_once_with(obj, networks_delete)
networks_update = [
{'network': 'net3', 'port': None, 'fixed_ip': 'ip1',
'security_groups': ['default'], 'floating_network': None,
'vnic_type': None, 'floating_ip': None},
'vnic_type': None, 'floating_ip': None, 'subnet': None},
{'network': 'net4', 'port': None, 'fixed_ip': 'ip1',
'security_groups': ['default'], 'floating_network': None,
'vnic_type': None, 'floating_ip': None},
'vnic_type': None, 'floating_ip': None, 'subnet': None},
{'network': None, 'port': 'port5', 'fixed_ip': None,
'security_groups': ['default', 'blah'], 'floating_network': None,
'vnic_type': None, 'floating_ip': None}
'vnic_type': None, 'floating_ip': None, 'subnet': None}
]
mock_update.assert_called_once_with(obj, networks_update)

View File

@ -41,6 +41,7 @@ spec = {
'vnic_type': 'direct',
'fixed_ip': 'FAKE_IP',
'network': 'FAKE_NET',
'subnet': 'FAKE_SUBNET',
}],
'scheduler_hints': {
'same_host': 'HOST_ID',