From c6f065afe707349b7514e761fab08a0f915990d7 Mon Sep 17 00:00:00 2001 From: Lanfon Fan Date: Mon, 13 Nov 2023 23:36:49 +0800 Subject: [PATCH] * [apiclient] fix for_version inherit bug and add unit test --- apiclient/harvester_api/api.py | 42 ++++++++++++------------ apiclient/harvester_api/managers/base.py | 12 +++++-- apiclient/tests/test_api.py | 11 +++++++ apiclient/tests/test_managers.py | 29 ++++++++++++++++ 4 files changed, 70 insertions(+), 24 deletions(-) diff --git a/apiclient/harvester_api/api.py b/apiclient/harvester_api/api.py index e141aa0e4..63acf667f 100644 --- a/apiclient/harvester_api/api.py +++ b/apiclient/harvester_api/api.py @@ -4,7 +4,7 @@ from pkg_resources import parse_version from requests.packages.urllib3.util.retry import Retry -from . import managers +from . import managers as mgrs from .managers.base import DEFAULT_NAMESPACE @@ -56,27 +56,27 @@ def cluster_version(self): def __repr__(self): return f"HarvesterAPI({self.endpoint!r}, {self.session.headers['Authorization']!r})" - def load_managers(self, target_version=""): - self.hosts = managers.HostManager(self, target_version) - self.keypairs = managers.KeypairManager(self, target_version) - self.images = managers.ImageManager(self, target_version) - self.networks = managers.NetworkManager(self, target_version) - self.volumes = managers.VolumeManager(self, target_version) - self.volsnapshots = managers.VolumeSnapshotManager(self, target_version) - self.templates = managers.TemplateManager(self, target_version) - self.supportbundle = managers.SupportBundleManager(self, target_version) - self.settings = managers.SettingManager(self, target_version) - self.clusternetworks = managers.ClusterNetworkManager(self, target_version) - self.vms = managers.VirtualMachineManager(self, target_version) - self.backups = managers.BackupManager(self, target_version) - self.vm_snapshots = managers.VirtualMachineSnapshotManager(self, target_version) - self.scs = managers.StorageClassManager(self, target_version) + def load_managers(self, version=""): + self.hosts = mgrs.HostManager.for_version(version)(self, version) + self.keypairs = mgrs.KeypairManager.for_version(version)(self, version) + self.images = mgrs.ImageManager.for_version(version)(self, version) + self.networks = mgrs.NetworkManager.for_version(version)(self, version) + self.volumes = mgrs.VolumeManager.for_version(version)(self, version) + self.volsnapshots = mgrs.VolumeSnapshotManager.for_version(version)(self, version) + self.templates = mgrs.TemplateManager.for_version(version)(self, version) + self.supportbundle = mgrs.SupportBundleManager.for_version(version)(self, version) + self.settings = mgrs.SettingManager.for_version(version)(self, version) + self.clusternetworks = mgrs.ClusterNetworkManager.for_version(version)(self, version) + self.vms = mgrs.VirtualMachineManager.for_version(version)(self, version) + self.backups = mgrs.BackupManager.for_version(version)(self, version) + self.vm_snapshots = mgrs.VirtualMachineSnapshotManager.for_version(version)(self, version) + self.scs = mgrs.StorageClassManager.for_version(version)(self, version) # not available in dashboard - self.versions = managers.VersionManager(self, target_version) - self.upgrades = managers.UpgradeManager(self, target_version) - self.lhreplicas = managers.LonghornReplicaManager(self, target_version) - self.lhvolumes = managers.LonghornVolumeManager(self, target_version) - self.lhbackupvolumes = managers.LonghornBackupVolumeManager(self, target_version) + self.versions = mgrs.VersionManager.for_version(version)(self, version) + self.upgrades = mgrs.UpgradeManager.for_version(version)(self, version) + self.lhreplicas = mgrs.LonghornReplicaManager.for_version(version)(self, version) + self.lhvolumes = mgrs.LonghornVolumeManager.for_version(version)(self, version) + self.lhbackupvolumes = mgrs.LonghornBackupVolumeManager.for_version(version)(self, version) def _get(self, path, **kwargs): url = self.get_url(path) diff --git a/apiclient/harvester_api/managers/base.py b/apiclient/harvester_api/managers/base.py index 28d3c7cf1..af0c67c96 100644 --- a/apiclient/harvester_api/managers/base.py +++ b/apiclient/harvester_api/managers/base.py @@ -16,6 +16,7 @@ def merge_dict(src, dest): class BaseManager: + _sub_classes = dict() support_to = "0.0.0" @classmethod @@ -24,12 +25,17 @@ def is_support(cls, target_version): @classmethod def for_version(cls, version): - for c in sorted(cls.__subclasses__(), reverse=True, - key=lambda x: parse_version(x.support_to).release): + for c in sorted(cls._sub_classes.get(cls, []), + reverse=True, key=lambda x: parse_version(x.support_to).release): if c.is_support(version): - return c.for_version(version) + return c return cls + def __init_subclass__(cls): + for parent in cls.__mro__: + if issubclass(parent, BaseManager): + cls._sub_classes.setdefault(parent, []).append(cls) + def __init__(self, api, target_version=""): self._api = ref(api) self._ver = target_version diff --git a/apiclient/tests/test_api.py b/apiclient/tests/test_api.py index dd007ff9c..949895803 100644 --- a/apiclient/tests/test_api.py +++ b/apiclient/tests/test_api.py @@ -70,6 +70,17 @@ def test_set_retries_customized(self): with self.subTest(attr=attr, val=val): self.assertEqual(getattr(retries, attr), val) + def test_load_managers(self): + default_ver, base_ver, new_ver = "", "0.0.0", "v1.1.0" + api = HarvesterAPI("https://endpoint") + + self.assertEqual(api.hosts.support_to, base_ver) + self.assertEqual(api.hosts._ver, default_ver) + + api.load_managers(new_ver) + self.assertTrue(api.hosts.is_support(new_ver)) + self.assertEqual(api.hosts._ver, new_ver) + def test_authenticate(self): user, pwd, token = "testuser", "testpasswd", "fake:token" post_json = dict(username=user, password=pwd) diff --git a/apiclient/tests/test_managers.py b/apiclient/tests/test_managers.py index c1a2b27b4..1b5e185d4 100644 --- a/apiclient/tests/test_managers.py +++ b/apiclient/tests/test_managers.py @@ -95,6 +95,35 @@ def test__update(self): self.assertDictEqual(dict(json=data), self.api._put.call_args[1]) + def test_for_version(self): + class B0(BaseManager): + pass + + class B103(B0): + support_to = '1.0.3' + + class B110(B0): + support_to = '1.1.0' + + class B120(B0): + support_to = '1.2.0' + + class B113(B120): + support_to = '1.1.3' + + class B130(B120): + support_to = '1.3.0' + + class B114(B130): + support_to = '1.1.4' + + self.assertEqual(B0.for_version('1.0.3'), B103) + self.assertEqual(B0.for_version('1.1.0'), B110) + self.assertEqual(B0.for_version('1.2.0'), B120) + self.assertEqual(B0.for_version('1.1.3'), B113) + self.assertEqual(B0.for_version('1.3.0'), B130) + self.assertEqual(B0.for_version('1.1.4'), B114) + class TestHostManager(BaseTestCase): manager_cls = HostManager