NSX|V admin utils: Find and fix spoofguard policies mismatches
1. List spoofguard policies with mismatching ips or mac, globally or for a specific network nsxadmin -r spoofguard-policy -o list-mismatches (--property network=<neutron net id>) 2. Fix the spoofguard ips of a neutron port nsxadmin -r spoofguard-policy -o fix-mismatch --property port=<neutron port id> Change-Id: I18723007fff89ffd4a250106fed1b7ea615eb648
This commit is contained in:
parent
2919467331
commit
fd8500ba42
@ -279,9 +279,10 @@ Security Groups, Firewall and Spoofguard
|
||||
|
||||
- Spoofguard support::
|
||||
|
||||
nsxadmin -r spoofguard-policy -o list-mismatches
|
||||
nsxadmin -r spoofguard-policy -o clean --property policy-id=spoofguardpolicy-10
|
||||
nsxadmin -r spoofguard-policy -o list --property reverse (entries defined on NSXv and not in Neutron)
|
||||
nsxadmin -r spoofguard-policy -o list-mismatches (--property network=<neutron net id>) - List spoofguard policies with mismatching ips or mac, globally or for a specific network
|
||||
nsxadmin -r spoofguard-policy -o fix-mismatch --property port=<neutron port id> - Fix the spoofgurad ips of a neutron port
|
||||
|
||||
Metadata
|
||||
~~~~~~~~
|
||||
|
@ -663,6 +663,17 @@ def get_spoofguard_policy_id(session, network_id):
|
||||
network_id)
|
||||
|
||||
|
||||
def get_spoofguard_policy_network_id(session, policy_id):
|
||||
try:
|
||||
mapping = (session.query(
|
||||
nsxv_models.NsxvSpoofGuardPolicyNetworkMapping).
|
||||
filter_by(policy_id=policy_id).one())
|
||||
return mapping['network_id']
|
||||
except exc.NoResultFound:
|
||||
LOG.debug("SpoofGuard Policy %s was not found in Neutron DB",
|
||||
policy_id)
|
||||
|
||||
|
||||
def get_nsxv_spoofguard_policy_network_mappings(session, filters=None,
|
||||
like_filters=None):
|
||||
session = db_api.get_reader_session()
|
||||
|
@ -812,6 +812,10 @@ class Vcns(object):
|
||||
uri = '%s/policies/%s' % (SPOOFGUARD_PREFIX, policy_id)
|
||||
return self.do_request(HTTP_GET, uri, decode=True)
|
||||
|
||||
def get_spoofguard_policy_data(self, policy_id, list_type='ALL'):
|
||||
uri = '%s/%s?list=%s' % (SPOOFGUARD_PREFIX, policy_id, list_type)
|
||||
return self.do_request(HTTP_GET, uri, decode=True)
|
||||
|
||||
def get_spoofguard_policies(self):
|
||||
uri = '%s/policies/' % SPOOFGUARD_PREFIX
|
||||
return self.do_request(HTTP_GET, uri, decode=True)
|
||||
|
@ -24,6 +24,8 @@ from neutron_lib.callbacks import registry
|
||||
from neutron_lib import exceptions
|
||||
|
||||
from vmware_nsx.db import nsxv_db
|
||||
from vmware_nsx.extensions import (
|
||||
vnicindex as ext_vnic_idx)
|
||||
|
||||
from oslo_log import log as logging
|
||||
|
||||
@ -36,6 +38,12 @@ def get_spoofguard_policies():
|
||||
return nsxv.get_spoofguard_policies()[1].get("policies")
|
||||
|
||||
|
||||
def get_spoofguard_policy_data(policy_id):
|
||||
nsxv = utils.get_nsxv_client()
|
||||
return nsxv.get_spoofguard_policy_data(policy_id)[1].get(
|
||||
'spoofguardList', [])
|
||||
|
||||
|
||||
@admin_utils.output_header
|
||||
def nsx_list_spoofguard_policies(resource, event, trigger, **kwargs):
|
||||
"""List spoofguard policies from NSXv backend"""
|
||||
@ -100,6 +108,134 @@ def nsx_list_missing_spoofguard_policies(resource, event, trigger,
|
||||
constants.SPOOFGUARD_POLICY, missing_policies, ['policy_id']))
|
||||
|
||||
|
||||
def get_port_vnic_id(plugin, port):
|
||||
vnic_idx = port.get(ext_vnic_idx.VNIC_INDEX)
|
||||
device_id = port.get('device_id')
|
||||
return plugin._get_port_vnic_id(vnic_idx, device_id)
|
||||
|
||||
|
||||
def nsx_list_mismatch_addresses_for_net(context, plugin, network_id,
|
||||
policy_id):
|
||||
policy_data = get_spoofguard_policy_data(policy_id)
|
||||
missing = []
|
||||
# Get all neutron compute ports on this network
|
||||
port_filters = {'network_id': [network_id]}
|
||||
neutron_ports = plugin.get_ports(context, filters=port_filters)
|
||||
comp_ports = [port for port in neutron_ports
|
||||
if port.get('device_owner', '').startswith('compute:')]
|
||||
|
||||
for port in comp_ports:
|
||||
if not port['port_security_enabled']:
|
||||
# This port is not in spoofguard
|
||||
continue
|
||||
error_data = None
|
||||
port_ips = []
|
||||
for pair in port.get('allowed_address_pairs'):
|
||||
port_ips.append(pair['ip_address'])
|
||||
for fixed in port.get('fixed_ips'):
|
||||
port_ips.append(fixed['ip_address'])
|
||||
if not port_ips:
|
||||
continue
|
||||
port_ips.sort()
|
||||
mac_addr = port['mac_address']
|
||||
vnic_id = get_port_vnic_id(plugin, port)
|
||||
|
||||
# look for this port in the spoofguard data
|
||||
found_port = False
|
||||
for spd in policy_data:
|
||||
if spd['id'] == vnic_id:
|
||||
found_port = True
|
||||
actual_ips = spd.get('publishedIpAddress',
|
||||
{}).get('ipAddresses', [])
|
||||
actual_ips.sort()
|
||||
if actual_ips != port_ips:
|
||||
error_data = ('Different IPs (%s/%s)' % (
|
||||
len(actual_ips), len(port_ips)))
|
||||
elif spd.get('publishedMacAddress') != mac_addr:
|
||||
error_data = ('Different MAC address (%s/%s)' % (
|
||||
spd.get('publishedMacAddress'), mac_addr))
|
||||
continue
|
||||
|
||||
if not found_port:
|
||||
error_data = 'Port missing from SG policy'
|
||||
|
||||
if error_data:
|
||||
missing.append({'network': network_id,
|
||||
'policy': policy_id,
|
||||
'port': port['id'],
|
||||
'data': error_data})
|
||||
return missing
|
||||
|
||||
|
||||
@admin_utils.output_header
|
||||
def nsx_list_mismatch_addresses(resource, event, trigger, **kwargs):
|
||||
"""List missing spoofguard policies approved addresses on NSXv.
|
||||
|
||||
Address pairs defined on neutron compute ports that are missing from the
|
||||
NSX-V spoofguard policy of a specific/all networks.
|
||||
"""
|
||||
network_id = None
|
||||
if kwargs.get('property'):
|
||||
properties = admin_utils.parse_multi_keyval_opt(kwargs['property'])
|
||||
network_id = properties.get('network')
|
||||
|
||||
spgapi = utils.NeutronDbClient()
|
||||
|
||||
if network_id:
|
||||
policy_id = nsxv_db.get_spoofguard_policy_id(
|
||||
spgapi.context.session, network_id)
|
||||
if not policy_id:
|
||||
LOG.error("Could not find spoofguard policy for neutron network "
|
||||
"%s", network_id)
|
||||
return
|
||||
with utils.NsxVPluginWrapper() as plugin:
|
||||
missing_data = nsx_list_mismatch_addresses_for_net(
|
||||
spgapi.context, plugin, network_id, policy_id)
|
||||
else:
|
||||
with utils.NsxVPluginWrapper() as plugin:
|
||||
missing_data = []
|
||||
# Go over all the networks with spoofguard policies
|
||||
mappings = get_spoofguard_policy_network_mappings()
|
||||
for entry in mappings:
|
||||
missing_data.extend(nsx_list_mismatch_addresses_for_net(
|
||||
spgapi.context, plugin, entry['network_id'],
|
||||
entry['policy_id']))
|
||||
|
||||
if missing_data:
|
||||
LOG.info(formatters.output_formatter(
|
||||
constants.SPOOFGUARD_POLICY, missing_data,
|
||||
['network', 'policy', 'port', 'data']))
|
||||
else:
|
||||
LOG.info("No mismatches found.")
|
||||
|
||||
|
||||
@admin_utils.output_header
|
||||
def nsx_fix_mismatch_addresses(resource, event, trigger, **kwargs):
|
||||
"""Fix missing spoofguard policies approved addresses for a port."""
|
||||
|
||||
port_id = None
|
||||
if kwargs.get('property'):
|
||||
properties = admin_utils.parse_multi_keyval_opt(kwargs['property'])
|
||||
port_id = properties.get('port')
|
||||
if not port_id:
|
||||
usage_msg = ("Need to specify the id of the neutron port. "
|
||||
"Add --property port=<port_id>")
|
||||
LOG.error(usage_msg)
|
||||
return
|
||||
|
||||
spgapi = utils.NeutronDbClient()
|
||||
with utils.NsxVPluginWrapper() as plugin:
|
||||
try:
|
||||
port = plugin.get_port(spgapi.context, port_id)
|
||||
except exceptions.PortNotFound:
|
||||
LOG.error("Could not find neutron port %s", port_id)
|
||||
return
|
||||
vnic_id = get_port_vnic_id(plugin, port)
|
||||
plugin._update_vnic_assigned_addresses(
|
||||
spgapi.context.session, port, vnic_id)
|
||||
LOG.info("Done.")
|
||||
|
||||
|
||||
def nsx_clean_spoofguard_policy(resource, event, trigger, **kwargs):
|
||||
"""Delete spoofguard policy"""
|
||||
errmsg = ("Need to specify policy-id. Add --property "
|
||||
@ -143,6 +279,12 @@ registry.subscribe(nsx_list_spoofguard_policies,
|
||||
registry.subscribe(nsx_list_missing_spoofguard_policies,
|
||||
constants.SPOOFGUARD_POLICY,
|
||||
shell.Operations.LIST.value)
|
||||
registry.subscribe(nsx_list_mismatch_addresses,
|
||||
constants.SPOOFGUARD_POLICY,
|
||||
shell.Operations.LIST_MISMATCHES.value)
|
||||
registry.subscribe(nsx_fix_mismatch_addresses,
|
||||
constants.SPOOFGUARD_POLICY,
|
||||
shell.Operations.FIX_MISMATCH.value)
|
||||
registry.subscribe(nsx_clean_spoofguard_policy,
|
||||
constants.SPOOFGUARD_POLICY,
|
||||
shell.Operations.CLEAN.value)
|
||||
|
@ -176,7 +176,9 @@ nsxv_resources = {
|
||||
[Operations.LIST.value]),
|
||||
constants.SPOOFGUARD_POLICY: Resource(constants.SPOOFGUARD_POLICY,
|
||||
[Operations.LIST.value,
|
||||
Operations.CLEAN.value]),
|
||||
Operations.CLEAN.value,
|
||||
Operations.LIST_MISMATCHES.value,
|
||||
Operations.FIX_MISMATCH.value]),
|
||||
constants.DHCP_BINDING: Resource(constants.DHCP_BINDING,
|
||||
[Operations.LIST.value,
|
||||
Operations.NSX_UPDATE.value,
|
||||
|
@ -1141,6 +1141,9 @@ class FakeVcns(object):
|
||||
raise exceptions.VcnsGeneralException(
|
||||
_("Spoofguard policy not found"))
|
||||
|
||||
def get_spoofguard_policy_data(self, policy_id, list_type='INACTIVE'):
|
||||
return None, {'spoofguardList': []}
|
||||
|
||||
def get_spoofguard_policies(self):
|
||||
return None, {'policies': self._spoofguard_policies}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user