diff --git a/cluster_upgrade/handlers.py b/cluster_upgrade/handlers.py index 21faab6..22dd948 100644 --- a/cluster_upgrade/handlers.py +++ b/cluster_upgrade/handlers.py @@ -18,6 +18,7 @@ import copy import six from nailgun.api.v1.handlers import base +from nailgun import errors from nailgun import objects from nailgun.task import manager @@ -53,6 +54,13 @@ class ClusterUpgradeCloneHandler(base.BaseHandler): request_data = self.checked_data(cluster=orig_cluster) new_cluster = upgrade.UpgradeHelper.clone_cluster(orig_cluster, request_data) + valid = upgrade.UpgradeHelper.validate_network_roles( + orig_cluster, new_cluster, + ) + if not valid: + raise errors.InvalidData("Network changes during upgrade" + " is not supported.") + return new_cluster.to_dict() diff --git a/cluster_upgrade/objects/adapters.py b/cluster_upgrade/objects/adapters.py index be5a00d..0edf3ee 100644 --- a/cluster_upgrade/objects/adapters.py +++ b/cluster_upgrade/objects/adapters.py @@ -98,6 +98,9 @@ class NailgunClusterAdapter(object): def get_admin_network_group(self): return objects.NetworkGroup.get_admin_network_group() + def get_network_roles(self): + return objects.Cluster.get_network_roles(self.cluster) + class NailgunReleaseAdapter(object): def __init__(self, release): diff --git a/cluster_upgrade/upgrade.py b/cluster_upgrade/upgrade.py index 0b5bede..812a0a1 100644 --- a/cluster_upgrade/upgrade.py +++ b/cluster_upgrade/upgrade.py @@ -319,3 +319,25 @@ class UpgradeHelper(object): seed_ng_dict = dict((ng.name, ng.id) for ng in seed_ng) mapping = dict((ng.id, seed_ng_dict[ng.name]) for ng in orig_ng) return mapping + + @classmethod + def validate_network_roles(cls, orig_cluster, seed_cluster): + if not orig_cluster.network_template: + return cls._compare_releases_roles(orig_cluster, seed_cluster) + else: + # TODO network template case + return True + + @classmethod + def _compare_releases_roles(cls, orig_cluster, seed_cluster): + orig_roles = orig_cluster.get_network_roles() + new_roles = seed_cluster.get_network_roles() + + orig_mapping = cls._get_release_mapping(orig_roles) + new_mapping = cls._get_release_mapping(new_roles) + + return orig_mapping.issubset(new_mapping) + + @staticmethod + def _get_release_mapping(roles): + return {(role['id'], role['default_mapping']) for role in roles}