You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
548 lines
20 KiB
548 lines
20 KiB
# Copyright 2013 VMware, Inc. |
|
# |
|
# All Rights Reserved. |
|
# |
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may |
|
# not use this file except in compliance with the License. You may obtain |
|
# a copy of the License at |
|
# |
|
# http://www.apache.org/licenses/LICENSE-2.0 |
|
# |
|
# Unless required by applicable law or agreed to in writing, software |
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
|
# License for the specific language governing permissions and limitations |
|
# under the License. |
|
|
|
import neutron.db.api as db |
|
from oslo_db import exception as db_exc |
|
from oslo_log import log as logging |
|
from oslo_utils import excutils |
|
import six |
|
from sqlalchemy.orm import exc |
|
from sqlalchemy.sql import expression as expr |
|
|
|
from neutron.i18n import _, _LE |
|
|
|
from vmware_nsx.common import exceptions as nsx_exc |
|
from vmware_nsx.common import nsxv_constants |
|
from vmware_nsx.db import nsxv_models |
|
from vmware_nsx.plugins.nsx_v.vshield.common import constants |
|
|
|
LOG = logging.getLogger(__name__) |
|
|
|
|
|
def _apply_filters_to_query(query, model, filters, like_filters=None): |
|
if filters: |
|
for key, value in six.iteritems(filters): |
|
column = getattr(model, key, None) |
|
if column: |
|
query = query.filter(column.in_(value)) |
|
if like_filters: |
|
for key, search_term in six.iteritems(like_filters): |
|
column = getattr(model, key, None) |
|
if column: |
|
query = query.filter(column.like(search_term)) |
|
return query |
|
|
|
|
|
def add_nsxv_router_binding(session, router_id, vse_id, lswitch_id, status, |
|
appliance_size=nsxv_constants.LARGE, |
|
edge_type=nsxv_constants.SERVICE_EDGE): |
|
with session.begin(subtransactions=True): |
|
binding = nsxv_models.NsxvRouterBinding( |
|
router_id=router_id, |
|
edge_id=vse_id, |
|
lswitch_id=lswitch_id, |
|
status=status, |
|
appliance_size=appliance_size, |
|
edge_type=edge_type) |
|
session.add(binding) |
|
return binding |
|
|
|
|
|
def get_nsxv_router_binding(session, router_id): |
|
return session.query(nsxv_models.NsxvRouterBinding).filter_by( |
|
router_id=router_id).first() |
|
|
|
|
|
def get_nsxv_router_binding_by_edge(session, edge_id): |
|
return session.query(nsxv_models.NsxvRouterBinding).filter_by( |
|
edge_id=edge_id).first() |
|
|
|
|
|
def get_nsxv_router_bindings_by_edge(session, edge_id): |
|
return session.query(nsxv_models.NsxvRouterBinding).filter_by( |
|
edge_id=edge_id).all() |
|
|
|
|
|
def get_nsxv_router_bindings(session, filters=None, |
|
like_filters=None): |
|
session = db.get_session() |
|
query = session.query(nsxv_models.NsxvRouterBinding) |
|
return _apply_filters_to_query(query, nsxv_models.NsxvRouterBinding, |
|
filters, like_filters).all() |
|
|
|
|
|
def update_nsxv_router_binding(session, router_id, **kwargs): |
|
with session.begin(subtransactions=True): |
|
binding = (session.query(nsxv_models.NsxvRouterBinding). |
|
filter_by(router_id=router_id).one()) |
|
for key, value in six.iteritems(kwargs): |
|
binding[key] = value |
|
return binding |
|
|
|
|
|
def delete_nsxv_router_binding(session, router_id): |
|
with session.begin(subtransactions=True): |
|
binding = (session.query(nsxv_models.NsxvRouterBinding). |
|
filter_by(router_id=router_id).first()) |
|
if binding: |
|
session.delete(binding) |
|
|
|
|
|
def get_edge_vnic_binding(session, edge_id, network_id): |
|
return session.query(nsxv_models.NsxvEdgeVnicBinding).filter_by( |
|
edge_id=edge_id, network_id=network_id).first() |
|
|
|
|
|
def get_edge_vnic_bindings_by_edge(session, edge_id): |
|
query = session.query(nsxv_models.NsxvEdgeVnicBinding) |
|
return query.filter( |
|
nsxv_models.NsxvEdgeVnicBinding.edge_id == edge_id, |
|
nsxv_models.NsxvEdgeVnicBinding.network_id != expr.null()).all() |
|
|
|
|
|
def get_edge_vnic_bindings_by_int_lswitch(session, lswitch_id): |
|
return session.query(nsxv_models.NsxvEdgeVnicBinding).filter_by( |
|
network_id=lswitch_id).all() |
|
|
|
|
|
def create_edge_vnic_binding(session, edge_id, vnic_index, |
|
network_id, tunnel_index=-1): |
|
with session.begin(subtransactions=True): |
|
binding = nsxv_models.NsxvEdgeVnicBinding( |
|
edge_id=edge_id, |
|
vnic_index=vnic_index, |
|
tunnel_index=tunnel_index, |
|
network_id=network_id) |
|
session.add(binding) |
|
return binding |
|
|
|
|
|
def delete_edge_vnic_binding_by_network(session, edge_id, network_id): |
|
with session.begin(subtransactions=True): |
|
binding = (session.query(nsxv_models.NsxvEdgeVnicBinding). |
|
filter_by(edge_id=edge_id, network_id=network_id).one()) |
|
session.delete(binding) |
|
|
|
|
|
def init_edge_vnic_binding(session, edge_id): |
|
"""Init edge vnic binding to preallocated 10 available edge vnics.""" |
|
|
|
with session.begin(subtransactions=True): |
|
for vnic_index in range(constants.MAX_VNIC_NUM)[1:]: |
|
start = (vnic_index - 1) * constants.MAX_TUNNEL_NUM |
|
stop = vnic_index * constants.MAX_TUNNEL_NUM |
|
for tunnel_index in range(start, stop): |
|
binding = nsxv_models.NsxvEdgeVnicBinding( |
|
edge_id=edge_id, |
|
vnic_index=vnic_index, |
|
tunnel_index=tunnel_index + 1) |
|
session.add(binding) |
|
|
|
|
|
def clean_edge_vnic_binding(session, edge_id): |
|
"""Clean edge vnic binding.""" |
|
|
|
with session.begin(subtransactions=True): |
|
(session.query(nsxv_models.NsxvEdgeVnicBinding). |
|
filter_by(edge_id=edge_id).delete()) |
|
|
|
|
|
def allocate_edge_vnic(session, edge_id, network_id): |
|
"""Allocate an avaliable edge vnic to network.""" |
|
|
|
with session.begin(subtransactions=True): |
|
bindings = (session.query(nsxv_models.NsxvEdgeVnicBinding). |
|
filter_by(edge_id=edge_id, network_id=None).all()) |
|
for binding in bindings: |
|
if binding['tunnel_index'] % constants.MAX_TUNNEL_NUM == 1: |
|
binding['network_id'] = network_id |
|
session.add(binding) |
|
return binding |
|
msg = (_("Failed to allocate one available vnic on edge_id: " |
|
":%(edge_id)s to network_id: %(network_id)s") % |
|
{'edge_id': edge_id, 'network_id': network_id}) |
|
LOG.exception(msg) |
|
raise nsx_exc.NsxPluginException(err_msg=msg) |
|
|
|
|
|
def allocate_edge_vnic_with_tunnel_index(session, edge_id, network_id): |
|
"""Allocate an avaliable edge vnic with tunnel index to network.""" |
|
|
|
# TODO(berlin): temporary solution to let metadata and dhcp use |
|
# different vnics |
|
net_list = get_nsxv_internal_network( |
|
session, constants.InternalEdgePurposes.INTER_EDGE_PURPOSE) |
|
metadata_net_id = net_list[0]['network_id'] if net_list else None |
|
|
|
with session.begin(subtransactions=True): |
|
query = session.query(nsxv_models.NsxvEdgeVnicBinding) |
|
query = query.filter( |
|
nsxv_models.NsxvEdgeVnicBinding.edge_id == edge_id, |
|
nsxv_models.NsxvEdgeVnicBinding.network_id == expr.null()) |
|
if metadata_net_id: |
|
vnic_binding = get_edge_vnic_binding( |
|
session, edge_id, metadata_net_id) |
|
if vnic_binding: |
|
vnic_index = vnic_binding.vnic_index |
|
query = query.filter( |
|
nsxv_models.NsxvEdgeVnicBinding.vnic_index != vnic_index) |
|
|
|
binding = query.first() |
|
if not binding: |
|
msg = (_("Failed to allocate one available vnic on edge_id: " |
|
":%(edge_id)s to network_id: %(network_id)s") % |
|
{'edge_id': edge_id, 'network_id': network_id}) |
|
LOG.exception(msg) |
|
raise nsx_exc.NsxPluginException(err_msg=msg) |
|
binding['network_id'] = network_id |
|
session.add(binding) |
|
session.flush() |
|
return binding |
|
|
|
|
|
def allocate_specific_edge_vnic(session, edge_id, vnic_index, |
|
tunnel_index, network_id): |
|
"""Allocate an specific edge vnic to network.""" |
|
|
|
with session.begin(subtransactions=True): |
|
binding = (session.query(nsxv_models.NsxvEdgeVnicBinding). |
|
filter_by(edge_id=edge_id, |
|
vnic_index=vnic_index, |
|
tunnel_index=tunnel_index).one()) |
|
binding['network_id'] = network_id |
|
session.add(binding) |
|
return binding |
|
|
|
|
|
def get_dhcp_edge_network_binding(session, network_id): |
|
with session.begin(subtransactions=True): |
|
dhcp_router_edges = [binding['edge_id'] |
|
for binding in get_nsxv_router_bindings(session) |
|
if binding['router_id'].startswith( |
|
constants.DHCP_EDGE_PREFIX)] |
|
bindings = (session.query(nsxv_models.NsxvEdgeVnicBinding). |
|
filter_by(network_id=network_id)) |
|
for binding in bindings: |
|
edge_id = binding['edge_id'] |
|
if edge_id in dhcp_router_edges: |
|
return binding |
|
|
|
|
|
def free_edge_vnic_by_network(session, edge_id, network_id): |
|
"""Free an edge vnic.""" |
|
|
|
with session.begin(subtransactions=True): |
|
binding = (session.query(nsxv_models.NsxvEdgeVnicBinding). |
|
filter_by(edge_id=edge_id, network_id=network_id).one()) |
|
binding['network_id'] = None |
|
session.add(binding) |
|
return binding |
|
|
|
|
|
def create_edge_dhcp_static_binding(session, edge_id, mac_address, binding_id): |
|
with session.begin(subtransactions=True): |
|
binding = nsxv_models.NsxvEdgeDhcpStaticBinding( |
|
edge_id=edge_id, |
|
mac_address=mac_address, |
|
binding_id=binding_id) |
|
session.add(binding) |
|
return binding |
|
|
|
|
|
def get_edge_dhcp_static_binding(session, edge_id, mac_address): |
|
return session.query(nsxv_models.NsxvEdgeDhcpStaticBinding).filter_by( |
|
edge_id=edge_id, mac_address=mac_address).first() |
|
|
|
|
|
def delete_edge_dhcp_static_binding(session, edge_id, mac_address): |
|
with session.begin(subtransactions=True): |
|
session.query(nsxv_models.NsxvEdgeDhcpStaticBinding).filter_by( |
|
edge_id=edge_id, mac_address=mac_address).delete() |
|
|
|
|
|
def clean_edge_dhcp_static_bindings_by_edge(session, edge_id): |
|
with session.begin(subtransactions=True): |
|
session.query(nsxv_models.NsxvEdgeDhcpStaticBinding).filter_by( |
|
edge_id=edge_id).delete() |
|
|
|
|
|
def create_nsxv_internal_network(session, network_purpose, network_id): |
|
with session.begin(subtransactions=True): |
|
try: |
|
network = nsxv_models.NsxvInternalNetworks( |
|
network_purpose=network_purpose, |
|
network_id=network_id) |
|
session.add(network) |
|
except db_exc.DBDuplicateEntry: |
|
with excutils.save_and_reraise_exception(): |
|
LOG.exception(_LE("Duplicate internal network for purpose %s"), |
|
network_purpose) |
|
|
|
|
|
def get_nsxv_internal_network(session, network_purpose): |
|
with session.begin(subtransactions=True): |
|
return (session.query(nsxv_models.NsxvInternalNetworks). |
|
filter_by(network_purpose=network_purpose).all()) |
|
|
|
|
|
def update_nsxv_internal_network(session, network_purpose, network_id): |
|
with session.begin(subtransactions=True): |
|
nets = get_nsxv_internal_network(session, network_purpose) |
|
for net in nets: |
|
net['network_id'] = network_id |
|
|
|
|
|
def delete_nsxv_internal_network(session, network_purpose): |
|
with session.begin(subtransactions=True): |
|
return (session.query(nsxv_models.NsxvInternalNetworks). |
|
filter_by(network_purpose=network_purpose).delete()) |
|
|
|
|
|
def create_nsxv_internal_edge(session, ext_ip_address, purpose, router_id): |
|
with session.begin(subtransactions=True): |
|
try: |
|
internal_edge = nsxv_models.NsxvInternalEdges( |
|
ext_ip_address=ext_ip_address, |
|
purpose=purpose, |
|
router_id=router_id) |
|
session.add(internal_edge) |
|
except db_exc.DBDuplicateEntry: |
|
with excutils.save_and_reraise_exception(): |
|
LOG.exception(_LE("Duplicate internal Edge IP %s"), |
|
ext_ip_address) |
|
|
|
|
|
def get_nsxv_internal_edge(session, ext_ip_address): |
|
with session.begin(subtransactions=True): |
|
return (session.query(nsxv_models.NsxvInternalEdges). |
|
filter_by(ext_ip_address=ext_ip_address).all()) |
|
|
|
|
|
def update_nsxv_internal_edge(session, ext_ip_address, router_id): |
|
with session.begin(subtransactions=True): |
|
edges = get_nsxv_internal_edge(session, ext_ip_address) |
|
|
|
for edge in edges: |
|
edge['router_id'] = router_id |
|
|
|
|
|
def get_nsxv_internal_edges_by_purpose(session, purpose): |
|
with session.begin(subtransactions=True): |
|
return (session.query(nsxv_models.NsxvInternalEdges). |
|
filter_by(purpose=purpose).all()) |
|
|
|
|
|
def delete_nsxv_internal_edge(session, ext_ip_address): |
|
with session.begin(subtransactions=True): |
|
return (session.query(nsxv_models.NsxvInternalEdges). |
|
filter_by(ext_ip_address=ext_ip_address).delete()) |
|
|
|
|
|
def add_neutron_nsx_section_mapping(session, neutron_id, ip_section_id): |
|
with session.begin(subtransactions=True): |
|
mapping = nsxv_models.NsxvSecurityGroupSectionMapping( |
|
neutron_id=neutron_id, ip_section_id=ip_section_id) |
|
session.add(mapping) |
|
return mapping |
|
|
|
|
|
def add_neutron_nsx_rule_mapping(session, neutron_id, nsx_rule_id): |
|
with session.begin(subtransactions=True): |
|
mapping = nsxv_models.NsxvRuleMapping(neutron_id=neutron_id, |
|
nsx_rule_id=nsx_rule_id) |
|
session.add(mapping) |
|
return mapping |
|
|
|
|
|
def add_neutron_nsx_port_vnic_mapping(session, neutron_id, nsx_id): |
|
with session.begin(subtransactions=True): |
|
mapping = nsxv_models.NsxvPortVnicMapping( |
|
neutron_id=neutron_id, nsx_id=nsx_id) |
|
session.add(mapping) |
|
return mapping |
|
|
|
|
|
def get_nsx_section(session, neutron_id): |
|
try: |
|
mapping = (session.query(nsxv_models.NsxvSecurityGroupSectionMapping). |
|
filter_by(neutron_id=neutron_id). |
|
one()) |
|
return mapping |
|
except exc.NoResultFound: |
|
LOG.debug("NSX identifiers for neutron security group %s not yet " |
|
"stored in Neutron DB", neutron_id) |
|
|
|
|
|
def get_nsx_rule_id(session, neutron_id): |
|
try: |
|
mapping = (session.query(nsxv_models.NsxvRuleMapping). |
|
filter_by(neutron_id=neutron_id). |
|
one()) |
|
return mapping['nsx_rule_id'] |
|
except exc.NoResultFound: |
|
LOG.debug("NSX identifiers for neutron rule %s not yet " |
|
"stored in Neutron DB", neutron_id) |
|
|
|
|
|
def get_nsx_vnic_id(session, neutron_id): |
|
try: |
|
mapping = (session.query(nsxv_models.NsxvPortVnicMapping). |
|
filter_by(neutron_id=neutron_id). |
|
one()) |
|
return mapping['nsx_id'] |
|
except exc.NoResultFound: |
|
LOG.debug("NSX identifiers for neutron port %s not yet " |
|
"stored in Neutron DB", neutron_id) |
|
|
|
|
|
def get_network_bindings(session, network_id): |
|
session = session or db.get_session() |
|
return (session.query(nsxv_models.NsxvTzNetworkBinding). |
|
filter_by(network_id=network_id). |
|
all()) |
|
|
|
|
|
def get_network_bindings_by_vlanid_and_physical_net(session, vlan_id, |
|
phy_uuid): |
|
session = session or db.get_session() |
|
return (session.query(nsxv_models.NsxvTzNetworkBinding). |
|
filter_by(vlan_id=vlan_id, phy_uuid=phy_uuid). |
|
all()) |
|
|
|
|
|
def delete_network_bindings(session, network_id): |
|
return (session.query(nsxv_models.NsxvTzNetworkBinding). |
|
filter_by(network_id=network_id).delete()) |
|
|
|
|
|
def add_network_binding(session, network_id, binding_type, phy_uuid, vlan_id): |
|
with session.begin(subtransactions=True): |
|
binding = nsxv_models.NsxvTzNetworkBinding(network_id, binding_type, |
|
phy_uuid, vlan_id) |
|
session.add(binding) |
|
return binding |
|
|
|
|
|
def get_network_bindings_by_vlanid(session, vlan_id): |
|
session = session or db.get_session() |
|
return (session.query(nsxv_models.NsxvTzNetworkBinding). |
|
filter_by(vlan_id=vlan_id). |
|
all()) |
|
|
|
|
|
# |
|
# Edge Firewall binding methods |
|
# |
|
def add_nsxv_edge_firewallrule_binding(session, map_info): |
|
with session.begin(subtransactions=True): |
|
binding = nsxv_models.NsxvEdgeFirewallRuleBinding( |
|
rule_id=map_info['rule_id'], |
|
rule_vseid=map_info['rule_vseid'], |
|
edge_id=map_info['edge_id']) |
|
session.add(binding) |
|
return binding |
|
|
|
|
|
def delete_nsxv_edge_firewallrule_binding(session, id): |
|
with session.begin(subtransactions=True): |
|
if not (session.query(nsxv_models.NsxvEdgeFirewallRuleBinding). |
|
filter_by(rule_id=id).delete()): |
|
msg = _("Rule Resource binding with id:%s not found!") % id |
|
raise nsx_exc.NsxPluginException(err_msg=msg) |
|
|
|
|
|
def get_nsxv_edge_firewallrule_binding(session, id, edge_id): |
|
with session.begin(subtransactions=True): |
|
return (session.query(nsxv_models.NsxvEdgeFirewallRuleBinding). |
|
filter_by(rule_id=id, edge_id=edge_id).first()) |
|
|
|
|
|
def get_nsxv_edge_firewallrule_binding_by_vseid( |
|
session, edge_id, rule_vseid): |
|
with session.begin(subtransactions=True): |
|
try: |
|
return (session.query(nsxv_models.NsxvEdgeFirewallRuleBinding). |
|
filter_by(edge_id=edge_id, rule_vseid=rule_vseid).one()) |
|
except exc.NoResultFound: |
|
msg = _("Rule Resource binding not found!") |
|
raise nsx_exc.NsxPluginException(err_msg=msg) |
|
|
|
|
|
def cleanup_nsxv_edge_firewallrule_binding(session, edge_id): |
|
with session.begin(subtransactions=True): |
|
session.query( |
|
nsxv_models.NsxvEdgeFirewallRuleBinding).filter_by( |
|
edge_id=edge_id).delete() |
|
|
|
|
|
def map_spoofguard_policy_for_network(session, network_id, policy_id): |
|
with session.begin(subtransactions=True): |
|
mapping = nsxv_models.NsxvSpoofGuardPolicyNetworkMapping( |
|
network_id=network_id, policy_id=policy_id) |
|
session.add(mapping) |
|
return mapping |
|
|
|
|
|
def get_spoofguard_policy_id(session, network_id): |
|
try: |
|
mapping = (session.query( |
|
nsxv_models.NsxvSpoofGuardPolicyNetworkMapping). |
|
filter_by(network_id=network_id).one()) |
|
return mapping['policy_id'] |
|
except exc.NoResultFound: |
|
LOG.debug("SpoofGuard Policy for network %s was not found", |
|
network_id) |
|
|
|
|
|
def add_vdr_dhcp_binding(session, vdr_router_id, dhcp_router_id, dhcp_edge_id): |
|
with session.begin(subtransactions=True): |
|
binding = nsxv_models.NsxvVdrDhcpBinding(vdr_router_id=vdr_router_id, |
|
dhcp_router_id=dhcp_router_id, |
|
dhcp_edge_id=dhcp_edge_id) |
|
session.add(binding) |
|
return binding |
|
|
|
|
|
def update_vdr_dhcp_binding(session, vdr_router_id, **kwargs): |
|
with session.begin(subtransactions=True): |
|
binding = (session.query(nsxv_models.NsxvVdrDhcpBinding). |
|
filter_by(vdr_router_id=vdr_router_id).one()) |
|
for key, value in six.iteritems(kwargs): |
|
binding[key] = value |
|
return binding |
|
|
|
|
|
def get_vdr_dhcp_bindings(session): |
|
try: |
|
bindings = session.query(nsxv_models.NsxvVdrDhcpBinding).all() |
|
return bindings |
|
except exc.NoResultFound: |
|
return None |
|
|
|
|
|
def get_vdr_dhcp_binding_by_vdr(session, vdr_router_id): |
|
try: |
|
binding = session.query( |
|
nsxv_models.NsxvVdrDhcpBinding).filter_by( |
|
vdr_router_id=vdr_router_id).one() |
|
return binding |
|
except exc.NoResultFound: |
|
return None |
|
|
|
|
|
def delete_vdr_dhcp_binding(session, vdr_router_id): |
|
return (session.query(nsxv_models.NsxvVdrDhcpBinding). |
|
filter_by(vdr_router_id=vdr_router_id).delete())
|
|
|