kuryr-kubernetes/kuryr_kubernetes/controller/drivers/multi_vif.py

118 lines
4.6 KiB
Python

# Copyright (c) 2018 RedHat, 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.
from oslo_log import log as logging
from oslo_serialization import jsonutils
from kuryr_kubernetes import clients
from kuryr_kubernetes import config as kuryr_config
from kuryr_kubernetes import constants
from kuryr_kubernetes.controller.drivers import base
from kuryr_kubernetes import exceptions
from kuryr_kubernetes import utils
LOG = logging.getLogger(__name__)
class NoopMultiVIFDriver(base.MultiVIFDriver):
def request_additional_vifs(
self, pod, project_id, security_groups):
return []
class NPWGMultiVIFDriver(base.MultiVIFDriver):
def __init__(self):
super(NPWGMultiVIFDriver, self).__init__()
self._drv_vif_pool = base.VIFPoolDriver.get_instance(
specific_driver='multi_pool')
self._drv_vif_pool.set_vif_driver()
def request_additional_vifs(self, pod, project_id, security_groups):
vifs = []
networks = self._get_networks(pod)
if not networks:
return vifs
kubernetes = clients.get_kubernetes_client()
namespace = pod['metadata']['namespace']
for network in networks:
if 'name' not in network:
raise exceptions.InvalidKuryrNetworkAnnotation()
if 'namespace' in network:
namespace = network['namespace']
try:
url = '%s/namespaces/%s/network-attachment-definitions/%s' % (
constants.K8S_API_NPWG_CRD, namespace, network['name'])
nad_obj = kubernetes.get(url)
except exceptions.K8sClientException:
LOG.exception("Kubernetes Client Exception")
raise
config = jsonutils.loads(nad_obj['metadata']['annotations']
['openstack.org/kuryr-config'])
subnet_id = config.get(constants.K8S_ANNOTATION_NPWG_CRD_SUBNET_ID)
neutron_defaults = kuryr_config.CONF.neutron_defaults
if constants.K8S_ANNOTATION_NPWG_CRD_DRIVER_TYPE not in config:
vif_drv = self._drv_vif_pool
if not subnet_id:
subnet_id = neutron_defaults.pod_subnet
else:
alias = config[constants.K8S_ANNOTATION_NPWG_CRD_DRIVER_TYPE]
vif_drv = base.PodVIFDriver.get_instance(
specific_driver=alias)
if not subnet_id:
try:
subnet_id = neutron_defaults.subnet_mapping[alias]
except KeyError:
subnet_id = neutron_defaults.pod_subnet
LOG.debug("Default subnet mapping in config file "
"doesn't contain any subnet for %s driver "
"alias. Default pod_subnet was used.", alias)
subnet = {subnet_id: utils.get_subnet(subnet_id)}
vif = vif_drv.request_vif(pod, project_id, subnet, security_groups)
if vif:
vifs.append(vif)
return vifs
def _get_networks(self, pod):
networks = []
try:
annotations = pod['metadata']['annotations']
key = constants.K8S_ANNOTATION_NPWG_NETWORK
networks_annotation = annotations[key]
except KeyError:
return []
try:
networks = jsonutils.loads(networks_annotation)
except ValueError:
# if annotation is not in json format, convert it to json.
net_list = networks_annotation.split(',')
for net in net_list:
net_details = net.split('/')
if len(net_details) == 1:
networks.append({'name': net_details[0]})
elif len(net_details) == 2:
networks.append(
{'namespace': net_details[0], 'name': net_details[1]}
)
else:
raise exceptions.InvalidKuryrNetworkAnnotation()
return networks