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

95 lines
3.6 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 oslo_serialization import jsonutils
from kuryr_kubernetes import clients
from kuryr_kubernetes import constants
from kuryr_kubernetes.controller.drivers import base as drivers
from kuryr_kubernetes.controller.drivers import utils as driver_utils
from kuryr_kubernetes.handlers import k8s_base
LOG = logging.getLogger(__name__)
class PodLabelHandler(k8s_base.ResourceEventHandler):
"""Controller side of Pod Label process for Kubernetes pods.
`PodLabelHandler` runs on the Kuryr-Kubernetes controller and is
responsible for triggering the vif port updates upon pod labels changes.
"""
OBJECT_KIND = constants.K8S_OBJ_POD
OBJECT_WATCH_PATH = "%s/%s" % (constants.K8S_API_BASE, "pods")
def __init__(self):
super(PodLabelHandler, self).__init__()
self._drv_project = drivers.PodProjectDriver.get_instance()
self._drv_sg = drivers.PodSecurityGroupsDriver.get_instance()
self._drv_vif_pool = drivers.VIFPoolDriver.get_instance(
specific_driver='multi_pool')
self._drv_vif_pool.set_vif_driver()
def on_present(self, pod):
if driver_utils.is_host_network(pod) or not self._has_pod_state(pod):
# NOTE(ltomasbo): The event will be retried once the vif handler
# annotates the pod with the pod state.
return
current_pod_labels = pod['metadata'].get('labels')
previous_pod_labels = self._get_pod_labels(pod)
LOG.debug("Got previous pod labels from annotation: %r",
previous_pod_labels)
if current_pod_labels == previous_pod_labels:
return
project_id = self._drv_project.get_project(pod)
security_groups = self._drv_sg.get_security_groups(pod, project_id)
self._drv_vif_pool.update_vif_sgs(pod, security_groups)
self._set_pod_labels(pod, current_pod_labels)
def _get_pod_labels(self, pod):
try:
annotations = pod['metadata']['annotations']
pod_labels_annotation = annotations[constants.K8S_ANNOTATION_LABEL]
except KeyError:
return None
pod_labels = jsonutils.loads(pod_labels_annotation)
return pod_labels
def _set_pod_labels(self, pod, labels):
if not labels:
LOG.debug("Removing Label annotation: %r", labels)
annotation = None
else:
annotation = jsonutils.dumps(labels, sort_keys=True)
LOG.debug("Setting Labels annotation: %r", annotation)
k8s = clients.get_kubernetes_client()
k8s.annotate(pod['metadata']['selfLink'],
{constants.K8S_ANNOTATION_LABEL: annotation},
resource_version=pod['metadata']['resourceVersion'])
def _has_pod_state(self, pod):
try:
pod_state = pod['metadata']['annotations'][
constants.K8S_ANNOTATION_VIF]
LOG.debug("Pod state is: %s", pod_state)
except KeyError:
return False
return True