impuls/lib/python3.11/site-packages/os_win/utils/network/nvgreutils.py

173 lines
6.3 KiB
Python
Raw Normal View History

# Copyright 2015 Cloudbase Solutions SRL
# 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.
from oslo_log import log as logging
from os_win import constants
from os_win import exceptions
from os_win.utils import baseutils
from os_win.utils.network import networkutils
LOG = logging.getLogger(__name__)
class NvgreUtils(baseutils.BaseUtils):
_HYPERV_VIRT_ADAPTER = 'Hyper-V Virtual Ethernet Adapter'
_IPV4_ADDRESS_FAMILY = 2
_TRANSLATE_NAT = 0
_TRANSLATE_ENCAP = 1
_LOOKUP_RECORD_TYPE_STATIC = 0
_LOOKUP_RECORD_TYPE_L2_ONLY = 3
_STDCIMV2_NAMESPACE = '//./root/StandardCimv2'
def __init__(self):
super(NvgreUtils, self).__init__()
self._utils = networkutils.NetworkUtils()
self._net_if_indexes = {}
self._scimv2 = self._get_wmi_conn(moniker=self._STDCIMV2_NAMESPACE)
def create_provider_address(self, network_name, provider_vlan_id):
iface_index = self._get_network_iface_index(network_name)
(provider_addr, prefix_len) = self.get_network_iface_ip(network_name)
if not provider_addr:
# logging is already provided by get_network_iface_ip.
raise exceptions.NotFound(resource=network_name)
provider = (
self._scimv2.MSFT_NetVirtualizationProviderAddressSettingData(
ProviderAddress=provider_addr))
if provider:
if (provider[0].VlanID == provider_vlan_id and
provider[0].InterfaceIndex == iface_index):
# ProviderAddress already exists.
return
# ProviderAddress exists, but with different VlanID or iface index.
provider[0].Delete_()
self._create_new_object(
self._scimv2.MSFT_NetVirtualizationProviderAddressSettingData,
ProviderAddress=provider_addr,
VlanID=provider_vlan_id,
InterfaceIndex=iface_index,
PrefixLength=prefix_len)
def create_provider_route(self, network_name):
iface_index = self._get_network_iface_index(network_name)
routes = self._scimv2.MSFT_NetVirtualizationProviderRouteSettingData(
InterfaceIndex=iface_index, NextHop=constants.IPV4_DEFAULT)
if not routes:
self._create_new_object(
self._scimv2.MSFT_NetVirtualizationProviderRouteSettingData,
InterfaceIndex=iface_index,
DestinationPrefix='%s/0' % constants.IPV4_DEFAULT,
NextHop=constants.IPV4_DEFAULT)
def clear_customer_routes(self, vsid):
routes = self._scimv2.MSFT_NetVirtualizationCustomerRouteSettingData(
VirtualSubnetID=vsid)
for route in routes:
route.Delete_()
def create_customer_route(self, vsid, dest_prefix, next_hop, rdid_uuid):
self._create_new_object(
self._scimv2.MSFT_NetVirtualizationCustomerRouteSettingData,
VirtualSubnetID=vsid,
DestinationPrefix=dest_prefix,
NextHop=next_hop,
Metric=255,
RoutingDomainID='{%s}' % rdid_uuid)
def create_lookup_record(self, provider_addr, customer_addr, mac, vsid):
# check for existing entry.
lrec = self._scimv2.MSFT_NetVirtualizationLookupRecordSettingData(
CustomerAddress=customer_addr, VirtualSubnetID=vsid)
if (lrec and lrec[0].VirtualSubnetID == vsid and
lrec[0].ProviderAddress == provider_addr and
lrec[0].MACAddress == mac):
# lookup record already exists, nothing to do.
return
# create new lookup record.
if lrec:
lrec[0].Delete_()
if constants.IPV4_DEFAULT == customer_addr:
# customer address used for DHCP requests.
record_type = self._LOOKUP_RECORD_TYPE_L2_ONLY
else:
record_type = self._LOOKUP_RECORD_TYPE_STATIC
self._create_new_object(
self._scimv2.MSFT_NetVirtualizationLookupRecordSettingData,
VirtualSubnetID=vsid,
Rule=self._TRANSLATE_ENCAP,
Type=record_type,
MACAddress=mac,
CustomerAddress=customer_addr,
ProviderAddress=provider_addr)
def _create_new_object(self, object_class, **args):
new_obj = object_class.new(**args)
new_obj.Put_()
return new_obj
def _get_network_ifaces_by_name(self, network_name):
return [n for n in self._scimv2.MSFT_NetAdapter() if
n.Name.find(network_name) >= 0]
def _get_network_iface_index(self, network_name):
if self._net_if_indexes.get(network_name):
return self._net_if_indexes[network_name]
description = (
self._utils.get_vswitch_external_network_name(network_name))
# physical NIC and vswitch must have the same MAC address.
networks = self._scimv2.MSFT_NetAdapter(
InterfaceDescription=description)
if not networks:
raise exceptions.NotFound(resource=network_name)
self._net_if_indexes[network_name] = networks[0].InterfaceIndex
return networks[0].InterfaceIndex
def get_network_iface_ip(self, network_name):
networks = [n for n in self._get_network_ifaces_by_name(network_name)
if n.DriverDescription == self._HYPERV_VIRT_ADAPTER]
if not networks:
LOG.error('No vswitch was found with name: %s', network_name)
return None, None
ip_addr = self._scimv2.MSFT_NetIPAddress(
InterfaceIndex=networks[0].InterfaceIndex,
AddressFamily=self._IPV4_ADDRESS_FAMILY)
if not ip_addr:
LOG.error('No IP Address could be found for network: %s',
network_name)
return None, None
return ip_addr[0].IPAddress, ip_addr[0].PrefixLength