From b89542701112011f511b099fb62a566a400e9e1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Dulko?= Date: Fri, 20 Jul 2018 17:20:24 +0200 Subject: [PATCH] Fix compatiblity with old Pod annotation format We've changed Pod annotation format in Rocky. To support upgrading Kuryr we need to keep compatiblity with that format. This commit implements that. We should also think about creating a tool that will convert all the annotations in a setup. Change-Id: I88e1b318d58d0d90138e347503928da41518a888 Closes-Bug: 1782366 --- kuryr_kubernetes/cni/handlers.py | 4 ++-- kuryr_kubernetes/controller/handlers/vif.py | 13 +++++++------ kuryr_kubernetes/tests/unit/test_utils.py | 17 +++++++++++++++++ kuryr_kubernetes/utils.py | 19 +++++++++++++++++-- 4 files changed, 43 insertions(+), 10 deletions(-) diff --git a/kuryr_kubernetes/cni/handlers.py b/kuryr_kubernetes/cni/handlers.py index c4f439917..2a1c1dc11 100644 --- a/kuryr_kubernetes/cni/handlers.py +++ b/kuryr_kubernetes/cni/handlers.py @@ -24,6 +24,7 @@ from kuryr_kubernetes.cni.binding import base as b_base from kuryr_kubernetes import constants as k_const from kuryr_kubernetes.handlers import dispatch as k_dis from kuryr_kubernetes.handlers import k8s_base +from kuryr_kubernetes import utils LOG = logging.getLogger(__name__) @@ -75,8 +76,7 @@ class CNIHandlerBase(k8s_base.ResourceEventHandler): except KeyError: return {} state_annotation = jsonutils.loads(state_annotation) - state = obj_vif.base.VersionedObject.obj_from_primitive( - state_annotation) + state = utils.extract_pod_annotation(state_annotation) vifs_dict = state.vifs LOG.debug("Got VIFs from annotation: %r", vifs_dict) return vifs_dict diff --git a/kuryr_kubernetes/controller/handlers/vif.py b/kuryr_kubernetes/controller/handlers/vif.py index a22337c76..dbdc369a0 100644 --- a/kuryr_kubernetes/controller/handlers/vif.py +++ b/kuryr_kubernetes/controller/handlers/vif.py @@ -13,7 +13,6 @@ # License for the specific language governing permissions and limitations # under the License. -from os_vif.objects import base from oslo_log import log as logging from oslo_serialization import jsonutils @@ -23,6 +22,7 @@ from kuryr_kubernetes.controller.drivers import base as drivers from kuryr_kubernetes import exceptions as k_exc from kuryr_kubernetes.handlers import k8s_base from kuryr_kubernetes import objects +from kuryr_kubernetes import utils LOG = logging.getLogger(__name__) @@ -145,8 +145,11 @@ class VIFHandler(k8s_base.ResourceEventHandler): annotation = jsonutils.dumps(state_dict, sort_keys=True) LOG.debug("Setting VIFs annotation: %r", annotation) - # TODO(dulek): Here goes backward compatiblity code. Probably we can - # just ignore this case. + # NOTE(dulek): We don't care about compatiblity with Queens format + # here, as eventually all Kuryr services will be upgraded + # and cluster will start working normally. Meanwhile + # we just ignore issue of old services being unable to + # read new annotations. k8s = clients.get_kubernetes_client() k8s.annotate(pod['metadata']['selfLink'], @@ -160,9 +163,7 @@ class VIFHandler(k8s_base.ResourceEventHandler): state_annotation = annotations[constants.K8S_ANNOTATION_VIF] except KeyError: return None - state_annotation = jsonutils.loads(state_annotation) - state = base.VersionedObject.obj_from_primitive(state_annotation) - # TODO(dulek): Here goes backward compatibility code. + state = utils.extract_pod_annotation(state_annotation) LOG.debug("Got VIFs from annotation: %r", state) return state diff --git a/kuryr_kubernetes/tests/unit/test_utils.py b/kuryr_kubernetes/tests/unit/test_utils.py index b2cd5c94f..e1d91b69b 100644 --- a/kuryr_kubernetes/tests/unit/test_utils.py +++ b/kuryr_kubernetes/tests/unit/test_utils.py @@ -14,8 +14,10 @@ import mock import os +from os_vif import objects from oslo_config import cfg +from kuryr_kubernetes.objects import vif from kuryr_kubernetes.tests import base as test_base from kuryr_kubernetes.tests.unit import kuryr_fixtures as k_fix from kuryr_kubernetes import utils @@ -97,3 +99,18 @@ class TestUtils(test_base.TestCase): m_osv_subnet.assert_called_once_with(neutron_subnet) m_osv_network.assert_called_once_with(neutron_network) network.subnets.objects.append.assert_called_once_with(subnet) + + def test_extract_pod_annotation(self): + vif_obj = objects.vif.VIFBase() + ps = vif.PodState(default_vif=vif_obj) + d = ps.obj_to_primitive() + result = utils.extract_pod_annotation(d) + self.assertEqual(vif.PodState.obj_name(), result.obj_name()) + self.assertEqual(vif_obj, result.default_vif) + + def test_extract_pod_annotation_convert(self): + vif_obj = objects.vif.VIFBase() + d = vif_obj.obj_to_primitive() + result = utils.extract_pod_annotation(d) + self.assertEqual(vif.PodState.obj_name(), result.obj_name()) + self.assertEqual(vif_obj, result.default_vif) diff --git a/kuryr_kubernetes/utils.py b/kuryr_kubernetes/utils.py index 5a45b7fc6..6fd14a100 100644 --- a/kuryr_kubernetes/utils.py +++ b/kuryr_kubernetes/utils.py @@ -17,14 +17,17 @@ import time import requests +from os_vif import objects from oslo_cache import core as cache from oslo_config import cfg from oslo_log import log from oslo_serialization import jsonutils from kuryr_kubernetes import clients +from kuryr_kubernetes.objects import vif from kuryr_kubernetes import os_vif_util + CONF = cfg.CONF LOG = log.getLogger(__name__) @@ -37,8 +40,6 @@ VALID_MULTI_POD_POOLS_OPTS = {'noop': ['neutron-vif', DEFAULT_TIMEOUT = 180 DEFAULT_INTERVAL = 3 -CONF = cfg.CONF - subnet_caching_opts = [ cfg.BoolOpt('caching', default=True), cfg.IntOpt('cache_time', default=3600), @@ -157,3 +158,17 @@ def get_subnet(subnet_id): network.subnets.objects.append(subnet) return network + + +def extract_pod_annotation(annotation): + obj = objects.base.VersionedObject.obj_from_primitive(annotation) + # FIXME(dulek): This is code to maintain compatibility with Queens. We can + # remove it once we stop supporting upgrading from Queens, + # most likely in Stein. Note that this requires being sure + # that *all* the pod annotations are in new format. + if obj.obj_name() != vif.PodState.obj_name(): + # This is old format of annotations - single VIF object. We need to + # pack it in PodState object. + obj = vif.PodState(default_vif=obj) + + return obj