Esempio n. 1
0
def nsx_update_metadata_proxy(resource, event, trigger, **kwargs):
    """Update Metadata proxy for NSXv3 CrossHairs."""

    nsx_version = utils.get_connected_nsxlib().get_version()
    if not nsx_utils.is_nsx_version_1_1_0(nsx_version):
        LOG.info(_LI("This utility is not available for NSX version %s"),
                 nsx_version)
        return

    metadata_proxy_uuid = None
    if kwargs.get('property'):
        properties = admin_utils.parse_multi_keyval_opt(kwargs['property'])
        metadata_proxy_uuid = properties.get('metadata_proxy_uuid')
    if not metadata_proxy_uuid:
        LOG.error(_LE("metadata_proxy_uuid is not defined"))
        return

    cfg.CONF.set_override('dhcp_agent_notification', False)
    cfg.CONF.set_override('native_dhcp_metadata', True, 'nsx_v3')
    cfg.CONF.set_override('metadata_proxy_uuid', metadata_proxy_uuid, 'nsx_v3')

    plugin = utils.NsxV3PluginWrapper()
    nsx_client = utils.get_nsxv3_client()
    port_resource = resources.LogicalPort(nsx_client)

    # For each Neutron network, check if it is an internal metadata network.
    # If yes, delete the network and associated router interface.
    # Otherwise, create a logical switch port with MD-Proxy attachment.
    for network in neutron_client.get_networks():
        if _is_metadata_network(network):
            # It is a metadata network, find the attached router,
            # remove the router interface and the network.
            filters = {'device_owner': const.ROUTER_INTERFACE_OWNERS,
                       'fixed_ips': {
                           'subnet_id': [network['subnets'][0]],
                           'ip_address': [nsx_rpc.METADATA_GATEWAY_IP]}}
            ports = neutron_client.get_ports(filters=filters)
            if not ports:
                continue
            router_id = ports[0]['device_id']
            interface = {'subnet_id': network['subnets'][0]}
            plugin.remove_router_interface(router_id, interface)
            LOG.info(_LI("Removed metadata interface on router %s"), router_id)
            plugin.delete_network(network['id'])
            LOG.info(_LI("Removed metadata network %s"), network['id'])
        else:
            lswitch_id = neutron_client.net_id_to_lswitch_id(network['id'])
            if not lswitch_id:
                continue
            tags = nsx_utils.build_v3_tags_payload(
                network, resource_type='os-neutron-net-id',
                project_name='admin')
            name = nsx_utils.get_name_and_uuid('%s-%s' % (
                'mdproxy', network['name'] or 'network'), network['id'])
            port_resource.create(
                lswitch_id, metadata_proxy_uuid, tags=tags, name=name,
                attachment_type=nsx_constants.ATTACHMENT_MDPROXY)
            LOG.info(_LI("Enabled native metadata proxy for network %s"),
                     network['id'])
Esempio n. 2
0
def migrate_nsgroups_to_dynamic_criteria(resource, event, trigger, **kwargs):
    if not utils.is_nsx_version_1_1_0(nsxlib.get_version()):
        LOG.error(
            _LE("Dynamic criteria grouping feature isn't supported by "
                "this NSX version."))
        return
    # First, we add the criteria tags for all ports.
    _update_ports_dynamic_criteria_tags()
    # Update security-groups with dynamic criteria and remove direct members.
    _update_security_group_dynamic_criteria()
Esempio n. 3
0
def nsx_update_metadata_proxy_server_ip(resource, event, trigger, **kwargs):
    """Update Metadata proxy server ip on the nsx."""
    nsxlib = utils.get_connected_nsxlib()
    nsx_version = nsxlib.get_version()
    if not nsx_utils.is_nsx_version_1_1_0(nsx_version):
        LOG.error("This utility is not available for NSX version %s",
                  nsx_version)
        return

    server_ip = None
    az_name = nsx_az.DEFAULT_NAME
    if kwargs.get('property'):
        properties = admin_utils.parse_multi_keyval_opt(kwargs['property'])
        server_ip = properties.get('server-ip')
        az_name = properties.get('availability-zone', az_name)
    if not server_ip or not netaddr.valid_ipv4(server_ip):
        LOG.error("Need to specify a valid server-ip parameter")
        return

    config.register_nsxv3_azs(cfg.CONF, cfg.CONF.nsx_v3.availability_zones)
    if (az_name != nsx_az.DEFAULT_NAME
            and az_name not in cfg.CONF.nsx_v3.availability_zones):
        LOG.error("Availability zone %s was not found in the configuration",
                  az_name)
        return

    az = nsx_az.NsxV3AvailabilityZones().get_availability_zone(az_name)
    az.translate_configured_names_to_uuids(nsxlib)

    if (not az.metadata_proxy or not cfg.CONF.nsx_v3.native_dhcp_metadata):
        LOG.error(
            "Native DHCP metadata is not enabled in the configuration "
            "of availability zone %s", az_name)
        return
    metadata_proxy_uuid = az._native_md_proxy_uuid

    try:
        mdproxy = nsxlib.native_md_proxy.get(metadata_proxy_uuid)
    except nsx_exc.ResourceNotFound:
        LOG.error("metadata proxy %s not found", metadata_proxy_uuid)
        return

    # update the IP in the URL
    url = mdproxy.get('metadata_server_url')
    url = re.sub(r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}', server_ip, url)
    LOG.info(
        "Updating the URL of the metadata proxy server %(uuid)s to "
        "%(url)s", {
            'uuid': metadata_proxy_uuid,
            'url': url
        })
    nsxlib.native_md_proxy.update(metadata_proxy_uuid, server_url=url)
    LOG.info("Done.")
Esempio n. 4
0
def fix_security_groups(resource, event, trigger, **kwargs):
    context_ = neutron_context.get_admin_context()
    plugin = v3_utils.NsxV3PluginWrapper()
    inconsistent_secgroups = _find_missing_sections()
    inconsistent_secgroups.update(_find_missing_security_groups())

    for sg_id, sg in inconsistent_secgroups.items():
        secgroup = plugin.get_security_group(context_, sg_id)

        try:
            # FIXME(roeyc): try..except clause should be removed once the api
            # will return 404 response code instead 400 for trying to delete a
            # non-existing firewall section.
            nsxlib.firewall_section.delete(sg['section-id'])
        except Exception:
            pass
        nsxlib.ns_group.delete(sg['nsx-securitygroup-id'])
        neutron_sg.delete_security_group_section_mapping(sg_id)
        neutron_sg.delete_security_group_backend_mapping(sg_id)
        nsgroup, fw_section = (
            plugin._create_security_group_backend_resources(secgroup))
        nsx_db.save_sg_mappings(context_.session, sg_id, nsgroup['id'],
                                fw_section['id'])
        # If version > 1.1 then we use dynamic criteria tags, and the port
        # should already have them.
        if not utils.is_nsx_version_1_1_0(plugin._nsx_version):
            members = []
            for port_id in neutron_db.get_ports_in_security_group(sg_id):
                lport_id = neutron_db.get_logical_port_id(port_id)
                members.append(lport_id)
            nsxlib.ns_group.add_members(nsgroup['id'],
                                        consts.TARGET_TYPE_LOGICAL_PORT,
                                        members)

        for rule in secgroup['security_group_rules']:
            rule_mapping = (context_.session.query(
                nsx_models.NeutronNsxRuleMapping).filter_by(
                    neutron_id=rule['id']).one())
            with context_.session.begin(subtransactions=True):
                context_.session.delete(rule_mapping)
        action = (consts.FW_ACTION_DROP if secgroup.get(provider_sg.PROVIDER)
                  else consts.FW_ACTION_ALLOW)
        rules = plugin._create_firewall_rules(
            context_, fw_section['id'], nsgroup['id'],
            secgroup.get(sg_logging.LOGGING, False), action,
            secgroup['security_group_rules'])
        plugin.save_security_group_rule_mappings(context_, rules['rules'])
        # Add nsgroup to a nested group
        plugin.nsgroup_manager.add_nsgroup(nsgroup['id'])
Esempio n. 5
0
def nsx_clean_orphaned_dhcp_servers(resource, event, trigger, **kwargs):
    """Remove logical DHCP servers without associated DHCP-enabled subnet."""

    # For each orphaned DHCP server,
    # (1) delete the attached logical DHCP port,
    # (2) delete the logical DHCP server,
    # (3) clean corresponding neutron DB entry.

    nsx_version = nsxlib.get_version()
    if not nsx_utils.is_nsx_version_1_1_0(nsx_version):
        LOG.error("This utility is not available for NSX version %s",
                  nsx_version)
        return

    dhcp_profile_uuid = _get_dhcp_profile_uuid(**kwargs)
    if not dhcp_profile_uuid:
        LOG.error("dhcp_profile_uuid is not defined")
        return

    cfg.CONF.set_override('dhcp_agent_notification', False)
    cfg.CONF.set_override('native_dhcp_metadata', True, 'nsx_v3')
    cfg.CONF.set_override('dhcp_profile', dhcp_profile_uuid, 'nsx_v3')

    orphaned_servers = _get_orphaned_dhcp_servers(dhcp_profile_uuid)

    for server in orphaned_servers:
        try:
            # TODO(asarfaty): should add this as api to nsxlib instead of
            # abusing it
            resource = ('?attachment_type=DHCP_SERVICE&attachment_id=%s' %
                        server['id'])
            response = nsxlib.logical_port.get(resource)
            if response and response['result_count'] > 0:
                nsxlib.logical_port.delete(response['results'][0]['id'])
            nsxlib.dhcp_server.delete(server['id'])
            net_id = server.get('neutron_net_id')
            if net_id:
                # Delete neutron_net_id -> dhcp_service_id mapping from the DB.
                nsx_db.delete_neutron_nsx_service_binding(
                    context.get_admin_context().session, net_id,
                    nsx_constants.SERVICE_DHCP)
            LOG.info("Removed orphaned DHCP server %s", server['id'])
        except Exception as e:
            LOG.error(
                "Failed to clean orphaned DHCP server %(id)s. "
                "Exception: %(e)s", {
                    'id': server['id'],
                    'e': e
                })
Esempio n. 6
0
def nsx_list_orphaned_dhcp_servers(resource, event, trigger, **kwargs):
    """List logical DHCP servers without associated DHCP-enabled subnet."""

    nsxlib = utils.get_connected_nsxlib()
    nsx_version = nsxlib.get_version()
    if not nsx_utils.is_nsx_version_1_1_0(nsx_version):
        LOG.error("This utility is not available for NSX version %s",
                  nsx_version)
        return

    dhcp_profile_uuid = _get_dhcp_profile_uuid(**kwargs)
    if not dhcp_profile_uuid:
        LOG.error("dhcp_profile_uuid is not defined")
        return

    orphaned_servers = _get_orphaned_dhcp_servers(dhcp_profile_uuid)
    LOG.info(formatters.output_formatter(constants.ORPHANED_DHCP_SERVERS,
                                         orphaned_servers,
                                         ['id', 'neutron_net_id']))
Esempio n. 7
0
def fix_security_groups(resource, event, trigger, **kwargs):
    context_ = neutron_context.get_admin_context()
    plugin = v3_utils.NsxV3PluginWrapper()
    inconsistent_secgroups = _find_missing_sections()
    inconsistent_secgroups.update(_find_missing_security_groups())

    for sg_id, sg in inconsistent_secgroups.items():
        secgroup = plugin.get_security_group(context_, sg_id)
        nsxlib.delete_section(sg['section-id'])
        nsxlib.delete_nsgroup(sg['nsx-securitygroup-id'])
        neutron_sg.delete_security_group_section_mapping(sg_id)
        neutron_sg.delete_security_group_backend_mapping(sg_id)
        nsgroup, fw_section = (
            plugin._create_security_group_backend_resources(secgroup))
        nsx_db.save_sg_mappings(context_.session, sg_id, nsgroup['id'],
                                fw_section['id'])
        # If version > 1.1 then we use dynamic criteria tags, and the port
        # should already have them.
        if not utils.is_nsx_version_1_1_0(plugin._nsx_version):
            members = []
            for port_id in neutron_db.get_ports_in_security_group(sg_id):
                lport_id = neutron_db.get_logical_port_id(port_id)
                members.append(lport_id)
            nsxlib.add_nsgroup_members(nsgroup['id'], firewall.LOGICAL_PORT,
                                       members)

        for rule in secgroup['security_group_rules']:
            rule_mapping = (context_.session.query(
                nsx_models.NeutronNsxRuleMapping).filter_by(
                    neutron_id=rule['id']).one())
            with context_.session.begin(subtransactions=True):
                context_.session.delete(rule_mapping)
        action = (firewall.DROP
                  if secgroup.get(provider_sg.PROVIDER) else firewall.ALLOW)
        rules = nsxlib.create_firewall_rules(
            context_, fw_section['id'], nsgroup['id'],
            secgroup.get(sg_logging.LOGGING, False), action,
            secgroup['security_group_rules'])
        nsxlib.save_sg_rule_mappings(context_.session, rules['rules'])
        # Add nsgroup to a nested group
        plugin.nsgroup_manager.add_nsgroup(nsgroup['id'])
Esempio n. 8
0
def nsx_list_orphaned_dhcp_servers(resource, event, trigger, **kwargs):
    """List logical DHCP servers without associated DHCP-enabled subnet."""

    nsxlib = utils.get_connected_nsxlib()
    nsx_version = nsxlib.get_version()
    if not nsx_utils.is_nsx_version_1_1_0(nsx_version):
        LOG.error("This utility is not available for NSX version %s",
                  nsx_version)
        return

    dhcp_profile_uuid = _get_dhcp_profile_uuid(**kwargs)
    if not dhcp_profile_uuid:
        LOG.error("dhcp_profile_uuid is not defined")
        return

    orphaned_servers = v3_utils.get_orphaned_dhcp_servers(
        context.get_admin_context(),
        neutron_client, nsxlib, dhcp_profile_uuid)
    LOG.info(formatters.output_formatter(
        constants.ORPHANED_DHCP_SERVERS,
        orphaned_servers,
        ['id', 'neutron_net_id', 'display_name']))
Esempio n. 9
0
def nsx_clean_orphaned_dhcp_servers(resource, event, trigger, **kwargs):
    """Remove logical DHCP servers without associated DHCP-enabled subnet."""

    # For each orphaned DHCP server,
    # (1) delete the attached logical DHCP port,
    # (2) delete the logical DHCP server,
    # (3) clean corresponding neutron DB entry.

    nsxlib = utils.get_connected_nsxlib()
    nsx_version = nsxlib.get_version()
    if not nsx_utils.is_nsx_version_1_1_0(nsx_version):
        LOG.error("This utility is not available for NSX version %s",
                  nsx_version)
        return

    dhcp_profile_uuid = _get_dhcp_profile_uuid(**kwargs)
    if not dhcp_profile_uuid:
        LOG.error("dhcp_profile_uuid is not defined")
        return

    cfg.CONF.set_override('dhcp_agent_notification', False)
    cfg.CONF.set_override('native_dhcp_metadata', True, 'nsx_v3')
    cfg.CONF.set_override('dhcp_profile', dhcp_profile_uuid, 'nsx_v3')

    orphaned_servers = v3_utils.get_orphaned_dhcp_servers(
        context.get_admin_context(), neutron_client, nsxlib, dhcp_profile_uuid)

    for server in orphaned_servers:
        success, error = v3_utils.delete_orphaned_dhcp_server(
            context.get_admin_context(), nsxlib, server)
        if success:
            LOG.info("Removed orphaned DHCP server %s", server['id'])
        else:
            LOG.error(
                "Failed to clean orphaned DHCP server %(id)s. "
                "Exception: %(e)s", {
                    'id': server['id'],
                    'e': error
                })
Esempio n. 10
0
def nsx_clean_orphaned_dhcp_servers(resource, event, trigger, **kwargs):
    """Remove logical DHCP servers without associated DHCP-enabled subnet."""

    # For each orphaned DHCP server,
    # (1) delete the attached logical DHCP port,
    # (2) delete the logical DHCP server,
    # (3) clean corresponding neutron DB entry.

    nsxlib = utils.get_connected_nsxlib()
    nsx_version = nsxlib.get_version()
    if not nsx_utils.is_nsx_version_1_1_0(nsx_version):
        LOG.error("This utility is not available for NSX version %s",
                  nsx_version)
        return

    dhcp_profile_uuid = _get_dhcp_profile_uuid(**kwargs)
    if not dhcp_profile_uuid:
        LOG.error("dhcp_profile_uuid is not defined")
        return

    cfg.CONF.set_override('dhcp_agent_notification', False)
    cfg.CONF.set_override('native_dhcp_metadata', True, 'nsx_v3')
    cfg.CONF.set_override('dhcp_profile', dhcp_profile_uuid, 'nsx_v3')

    orphaned_servers = v3_utils.get_orphaned_dhcp_servers(
        context.get_admin_context(),
        neutron_client, nsxlib, dhcp_profile_uuid)

    for server in orphaned_servers:
        success, error = v3_utils.delete_orphaned_dhcp_server(
            context.get_admin_context(), nsxlib, server)
        if success:
            LOG.info("Removed orphaned DHCP server %s", server['id'])
        else:
            LOG.error("Failed to clean orphaned DHCP server %(id)s. "
                      "Exception: %(e)s", {'id': server['id'], 'e': error})
Esempio n. 11
0
def nsx_update_dhcp_bindings(resource, event, trigger, **kwargs):
    """Resync DHCP bindings for NSXv3 CrossHairs."""

    nsxlib = utils.get_connected_nsxlib()
    nsx_version = nsxlib.get_version()
    if not nsx_utils.is_nsx_version_1_1_0(nsx_version):
        LOG.error("This utility is not available for NSX version %s",
                  nsx_version)
        return

    dhcp_profile_uuid = None
    # TODO(asarfaty) Add availability zones support here
    if kwargs.get('property'):
        properties = admin_utils.parse_multi_keyval_opt(kwargs['property'])
        dhcp_profile_uuid = properties.get('dhcp_profile_uuid')
    if not dhcp_profile_uuid:
        LOG.error("dhcp_profile_uuid is not defined")
        return

    cfg.CONF.set_override('dhcp_agent_notification', False)
    cfg.CONF.set_override('native_dhcp_metadata', True, 'nsx_v3')
    cfg.CONF.set_override('dhcp_profile', dhcp_profile_uuid, 'nsx_v3')

    port_bindings = {}    # lswitch_id: [(port_id, mac, ip), ...]
    server_bindings = {}  # lswitch_id: dhcp_server_id
    ports = neutron_client.get_ports()
    for port in ports:
        device_owner = port['device_owner']
        if (device_owner != const.DEVICE_OWNER_DHCP and
            not nsx_utils.is_port_dhcp_configurable(port)):
            continue
        for fixed_ip in port['fixed_ips']:
            if netaddr.IPNetwork(fixed_ip['ip_address']).version == 6:
                continue
            network_id = port['network_id']
            subnet = neutron_client.get_subnet(fixed_ip['subnet_id'])
            if device_owner == const.DEVICE_OWNER_DHCP:
                # For each DHCP-enabled network, create a logical DHCP server
                # and update the attachment type to DHCP on the corresponding
                # logical port of the Neutron DHCP port.
                network = neutron_client.get_network(port['network_id'])
                net_tags = nsxlib.build_v3_tags_payload(
                    network, resource_type='os-neutron-net-id',
                    project_name='admin')
                # TODO(asarfaty): add default_dns_nameservers & dns_domain
                # from availability zone
                server_data = nsxlib.native_dhcp.build_server_config(
                    network, subnet, port, net_tags)
                server_data['dhcp_profile_id'] = dhcp_profile_uuid
                dhcp_server = nsxlib.dhcp_server.create(**server_data)
                LOG.info("Created logical DHCP server %(server)s for "
                         "network %(network)s",
                         {'server': dhcp_server['id'],
                          'network': port['network_id']})
                # Add DHCP service binding in neutron DB.
                neutron_client.add_dhcp_service_binding(
                    network['id'], port['id'], dhcp_server['id'])
                # Update logical port for DHCP purpose.
                lswitch_id, lport_id = (
                    neutron_client.get_lswitch_and_lport_id(port['id']))
                nsxlib.logical_port.update(
                    lport_id, dhcp_server['id'],
                    attachment_type=nsx_constants.ATTACHMENT_DHCP)
                server_bindings[lswitch_id] = dhcp_server['id']
                LOG.info("Updated DHCP logical port %(port)s for "
                         "network %(network)s",
                         {'port': lport_id, 'network': port['network_id']})
            elif subnet['enable_dhcp']:
                # Store (mac, ip) binding of each compute port in a
                # DHCP-enabled subnet.
                lswitch_id = neutron_client.net_id_to_lswitch_id(network_id)
                bindings = port_bindings.get(lswitch_id, [])
                bindings.append((port['id'], port['mac_address'],
                                 fixed_ip['ip_address'],
                                 fixed_ip['subnet_id']))
                port_bindings[lswitch_id] = bindings
            break  # process only the first IPv4 address

    # Populate mac/IP bindings in each logical DHCP server.
    for lswitch_id, bindings in port_bindings.items():
        dhcp_server_id = server_bindings.get(lswitch_id)
        if not dhcp_server_id:
            continue
        for (port_id, mac, ip, subnet_id) in bindings:
            hostname = 'host-%s' % ip.replace('.', '-')
            options = {'option121': {'static_routes': [
                {'network': '%s' % cfg.CONF.nsx_v3.native_metadata_route,
                 'next_hop': ip}]}}
            subnet = neutron_client.get_subnet(subnet_id)
            binding = nsxlib.dhcp_server.create_binding(
                dhcp_server_id, mac, ip, hostname,
                cfg.CONF.nsx_v3.dhcp_lease_time, options,
                subnet.get('gateway_ip'))
            # Add DHCP static binding in neutron DB.
            neutron_client.add_dhcp_static_binding(
                port_id, subnet_id, ip, dhcp_server_id, binding['id'])
            LOG.info("Added DHCP binding (mac: %(mac)s, ip: %(ip)s) "
                     "for neutron port %(port)s",
                     {'mac': mac, 'ip': ip, 'port': port_id})