kuryr-kubernetes/kuryr_kubernetes/controller/handlers/namespace.py

124 lines
4.5 KiB
Python

# Copyright 2018 Red Hat, Inc.
#
# 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 kuryr_kubernetes import clients
from kuryr_kubernetes import constants
from kuryr_kubernetes.controller.drivers import base as drivers
from kuryr_kubernetes import exceptions
from kuryr_kubernetes.handlers import k8s_base
from kuryr_kubernetes import utils
LOG = logging.getLogger(__name__)
class NamespaceHandler(k8s_base.ResourceEventHandler):
OBJECT_KIND = constants.K8S_OBJ_NAMESPACE
OBJECT_WATCH_PATH = constants.K8S_API_NAMESPACES
def __init__(self):
super(NamespaceHandler, self).__init__()
self._drv_project = drivers.NamespaceProjectDriver.get_instance()
def on_present(self, namespace, *args, **kwargs):
ns_labels = namespace['metadata'].get('labels', {})
ns_name = namespace['metadata']['name']
kns_crd = self._get_kns_crd(ns_name)
if kns_crd:
LOG.debug("Previous CRD existing at the new namespace.")
self._update_labels(kns_crd, ns_labels)
return
try:
self._add_kuryrnetwork_crd(ns_name, ns_labels)
except exceptions.K8sClientException:
LOG.exception("Kuryrnetwork CRD creation failed.")
raise exceptions.ResourceNotReady(namespace)
def _update_labels(self, kns_crd, ns_labels):
kns_status = kns_crd.get('status')
if kns_status:
kns_crd_labels = kns_crd['status'].get('nsLabels', {})
if kns_crd_labels == ns_labels:
# Labels are already up to date, nothing to do
return
kubernetes = clients.get_kubernetes_client()
LOG.debug('Patching KuryrNetwork CRD %s', kns_crd)
try:
kubernetes.patch_crd('spec', utils.get_res_link(kns_crd),
{'nsLabels': ns_labels})
except exceptions.K8sResourceNotFound:
LOG.debug('KuryrNetwork CRD not found %s', kns_crd)
except exceptions.K8sClientException:
LOG.exception('Error updating kuryrnetwork CRD %s', kns_crd)
raise
def _get_kns_crd(self, namespace):
k8s = clients.get_kubernetes_client()
try:
kuryrnetwork_crd = k8s.get('{}/{}/kuryrnetworks/{}'.format(
constants.K8S_API_CRD_NAMESPACES, namespace,
namespace))
except exceptions.K8sResourceNotFound:
return None
except exceptions.K8sClientException:
LOG.exception("Kubernetes Client Exception.")
raise
return kuryrnetwork_crd
def _add_kuryrnetwork_crd(self, namespace, ns_labels):
project_id = self._drv_project.get_project(namespace)
kubernetes = clients.get_kubernetes_client()
kns_crd = {
'apiVersion': 'openstack.org/v1',
'kind': 'KuryrNetwork',
'metadata': {
'name': namespace,
'finalizers': [constants.KURYRNETWORK_FINALIZER],
},
'spec': {
'nsName': namespace,
'projectId': project_id,
'nsLabels': ns_labels,
}
}
try:
kubernetes.post('{}/{}/kuryrnetworks'.format(
constants.K8S_API_CRD_NAMESPACES, namespace), kns_crd)
except exceptions.K8sClientException:
LOG.exception("Kubernetes Client Exception creating kuryrnetwork "
"CRD.")
raise
def is_ready(self, quota):
if not (utils.has_kuryr_crd(constants.K8S_API_CRD_KURYRNETWORKS) and
self._check_quota(quota)):
LOG.error('Marking NamespaceHandler as not ready.')
return False
return True
def _check_quota(self, quota):
resources = ('subnets', 'networks', 'security_groups')
for resource in resources:
resource_quota = quota[resource]
if utils.has_limit(resource_quota):
if not utils.is_available(resource, resource_quota):
return False
return True