summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnastasiya <atolochkova@mirantis.com>2016-08-29 16:46:20 +0300
committerAnastasia Balobashina <atolochkova@mirantis.com>2016-09-15 11:00:28 +0000
commite2b9dbf1ca61b92c457722108eaf6dba95ac4f4b (patch)
tree0851e4450fdcd9897b355f5257cfaa547074b4e1
parent4136bc9aed6d766ea191d65a0b2b6e9898121d49 (diff)
Add initial support of multi-rack for upgrades
* netgroups mapping was changed (additional argument for the mapping was added - name of node group) * copying of node group during cluster cloning was added Depends-On: I2638279371e91f15090c782fc5fdbb434a2e85f8 Partial-bug: #1612297 Change-Id: Ib1689d7b6d673c0d78434dd047a7ebc520c232e7 Co-Authored-By: Ryan Moe <rmoe@mirantis.com> Co-Authored-By: Andrew Woodward <awoodward@mirantis.com> Co-Authored-By: Ilya Kharin <akscram@gmail.com>
Notes
Notes (review): Code-Review+1: Nikita Zubkov <nzubkov@mirantis.com> Code-Review+2: Ilya Kharin <akscram@gmail.com> Workflow+1: Ilya Kharin <akscram@gmail.com> Verified+2: Jenkins Submitted-by: Jenkins Submitted-at: Mon, 19 Sep 2016 08:23:01 +0000 Reviewed-on: https://review.openstack.org/362135 Project: openstack/fuel-nailgun-extension-cluster-upgrade Branch: refs/heads/master
-rw-r--r--cluster_upgrade/handlers.py7
-rw-r--r--cluster_upgrade/objects/adapters.py17
-rw-r--r--cluster_upgrade/tests/test_handlers.py3
-rw-r--r--cluster_upgrade/tests/test_transformations.py18
-rw-r--r--cluster_upgrade/tests/test_upgrade.py2
-rw-r--r--cluster_upgrade/transformations/vip.py10
-rw-r--r--cluster_upgrade/upgrade.py68
7 files changed, 87 insertions, 38 deletions
diff --git a/cluster_upgrade/handlers.py b/cluster_upgrade/handlers.py
index ac590c3..21faab6 100644
--- a/cluster_upgrade/handlers.py
+++ b/cluster_upgrade/handlers.py
@@ -140,11 +140,8 @@ class CopyVIPsHandler(base.BaseHandler):
140 self.checked_data(cluster=cluster, relation=relation) 140 self.checked_data(cluster=cluster, relation=relation)
141 141
142 # get original cluster object and create adapter with it 142 # get original cluster object and create adapter with it
143 orig_cluster_adapter = \ 143 orig_cluster_adapter = adapters.NailgunClusterAdapter.get_by_uid(
144 adapters.NailgunClusterAdapter( 144 relation.orig_cluster_id)
145 adapters.NailgunClusterAdapter.get_by_uid(
146 relation.orig_cluster_id)
147 )
148 145
149 seed_cluster_adapter = adapters.NailgunClusterAdapter(cluster) 146 seed_cluster_adapter = adapters.NailgunClusterAdapter(cluster)
150 147
diff --git a/cluster_upgrade/objects/adapters.py b/cluster_upgrade/objects/adapters.py
index d3b00e4..1adb27a 100644
--- a/cluster_upgrade/objects/adapters.py
+++ b/cluster_upgrade/objects/adapters.py
@@ -36,6 +36,10 @@ class NailgunClusterAdapter(object):
36 return self.cluster.name 36 return self.cluster.name
37 37
38 @property 38 @property
39 def node_groups(self):
40 return self.cluster.node_groups
41
42 @property
39 def net_provider(self): 43 def net_provider(self):
40 return self.cluster.net_provider 44 return self.cluster.net_provider
41 45
@@ -135,8 +139,9 @@ class NailgunNetworkManager(object):
135 def update(self, network_configuration): 139 def update(self, network_configuration):
136 self.net_manager.update(self.cluster, network_configuration) 140 self.net_manager.update(self.cluster, network_configuration)
137 141
138 def get_assigned_vips(self): 142 def get_assigned_vips(self, network_names=None):
139 return self.net_manager.get_assigned_vips(self.cluster) 143 return self.net_manager.get_assigned_vips(
144 self.cluster, network_names=network_names)
140 145
141 def assign_vips_for_net_groups(self): 146 def assign_vips_for_net_groups(self):
142 return self.net_manager.assign_vips_for_net_groups(self.cluster) 147 return self.net_manager.assign_vips_for_net_groups(self.cluster)
@@ -230,3 +235,11 @@ class NailgunNetworkGroupAdapter(object):
230 @property 235 @property
231 def name(self): 236 def name(self):
232 return self.network_group.name 237 return self.network_group.name
238
239 @property
240 def nodegroup(self):
241 return self.network_group.nodegroup
242
243 @classmethod
244 def get_by_uid(cls, ng_id):
245 return objects.NetworkGroup.get_by_uid(ng_id)
diff --git a/cluster_upgrade/tests/test_handlers.py b/cluster_upgrade/tests/test_handlers.py
index 71c5f05..d3eff0a 100644
--- a/cluster_upgrade/tests/test_handlers.py
+++ b/cluster_upgrade/tests/test_handlers.py
@@ -13,7 +13,6 @@
13# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14# License for the specific language governing permissions and limitations 14# License for the specific language governing permissions and limitations
15# under the License. 15# under the License.
16import unittest
17 16
18import mock 17import mock
19 18
@@ -227,7 +226,7 @@ class TestNodeReassignHandler(base.BaseIntegrationTest):
227 226
228 227
229class TestCopyVipsHandler(tests_base.BaseCloneClusterTest): 228class TestCopyVipsHandler(tests_base.BaseCloneClusterTest):
230 @unittest.skip("Skip test regarding vips") 229
231 def test_copy_vips(self): 230 def test_copy_vips(self):
232 node_db = self.env.create_node(cluster_id=self.src_cluster.id, 231 node_db = self.env.create_node(cluster_id=self.src_cluster.id,
233 roles=["controller"]) 232 roles=["controller"])
diff --git a/cluster_upgrade/tests/test_transformations.py b/cluster_upgrade/tests/test_transformations.py
index d192f28..f07abcb 100644
--- a/cluster_upgrade/tests/test_transformations.py
+++ b/cluster_upgrade/tests/test_transformations.py
@@ -10,7 +10,6 @@
10# License for the specific language governing permissions and limitations 10# License for the specific language governing permissions and limitations
11# under the License. 11# under the License.
12from distutils import version 12from distutils import version
13import unittest
14 13
15import mock 14import mock
16from nailgun.test import base as nailgun_test_base 15from nailgun.test import base as nailgun_test_base
@@ -249,33 +248,32 @@ class TestClusterTransformers(nailgun_test_base.BaseUnitTest):
249class TestVipTransformers(nailgun_test_base.BaseUnitTest): 248class TestVipTransformers(nailgun_test_base.BaseUnitTest):
250 def setUp(self): 249 def setUp(self):
251 ip = '0.0.0.0' 250 ip = '0.0.0.0'
252
253 self.data = { 251 self.data = {
254 'management': { 252 1: {
255 'haproxy': ip, 253 'haproxy': ip,
256 'vrouter': ip, 254 'vrouter': ip,
257 'test': ip, 255 'test': ip,
258 }, 256 },
259 'public': { 257 2: {
260 'haproxy': ip, 258 'haproxy': ip,
261 'vrouter': ip, 259 'vrouter': ip,
262 'test': ip, 260 'test': ip,
263 } 261 }
264 } 262 }
263 self.mapping = {1: 'management', 2: 'public'}
265 264
266 @unittest.skip("Skip test regarding vips")
267 def test_vip_transform(self): 265 def test_vip_transform(self):
268 ip = '0.0.0.0' 266 ip = '0.0.0.0'
269 267
270 data = vip.transform_vips(self.data) 268 data = vip.transform_vips((self.data, self.mapping))
271 self.assertEqual( 269 self.assertEqual(
272 data, { 270 data, ({
273 'management': { 271 1: {
274 'management': ip, 272 'management': ip,
275 'vrouter': ip, 273 'vrouter': ip,
276 }, 274 },
277 'public': { 275 2: {
278 'public': ip, 276 'public': ip,
279 'vrouter_pub': ip, 277 'vrouter_pub': ip,
280 }} 278 }}, {1: 'management', 2: 'public'})
281 ) 279 )
diff --git a/cluster_upgrade/tests/test_upgrade.py b/cluster_upgrade/tests/test_upgrade.py
index 56a8af8..3d03ec4 100644
--- a/cluster_upgrade/tests/test_upgrade.py
+++ b/cluster_upgrade/tests/test_upgrade.py
@@ -15,7 +15,6 @@
15# under the License. 15# under the License.
16 16
17import copy 17import copy
18import unittest
19 18
20import six 19import six
21 20
@@ -146,7 +145,6 @@ class TestUpgradeHelperCloneCluster(base_tests.BaseCloneClusterTest):
146 self.assertEqual(public_net['ip_ranges'], 145 self.assertEqual(public_net['ip_ranges'],
147 self.public_net_data['ip_ranges']) 146 self.public_net_data['ip_ranges'])
148 147
149 @unittest.skip("Skip test regarding vips")
150 def test_copy_vips(self): 148 def test_copy_vips(self):
151 # save network information before node reassignment to seed cluster 149 # save network information before node reassignment to seed cluster
152 # as after that no VIP will be allocated/serialized due to 150 # as after that no VIP will be allocated/serialized due to
diff --git a/cluster_upgrade/transformations/vip.py b/cluster_upgrade/transformations/vip.py
index 417b5f6..350cc0a 100644
--- a/cluster_upgrade/transformations/vip.py
+++ b/cluster_upgrade/transformations/vip.py
@@ -42,17 +42,17 @@ def transform_vips(data):
42 }, 42 },
43 } 43 }
44 renamed_vips = collections.defaultdict(dict) 44 renamed_vips = collections.defaultdict(dict)
45 for ng_name, vips_obj in data.items(): 45 vips, id_name_mapping = data
46 46 for ng_id, vips_obj in vips.items():
47 ng_vip_rules = rename_vip_rules[ng_name] 47 ng_vip_rules = rename_vip_rules[id_name_mapping[ng_id]]
48 for vip_name, vip_addr in vips_obj.items(): 48 for vip_name, vip_addr in vips_obj.items():
49 if vip_name not in ng_vip_rules: 49 if vip_name not in ng_vip_rules:
50 continue 50 continue
51 51
52 new_vip_name = ng_vip_rules[vip_name] 52 new_vip_name = ng_vip_rules[vip_name]
53 renamed_vips[ng_name][new_vip_name] = vip_addr 53 renamed_vips[ng_id][new_vip_name] = vip_addr
54 54
55 return renamed_vips 55 return renamed_vips, id_name_mapping
56 56
57 57
58class Manager(transformations.Manager): 58class Manager(transformations.Manager):
diff --git a/cluster_upgrade/upgrade.py b/cluster_upgrade/upgrade.py
index dde0606..2ade745 100644
--- a/cluster_upgrade/upgrade.py
+++ b/cluster_upgrade/upgrade.py
@@ -15,6 +15,8 @@
15# under the License. 15# under the License.
16 16
17import copy 17import copy
18
19import collections
18import six 20import six
19 21
20from nailgun import consts 22from nailgun import consts
@@ -47,13 +49,22 @@ def merge_attributes(a, b):
47 return attrs 49 return attrs
48 50
49 51
52def get_net_key(net):
53 group_name = None
54 if net["group_id"]:
55 group_name = objects.NodeGroup.get_by_uid(net["group_id"]).name
56 return (net["name"], group_name)
57
58
50def merge_nets(a, b): 59def merge_nets(a, b):
51 new_settings = copy.deepcopy(b) 60 new_settings = copy.deepcopy(b)
52 source_networks = dict((n["name"], n) for n in a["networks"]) 61 source_networks = dict((get_net_key(net), net) for net in a["networks"])
62
53 for net in new_settings["networks"]: 63 for net in new_settings["networks"]:
54 if net["name"] not in source_networks: 64 net_key = get_net_key(net)
65 if net_key not in source_networks:
55 continue 66 continue
56 source_net = source_networks[net["name"]] 67 source_net = source_networks[net_key]
57 for key, value in six.iteritems(net): 68 for key, value in six.iteritems(net):
58 if (key not in ("cluster_id", "id", "meta", "group_id") and 69 if (key not in ("cluster_id", "id", "meta", "group_id") and
59 key in source_net): 70 key in source_net):
@@ -84,6 +95,7 @@ class UpgradeHelper(object):
84 95
85 new_cluster = cls.create_cluster_clone(orig_cluster, data) 96 new_cluster = cls.create_cluster_clone(orig_cluster, data)
86 cls.copy_attributes(orig_cluster, new_cluster) 97 cls.copy_attributes(orig_cluster, new_cluster)
98 cls.copy_node_groups(orig_cluster, new_cluster)
87 cls.copy_network_config(orig_cluster, new_cluster) 99 cls.copy_network_config(orig_cluster, new_cluster)
88 relations.UpgradeRelationObject.create_relation(orig_cluster.id, 100 relations.UpgradeRelationObject.create_relation(orig_cluster.id,
89 new_cluster.id) 101 new_cluster.id)
@@ -125,6 +137,18 @@ class UpgradeHelper(object):
125 attrs['editable']['provision']['method']['value'] = 'image' 137 attrs['editable']['provision']['method']['value'] = 'image'
126 138
127 @classmethod 139 @classmethod
140 def copy_node_groups(cls, orig_cluster, new_cluster):
141 for ng in orig_cluster.node_groups:
142 if getattr(ng, 'is_default', False) or ng.name == 'default':
143 continue
144
145 data = {
146 'name': ng.name,
147 'cluster_id': new_cluster.id
148 }
149 objects.NodeGroup.create(data)
150
151 @classmethod
128 def copy_network_config(cls, orig_cluster, new_cluster): 152 def copy_network_config(cls, orig_cluster, new_cluster):
129 nets_serializer = cls.network_serializers[orig_cluster.net_provider] 153 nets_serializer = cls.network_serializers[orig_cluster.net_provider]
130 nets = merge_nets( 154 nets = merge_nets(
@@ -140,20 +164,38 @@ class UpgradeHelper(object):
140 orig_net_manager = orig_cluster.get_network_manager() 164 orig_net_manager = orig_cluster.get_network_manager()
141 new_net_manager = new_cluster.get_network_manager() 165 new_net_manager = new_cluster.get_network_manager()
142 166
143 vips = {} 167 vips = orig_net_manager.get_assigned_vips(
144 assigned_vips = orig_net_manager.get_assigned_vips() 168 network_names=(consts.NETWORKS.public, consts.NETWORKS.management))
145 for ng_name in (consts.NETWORKS.public, consts.NETWORKS.management):
146 vips[ng_name] = assigned_vips[ng_name]
147 169
148 vips = cls.vip_transformations.apply( 170 netgroups_id_mapping = cls.get_netgroups_id_mapping(orig_cluster,
171 new_cluster)
172 new_vips = cls.reassociate_vips(vips, netgroups_id_mapping)
173 id_name_vips_mapping = cls.get_id_name_vips_mapping(new_vips)
174 new_vips, id_name_vips_mapping = cls.vip_transformations.apply(
149 orig_cluster.release.environment_version, 175 orig_cluster.release.environment_version,
150 new_cluster.release.environment_version, 176 new_cluster.release.environment_version,
151 vips 177 (new_vips, id_name_vips_mapping),
152 ) 178 )
153 new_net_manager.assign_given_vips_for_net_groups(vips) 179 new_net_manager.assign_given_vips_for_net_groups(new_vips)
154 new_net_manager.assign_vips_for_net_groups() 180 new_net_manager.assign_vips_for_net_groups()
155 181
156 @classmethod 182 @classmethod
183 def reassociate_vips(cls, vips, netgroups_id_mapping):
184 new_vips = collections.defaultdict(dict)
185 for orig_net_id, net_vips in vips.items():
186 new_net_id = netgroups_id_mapping[orig_net_id]
187 new_vips[new_net_id] = net_vips
188 return new_vips
189
190 @classmethod
191 def get_id_name_vips_mapping(self, vips):
192 mapping = {}
193 for vip_id in vips:
194 mapping[vip_id] = \
195 adapters.NailgunNetworkGroupAdapter.get_by_uid(vip_id).name
196 return mapping
197
198 @classmethod
157 def get_node_roles(cls, reprovision, current_roles, given_roles): 199 def get_node_roles(cls, reprovision, current_roles, given_roles):
158 """Return roles depending on the reprovisioning status. 200 """Return roles depending on the reprovisioning status.
159 201
@@ -210,8 +252,10 @@ class UpgradeHelper(object):
210 orig_ng = orig_cluster.get_network_groups() 252 orig_ng = orig_cluster.get_network_groups()
211 seed_ng = seed_cluster.get_network_groups() 253 seed_ng = seed_cluster.get_network_groups()
212 254
213 seed_ng_dict = dict((ng.name, ng.id) for ng in seed_ng) 255 seed_ng_dict = dict(((ng.name, ng.nodegroup.name), ng.id)
214 mapping = dict((ng.id, seed_ng_dict[ng.name]) for ng in orig_ng) 256 for ng in seed_ng)
257 mapping = dict((ng.id, seed_ng_dict[(ng.name, ng.nodegroup.name)])
258 for ng in orig_ng)
215 mapping[orig_cluster.get_admin_network_group().id] = \ 259 mapping[orig_cluster.get_admin_network_group().id] = \
216 seed_cluster.get_admin_network_group().id 260 seed_cluster.get_admin_network_group().id
217 return mapping 261 return mapping