Log when FIP is associated/disassociated

Add a log entry when a floating IP is associated/disassociated from a
port, reporting the external IP, the internal IP, the fixed port ID and
the FIP ID.

The log level is set to INFO; this security information will be
registered regardless of the logging level.

Change-Id: I9124399f680e4123c4dc14e8be666f9c4c5385a0
Closes-Bug: #1842327
This commit is contained in:
Rodolfo Alonso Hernandez 2019-09-02 15:46:10 +00:00
parent f5bcca87d1
commit 791dc24960
2 changed files with 76 additions and 0 deletions

View File

@ -71,6 +71,8 @@ EXTERNAL_GW_INFO = l3_apidef.EXTERNAL_GW_INFO
# Useful to keep the filtering between API and Database.
API_TO_DB_COLUMN_MAP = {'port_id': 'fixed_port_id'}
CORE_ROUTER_ATTRS = ('id', 'name', 'tenant_id', 'admin_state_up', 'status')
FIP_ASSOC_MSG = ('Floating IP %(fip_id)s %(assoc)s. External IP: %(ext_ip)s, '
'port: %(port_id)s.')
@registry.has_registry_receivers
@ -1364,6 +1366,12 @@ class L3_NAT_dbonly_mixin(l3.RouterPluginBase,
events.AFTER_UPDATE,
self._update_fip_assoc,
**assoc_result)
if assoc_result['fixed_ip_address'] and assoc_result['fixed_port_id']:
LOG.info(FIP_ASSOC_MSG,
{'fip_id': assoc_result['floating_ip_id'],
'ext_ip': assoc_result['floating_ip_address'],
'port_id': assoc_result['fixed_port_id'],
'assoc': 'associated'})
if self._is_dns_integration_supported:
self._process_dns_floatingip_create_postcommit(context,
@ -1395,9 +1403,11 @@ class L3_NAT_dbonly_mixin(l3.RouterPluginBase,
floatingip_obj = self._get_floatingip(context, id)
old_floatingip = self._make_floatingip_dict(floatingip_obj)
fip_port_id = floatingip_obj.floating_port_id
old_fixed_port_id = floatingip_obj.fixed_port_id
assoc_result = self._update_fip_assoc(
context, fip, floatingip_obj,
self._core_plugin.get_port(context.elevated(), fip_port_id))
floatingip_obj.update()
floatingip_dict = self._make_floatingip_dict(floatingip_obj)
if self._is_dns_integration_supported:
@ -1423,6 +1433,14 @@ class L3_NAT_dbonly_mixin(l3.RouterPluginBase,
events.AFTER_UPDATE,
self._update_fip_assoc,
**assoc_result)
if old_fixed_port_id != assoc_result['fixed_port_id']:
assoc = ('associated' if assoc_result['fixed_port_id']
else 'disassociated')
port_id = old_fixed_port_id or assoc_result['fixed_port_id']
LOG.info(FIP_ASSOC_MSG,
{'fip_id': assoc_result['floating_ip_id'],
'ext_ip': assoc_result['floating_ip_address'],
'port_id': port_id, 'assoc': assoc})
if self._is_dns_integration_supported:
self._process_dns_floatingip_update_postcommit(context,
@ -1610,6 +1628,12 @@ class L3_NAT_dbonly_mixin(l3.RouterPluginBase,
}
registry.notify(resources.FLOATING_IP, events.AFTER_UPDATE, self,
**assoc_result)
for fip in old_fips.values():
LOG.info(FIP_ASSOC_MSG,
{'fip_id': fip['id'],
'ext_ip': fip['floating_ip_address'],
'port_id': fip['fixed_port_id'],
'assoc': 'disassociated'})
return router_ids
def _get_floatingips_by_port_id(self, context, port_id):

View File

@ -4553,3 +4553,55 @@ class L3NatDBFloatingIpTestCaseWithDNS(L3BaseForSepTests, L3NatTestCaseMixin):
self.mock_admin_client.recordsets.create.assert_not_called()
self.assertEqual(self.DNS_DOMAIN, floatingip['dns_domain'])
self.assertEqual(self.DNS_NAME, floatingip['dns_name'])
class L3DBFloatingIpTestCaseLogging(L3BaseForSepTests, L3NatTestCaseMixin):
def setUp(self, *args, **kwargs):
ext_mgr = L3TestExtensionManagerWithDNS()
plugin = 'neutron.plugins.ml2.plugin.Ml2Plugin'
super(L3DBFloatingIpTestCaseLogging, self).setUp(plugin=plugin,
ext_mgr=ext_mgr)
self.mock_log = mock.patch.object(l3_db, 'LOG').start()
def test_create_floatingip_event_logging_port_assoc(self):
with self.floatingip_with_assoc() as fip:
msg_vars = {'fip_id': fip['floatingip']['id'],
'ext_ip': fip['floatingip']['floating_ip_address'],
'port_id': fip['floatingip']['port_id'],
'assoc': 'associated'}
self.mock_log.info.assert_called_once_with(l3_db.FIP_ASSOC_MSG,
msg_vars)
def test_update_floatingip_event_logging(self):
with self.port() as port:
private_subnet = {'subnet': {
'id': port['port']['fixed_ips'][0]['subnet_id']}}
with self.floatingip_no_assoc(private_subnet) as fip:
self.mock_log.info.assert_not_called()
fip_id = fip['floatingip']['id']
data = {'floatingip': {'port_id': port['port']['id']}}
req = self.new_update_request('floatingips', data, fip_id)
res = req.get_response(self._api_for_resource('floatingip'))
self.assertEqual(200, res.status_code)
msg_vars = {'fip_id': fip['floatingip']['id'],
'ext_ip': fip['floatingip']['floating_ip_address'],
'port_id': port['port']['id'],
'assoc': 'associated'}
self.mock_log.info.assert_called_once_with(l3_db.FIP_ASSOC_MSG,
msg_vars)
def test_update_floatingip_event_logging_disassociate(self):
with self.floatingip_with_assoc() as fip:
self.mock_log.reset_mock()
fip_id = fip['floatingip']['id']
data = {'floatingip': {'port_id': None}}
req = self.new_update_request('floatingips', data, fip_id)
res = req.get_response(self._api_for_resource('floatingip'))
self.assertEqual(200, res.status_code)
msg_vars = {'fip_id': fip['floatingip']['id'],
'ext_ip': fip['floatingip']['floating_ip_address'],
'port_id': fip['floatingip']['port_id'],
'assoc': 'disassociated'}
self.mock_log.info.assert_called_once_with(l3_db.FIP_ASSOC_MSG,
msg_vars)