Update security groups for server interfaces

Update the security groups for server interfaces
if only 'network' is specified when update networks
of nova server, to make sure the security groups
info correctly.

Change-Id: I0635d50b52c430885cb3d7733fb565a5c113fad2
Closes-Bug: #1703279
This commit is contained in:
huangtianhua 2017-07-10 14:39:04 +08:00
parent ec832dae4b
commit 99b6187f3a
3 changed files with 92 additions and 6 deletions

View File

@ -686,10 +686,15 @@ echo -e '%s\tALL=(ALL)\tNOPASSWD: ALL' >> /etc/sudoers
server.interface_detach(port_id)
return True
def interface_attach(self, server_id, port_id=None, net_id=None, fip=None):
def interface_attach(self, server_id, port_id=None, net_id=None, fip=None,
security_groups=None):
server = self.fetch_server(server_id)
if server:
server.interface_attach(port_id, net_id, fip)
attachment = server.interface_attach(port_id, net_id, fip)
if not port_id and security_groups:
props = {'security_groups': security_groups}
self.clients.client('neutron').update_port(
attachment.port_id, {'port': props})
return True
else:
return False

View File

@ -349,7 +349,8 @@ class ServerNetworkMixin(object):
return topology['id']
def _calculate_using_str_network(self, ifaces, str_net):
def _calculate_using_str_network(self, ifaces, str_net,
security_groups=None):
add_nets = []
remove_ports = [iface.port_id for iface in ifaces or []]
if str_net == self.NETWORK_AUTO:
@ -359,8 +360,12 @@ class ServerNetworkMixin(object):
if len(nets) > 1:
msg = 'Multiple possible networks found.'
raise exception.UnableToAutoAllocateNetwork(message=msg)
add_nets.append({'port_id': None, 'net_id': nets[0], 'fip': None})
handle_args = {'port_id': None, 'net_id': nets[0], 'fip': None}
if security_groups:
sg_ids = self.client_plugin(
'neutron').get_secgroup_uuids(security_groups)
handle_args['security_groups'] = sg_ids
add_nets.append(handle_args)
return remove_ports, add_nets
def _calculate_using_list_networks(self, old_nets, new_nets, ifaces,
@ -435,6 +440,10 @@ class ServerNetworkMixin(object):
# according to similar behavior during instance creation
if not new_nets:
handler_kwargs = {'port_id': None, 'net_id': None, 'fip': None}
if security_groups:
sec_uuids = self.client_plugin(
'neutron').get_secgroup_uuids(security_groups)
handler_kwargs['security_groups'] = sec_uuids
add_nets.append(handler_kwargs)
else:
# attach section similar for both variants that
@ -452,6 +461,10 @@ class ServerNetworkMixin(object):
if not handler_kwargs['port_id']:
handler_kwargs['net_id'] = self._get_network_id(net)
if security_groups:
sec_uuids = self.client_plugin(
'neutron').get_secgroup_uuids(security_groups)
handler_kwargs['security_groups'] = sec_uuids
if handler_kwargs['net_id']:
handler_kwargs['fip'] = net.get('fixed_ip')
@ -490,7 +503,8 @@ class ServerNetworkMixin(object):
security_groups=None):
new_str_net = self._str_network(new_nets)
if new_str_net:
return self._calculate_using_str_network(ifaces, new_str_net)
return self._calculate_using_str_network(ifaces, new_str_net,
security_groups)
else:
return self._calculate_using_list_networks(
old_nets, new_nets, ifaces, security_groups)

View File

@ -3582,6 +3582,73 @@ class ServersTest(common.HeatTestCase):
}
mock_create_port.assert_called_with({'port': kwargs})
def test_server_update_subnet_to_network_with_security_group(self):
return_server = self.fc.servers.list()[3]
return_server.id = '9102'
server = self._create_test_server(return_server, 'update_subnet')
# set old properties for 'networks' and 'security_groups'
before_props = self.server_props.copy()
before_props['networks'] = [
{'subnet': 'aaa09d50-8c23-4498-a542-aa0deb24f73e'}
]
before_props['security_groups'] = ['the_sg']
# set new property 'networks'
new_networks = [{'network': '2a60cbaa-3d33-4af6-a9ce-83594ac546fc'}]
update_props = self.server_props.copy()
update_props['networks'] = new_networks
update_props['security_groups'] = ['the_sg']
update_template = server.t.freeze(properties=update_props)
server.t = server.t.freeze(properties=before_props)
sec_uuids = ['86c0f8ae-23a8-464f-8603-c54113ef5467']
self.patchobject(self.fc.servers, 'get', return_value=return_server)
self.patchobject(neutron.NeutronClientPlugin,
'get_secgroup_uuids', return_value=sec_uuids)
self.patchobject(neutron.NeutronClientPlugin,
'network_id_from_subnet_id',
return_value='05d8e681-4b37-4570-bc8d-810089f706b2')
iface = self.create_fake_iface('aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa',
'05d8e681-4b37-4570-bc8d-810089f706b2',
'1.2.3.4')
self.patchobject(return_server, 'interface_list', return_value=[iface])
mock_detach = self.patchobject(return_server, 'interface_detach')
mock_attach = self.patchobject(return_server, 'interface_attach')
def interface_attach_mock(port, net):
class attachment(object):
def __init__(self, port_id, net_id):
self.port_id = port_id
self.net_id = net_id
return attachment(port, net)
mock_attach.return_value = interface_attach_mock(
'ad4a231b-67f7-45fe-aee9-461176b48203',
'2a60cbaa-3d33-4af6-a9ce-83594ac546fc')
mock_detach_check = self.patchobject(nova.NovaClientPlugin,
'check_interface_detach',
return_value=True)
mock_attach_check = self.patchobject(nova.NovaClientPlugin,
'check_interface_attach',
return_value=True)
mock_update_port = self.patchobject(
neutronclient.Client, 'update_port')
scheduler.TaskRunner(server.update, update_template, before=server.t)()
self.assertEqual((server.UPDATE, server.COMPLETE), server.state)
self.assertEqual(1, mock_detach.call_count)
self.assertEqual(1, mock_attach.call_count)
self.assertEqual(1, mock_detach_check.call_count)
self.assertEqual(1, mock_attach_check.call_count)
kwargs = {'security_groups': sec_uuids}
mock_update_port.assert_called_with(
'ad4a231b-67f7-45fe-aee9-461176b48203',
{'port': kwargs})
def test_server_update_empty_networks_with_complex_parameters(self):
return_server = self.fc.servers.list()[3]
return_server.id = '9102'