[Admin-util] NSX|V admin util to use a policy in a security group

New admin utility that can be used when the user changes the configuration to use
policies in security groups (use_nsx_policies=True)
This utility deletes the current rules and section of the security group,
and adds it to the policy.

usage:
nsxadmin -r security-groups -o migrate-to-policy --property policy-id=<> --property
         security-group-id=<>

Output example:
==== [MIGRATE] Sg To Policy ====
Successfully established new session; session ID is 28c3f.
Deleting the rules of security group: 415ff93e-cbd4-4f49-a06d-44885eba7c88
Deleting the section of security group: 415ff93e-cbd4-4f49-a06d-44885eba7c88
Binding the NSX security group securitygroup-143 to policy policy-9
Done.

Change-Id: I7041c33b86a0ebc965e2cfcfe1c9ac9261a0318a
This commit is contained in:
Adit Sarfaty 2016-11-14 16:39:15 +02:00
parent a4d1498a06
commit 9d0e903139
4 changed files with 96 additions and 1 deletions

View File

@ -137,6 +137,10 @@ Security Groups, Firewall and Spoofguard
nsxadmin -r spoofguard-policy -o clean --property policy-id=spoofguardpolicy-10 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 --property reverse (entries defined on NSXv and not in Neutron)
- Migrate a security group from using rules to using a policy
nsxadmin -r security-groups -o migrate-to-policy --property policy-id=policy-10 --property security-group-id=733f0741-fa2c-4b32-811c-b78e4dc8ec39
Metadata Metadata
~~~~~~~~ ~~~~~~~~

View File

@ -448,6 +448,12 @@ def get_nsx_section(session, neutron_id):
"stored in Neutron DB", neutron_id) "stored in Neutron DB", neutron_id)
def delete_neutron_nsx_section_mapping(session, neutron_id):
with session.begin(subtransactions=True):
return (session.query(nsxv_models.NsxvSecurityGroupSectionMapping).
filter_by(neutron_id=neutron_id).delete())
def get_nsx_rule_id(session, neutron_id): def get_nsx_rule_id(session, neutron_id):
try: try:
mapping = (session.query(nsxv_models.NsxvRuleMapping). mapping = (session.query(nsxv_models.NsxvRuleMapping).

View File

@ -16,18 +16,24 @@
import logging import logging
import xml.etree.ElementTree as et import xml.etree.ElementTree as et
from neutron.callbacks import registry
from neutron import context from neutron import context
from neutron.db.models import securitygroup as sg_models from neutron.db.models import securitygroup as sg_models
from neutron.db import models_v2 from neutron.db import models_v2
from neutron.db import securitygroups_db from neutron.db import securitygroups_db
from neutron.extensions import securitygroup as ext_sg
from vmware_nsx._i18n import _LE, _LI, _LW
from vmware_nsx.db import db as nsx_db from vmware_nsx.db import db as nsx_db
from vmware_nsx.db import nsx_models from vmware_nsx.db import nsx_models
from vmware_nsx.db import nsxv_db
from vmware_nsx.db import nsxv_models from vmware_nsx.db import nsxv_models
from vmware_nsx.extensions import securitygrouppolicy as sg_policy
from vmware_nsx.shell.admin.plugins.common import constants from vmware_nsx.shell.admin.plugins.common import constants
from vmware_nsx.shell.admin.plugins.common import formatters from vmware_nsx.shell.admin.plugins.common import formatters
from vmware_nsx.shell.admin.plugins.common import utils as admin_utils from vmware_nsx.shell.admin.plugins.common import utils as admin_utils
from vmware_nsx.shell.admin.plugins.nsxv.resources import utils from vmware_nsx.shell.admin.plugins.nsxv.resources import utils
from vmware_nsx.shell import resources as shell
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
@ -242,3 +248,80 @@ def fix_security_groups(resource, event, trigger, **kwargs):
nsx_id = nsx_db.get_nsx_security_group_id(context_.session, sg_id) nsx_id = nsx_db.get_nsx_security_group_id(context_.session, sg_id)
for vnic_id in neutron_sg.get_vnics_in_security_group(sg_id): for vnic_id in neutron_sg.get_vnics_in_security_group(sg_id):
plugin._add_member_to_security_group(nsx_id, vnic_id) plugin._add_member_to_security_group(nsx_id, vnic_id)
@admin_utils.output_header
def migrate_sg_to_policy(resource, event, trigger, **kwargs):
"""Change the mode of a security group from rules to NSX policy"""
if not kwargs.get('property'):
LOG.error(_LE("Need to specify security-group-id and policy-id "
"parameters"))
return
# input validation
properties = admin_utils.parse_multi_keyval_opt(kwargs['property'])
sg_id = properties.get('security-group-id')
if not sg_id:
LOG.error(_LE("Need to specify security-group-id parameter"))
return
policy_id = properties.get('policy-id')
if not policy_id:
LOG.error(_LE("Need to specify policy-id parameter"))
return
# validate that the security group exist and contains rules and no policy
context_ = context.get_admin_context()
plugin = utils.NsxVPluginWrapper()
try:
secgroup = plugin.get_security_group(context_, sg_id)
except ext_sg.SecurityGroupNotFound:
LOG.error(_LE("Security group %s was not found"), sg_id)
return
if secgroup.get('policy'):
LOG.error(_LE("Security group %s already uses a policy"), sg_id)
return
# validate that the policy exists
if not plugin.nsx_v.vcns.validate_inventory(policy_id):
LOG.error(_LE("NSX policy %s was not found"), policy_id)
return
# Delete the rules from the security group
LOG.info(_LI("Deleting the rules of security group: %s"), sg_id)
for rule in secgroup.get('security_group_rules', []):
try:
plugin.delete_security_group_rule(context_, rule['id'])
except Exception as e:
LOG.warning(_LW("Failed to delete rule %(r)s from security group "
"%(sg)s: %(e)s"),
{'r': rule['id'], 'sg': sg_id, 'e': e})
# continue anyway
# Delete the security group FW section
LOG.info(_LI("Deleting the section of security group: %s"), sg_id)
try:
section_uri = plugin._get_section_uri(context_.session, sg_id)
plugin._delete_section(section_uri)
nsxv_db.delete_neutron_nsx_section_mapping(context_.session, sg_id)
except Exception as e:
LOG.warning(_LW("Failed to delete firewall section of security group "
"%(sg)s: %(e)s"),
{'sg': sg_id, 'e': e})
# continue anyway
# bind this security group to the policy in the backend and DB
nsx_sg_id = nsx_db.get_nsx_security_group_id(context_.session, sg_id)
LOG.info(_LI("Binding the NSX security group %(nsx)s to policy %(pol)s"),
{'nsx': nsx_sg_id, 'pol': policy_id})
plugin._update_nsx_security_group_policies(
policy_id, None, nsx_sg_id)
prop = plugin._get_security_group_properties(context_, sg_id)
with context_.session.begin(subtransactions=True):
prop.update({sg_policy.POLICY: policy_id})
LOG.info(_LI("Done."))
registry.subscribe(migrate_sg_to_policy,
constants.SECURITY_GROUPS,
shell.Operations.MIGRATE_TO_POLICY.value)

View File

@ -48,6 +48,7 @@ class Operations(enum.Enum):
NSX_RECREATE = 'nsx-recreate' NSX_RECREATE = 'nsx-recreate'
MIGRATE_TO_DYNAMIC_CRITERIA = 'migrate-to-dynamic-criteria' MIGRATE_TO_DYNAMIC_CRITERIA = 'migrate-to-dynamic-criteria'
NSX_MIGRATE_V_V3 = 'nsx-migrate-v-v3' NSX_MIGRATE_V_V3 = 'nsx-migrate-v-v3'
MIGRATE_TO_POLICY = 'migrate-to-policy'
STATUS = 'status' STATUS = 'status'
ops = [op.value for op in Operations] ops = [op.value for op in Operations]
@ -121,7 +122,8 @@ nsxv_resources = {
Operations.NSX_CLEAN.value]), Operations.NSX_CLEAN.value]),
constants.SECURITY_GROUPS: Resource(constants.SECURITY_GROUPS, constants.SECURITY_GROUPS: Resource(constants.SECURITY_GROUPS,
[Operations.LIST.value, [Operations.LIST.value,
Operations.FIX_MISMATCH.value]), Operations.FIX_MISMATCH.value,
Operations.MIGRATE_TO_POLICY.value]),
constants.FIREWALL_SECTIONS: Resource(constants.FIREWALL_SECTIONS, constants.FIREWALL_SECTIONS: Resource(constants.FIREWALL_SECTIONS,
[Operations.LIST.value, [Operations.LIST.value,
Operations.LIST_MISMATCHES.value]), Operations.LIST_MISMATCHES.value]),