This is an automated email from the ASF dual-hosted git repository.
nvazquez pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cloudstack.git
The following commit(s) were added to refs/heads/main by this push:
new f572c7ab74 Gateways after Nic update on Shared Network tests (#6355)
f572c7ab74 is described below
commit f572c7ab74508366b3b2ccbb2c0e6eeaa872fd36
Author: dahn <[email protected]>
AuthorDate: Fri May 6 00:53:31 2022 +0200
Gateways after Nic update on Shared Network tests (#6355)
* initial code to set up test
* validations in marvin test
---
.../smoke/test_gateway_on_shared_networks.py | 241 +++++++++++++++++++++
tools/marvin/marvin/lib/base.py | 13 +-
2 files changed, 250 insertions(+), 4 deletions(-)
diff --git a/test/integration/smoke/test_gateway_on_shared_networks.py
b/test/integration/smoke/test_gateway_on_shared_networks.py
new file mode 100644
index 0000000000..dd2982f569
--- /dev/null
+++ b/test/integration/smoke/test_gateway_on_shared_networks.py
@@ -0,0 +1,241 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+
+#Import Local Modules
+from marvin.cloudstackAPI import *
+from marvin.cloudstackTestCase import cloudstackTestCase
+import unittest
+from marvin.lib.base import (NetworkOffering,
+ Network,
+ ServiceOffering,
+ VirtualMachine,
+ Template,
+ PublicIpRange,
+ NIC
+ )
+from marvin.lib.common import (get_domain,
+ get_zone,
+ get_template,
+ find_storage_pool_type,
+ get_builtin_template_info)
+from marvin.codes import (
+ PASS,
+ FAILED,
+ JOB_FAILED,
+ JOB_CANCELLED,
+ JOB_SUCCEEDED
+)
+from nose.plugins.attrib import attr
+import time
+
+
+class TestGatewayOnSharedNetwork(cloudstackTestCase):
+
+ @classmethod
+ def setUpClass(cls):
+ try:
+ testClient = super(TestGatewayOnSharedNetwork,
cls).getClsTestClient()
+ cls.apiclient = testClient.getApiClient()
+ cls.services = testClient.getParsedTestDataConfig()
+ cls._cleanup = []
+ # Get Zone, Domain and templates
+ cls.domain = get_domain(cls.apiclient)
+ cls.zone = get_zone(cls.apiclient, testClient.getZoneForTests())
+ cls.services['mode'] = cls.zone.networktype
+ cls.hypervisor = testClient.getHypervisorInfo()
+
+ cls.service_offering = ServiceOffering.create(
+ cls.apiclient,
+ cls.services["service_offering"]
+ )
+ cls._cleanup.append(cls.service_offering)
+
+ builtin_info = get_builtin_template_info(cls.apiclient,
cls.zone.id)
+ cls.services["template"]["url"] = builtin_info[0]
+ cls.services["template"]["hypervisor"] = builtin_info[1]
+ cls.services["template"]["format"] = builtin_info[2]
+
+ cls.template = get_template(
+ cls.apiclient,
+ cls.zone.id
+ )
+
+ # # Register new template
+ # cls.template = Template.register(
+ # cls.apiclient,
+ # cls.services["template"],
+ # zoneid=cls.zone.id,
+ # hypervisor=cls.hypervisor
+ # )
+ # cls._cleanup.append(cls.template)
+
+ cls.services["shared_network_offering"]["specifyVlan"] = "True"
+ cls.services["shared_network_offering"]["specifyIpRanges"] = "True"
+ cls.shared_network_offering = NetworkOffering.create(
+ cls.apiclient,
+ cls.services["shared_network_offering"],
+ conservemode=False
+ )
+ cls._cleanup.append(cls.shared_network_offering)
+ NetworkOffering.update(
+ cls.shared_network_offering,
+ cls.apiclient,
+ id=cls.shared_network_offering.id,
+ state="enabled"
+ )
+
+ except Exception as e:
+ cls.tearDownClass()
+ raise unittest.SkipTest("Exception in setUpClass: %s" % e)
+
+
+ @classmethod
+ def tearDownClass(cls):
+ cls.debug(f"tearing down TestGatewayOnSharedNetwork")
+ super(TestGatewayOnSharedNetwork, cls).tearDownClass()
+
+ def setUp(self):
+ self.cleanup = []
+
+ def tearDown(self):
+ self.debug(f"tearing down test in TestGatewayOnSharedNetwork")
+ super(TestGatewayOnSharedNetwork, self).tearDown()
+
+ @attr(tags=["advanced", "advancedns"], required_hardware="false")
+ def test_updating_nics_on_two_shared_networks(self):
+ """
+ Test updating vm nics on two shared networks
+ Works as follows:
+ - Create two shared networks, with different IP ranges (eg network1,
network2).
+ - Create two VMs on each shared network (eg vm1 on network1, vm2 on
network2) and stop them.
+ - Add additional IP range to each shared network. The two additional
IP ranges have same start IP and end IP,
+ but different gateway and netmask (eg network1-iprange2,
network2-iprange2).
+ - Update IP address of the two vms, by specifying new IP address on
additional IP ranges. The new gateway and
+ netmask should be updated correctly (eg vm1 on network1-iprange2,
vm2 on network2-iprange2).
+ """
+ # - Create two shared networks, with different IP ranges (eg network1,
network2).
+ self.services["shared_network"]["netmask"] = "255.255.255.0"
+ self.services["shared_network"]["gateway"] = "192.168.1.1"
+ self.services["shared_network"]["startip"] = "192.168.1.2"
+ self.services["shared_network"]["endip"] = "192.168.1.20"
+ self.services["shared_network"]["vlan"] = "111"
+ testnet = self.services["shared_network"]
+ self.debug(f"========= network 1 : {testnet}")
+
+ self.network1 = Network.create(
+ self.apiclient,
+ self.services["shared_network"],
+ networkofferingid=self.shared_network_offering.id,
+ zoneid=self.zone.id,
+ )
+ self._cleanup.append(self.network1)
+
+ self.services["shared_network"]["netmask"] = "255.255.255.0"
+ self.services["shared_network"]["gateway"] = "192.168.2.1"
+ self.services["shared_network"]["startip"] = "192.168.2.2"
+ self.services["shared_network"]["endip"] = "192.168.2.20"
+ self.services["shared_network"]["vlan"] = "222"
+ self.network2 = Network.create(
+ self.apiclient,
+ self.services["shared_network"],
+ networkofferingid=self.shared_network_offering.id,
+ zoneid=self.zone.id,
+ )
+ self._cleanup.append(self.network2)
+
+ # - Create two VMs on each shared network (eg vm1 on network1, vm2 on
network2) and stop them.
+ vm_data = self.services["virtual_machine"]
+ self.debug(f"============virtual machine data : {vm_data}")
+ virtual_machine1 = VirtualMachine.create(
+ self.apiclient,
+ self.services["virtual_machine"],
+ templateid=self.template.id,
+ serviceofferingid=self.service_offering.id,
+ networkids=[self.network1.id],
+ zoneid=self.zone.id
+ )
+ self.cleanup.append(virtual_machine1)
+ virtual_machine1.stop(self.apiclient)
+ virtual_machine2 = VirtualMachine.create(
+ self.apiclient,
+ self.services["virtual_machine"],
+ templateid=self.template.id,
+ serviceofferingid=self.service_offering.id,
+ networkids=[self.network2.id],
+ zoneid=self.zone.id
+ )
+ self.cleanup.append(virtual_machine2)
+ virtual_machine2.stop(self.apiclient)
+ # - Add additional IP range to each shared network. The two additional
IP ranges have same start IP and end IP,
+ # but different gateway and netmask (eg network1-iprange2,
network2-iprange2).
+ self.services["vlan_ip_range"]["netmask"] = "255.255.255.224"
+ self.services["vlan_ip_range"]["gateway"] = "192.168.3.1"
+ self.services["vlan_ip_range"]["startip"] = "192.168.3.2"
+ self.services["vlan_ip_range"]["endip"] = "192.168.3.20"
+ self.services["vlan_ip_range"]["vlan"] = "111"
+ range1 = PublicIpRange.create(self.apiclient,
self.services["vlan_ip_range"], networkid=self.network1.id)
+ self.debug(f"============range 1 : {range1}")
+
+ self.services["vlan_ip_range"]["netmask"] = "255.255.255.192"
+ self.services["vlan_ip_range"]["gateway"] = "192.168.3.21"
+ self.services["vlan_ip_range"]["startip"] = "192.168.3.2"
+ self.services["vlan_ip_range"]["endip"] = "192.168.3.20"
+ self.services["vlan_ip_range"]["vlan"] = "222"
+ range2 = PublicIpRange.create(self.apiclient,
self.services["vlan_ip_range"], networkid=self.network2.id)
+
+ # - Update IP address of the two vms, by specifying new IP address on
additional IP ranges. The new gateway and
+ # netmask should be updated correctly (eg vm1 on network1-iprange2,
vm2 on network2-iprange2).
+ nic1id = NIC.list(self.apiclient,
virtualmachineid=virtual_machine1.id, networkid=self.network1.id)[0].id
+ NIC.updateIp(self.apiclient, id=nic1id, ipaddress="192.168.3.2")
+ nics = NIC.list(self.apiclient, virtualmachineid=virtual_machine1.id,
networkid=self.network1.id)
+ self.check_nic(nics, self.network1, range1)
+
+ nic2id = NIC.list(self.apiclient,
virtualmachineid=virtual_machine2.id, networkid=self.network2.id)[0].id
+ NIC.updateIp(self.apiclient, id=nic2id, ipaddress="192.168.3.2")
+ nics = NIC.list(self.apiclient, virtualmachineid=virtual_machine2.id,
networkid=self.network2.id)
+ self.check_nic(nics, self.network2, range2)
+
+
+ return
+
+ def check_nic(self, nics, network, range):
+ # network = Network.list(self.apiclient, id=network_obj.id)[0]
+ self.assertEqual(
+ len(nics),
+ 1,
+ "VM should have only one nic"
+ )
+ self.assertNotEqual(
+ nics[0].netmask,
+ network.netmask,
+ "netmask is from the primary range of the network"
+ )
+ self.assertNotEqual(
+ nics[0].gateway,
+ network.gateway,
+ "gateway is from the primary range of the network"
+ )
+ self.assertEqual(
+ nics[0].netmask,
+ range.vlan.netmask,
+ f"netmask should be from the extra range {range}, of network
{network}."
+ )
+ self.assertEqual(
+ nics[0].gateway,
+ range.vlan.gateway,
+ f"gateway should be from the extra range {range}, of network
{network}."
+ )
diff --git a/tools/marvin/marvin/lib/base.py b/tools/marvin/marvin/lib/base.py
index 274b8b9252..5b38c65501 100755
--- a/tools/marvin/marvin/lib/base.py
+++ b/tools/marvin/marvin/lib/base.py
@@ -3627,7 +3627,7 @@ class PublicIpRange:
self.__dict__.update(items)
@classmethod
- def create(cls, apiclient, services, account=None, domainid=None,
forsystemvms=None):
+ def create(cls, apiclient, services, account=None, domainid=None,
forsystemvms=None, networkid=None):
"""Create VlanIpRange"""
cmd = createVlanIpRange.createVlanIpRangeCmd()
@@ -3635,15 +3635,18 @@ class PublicIpRange:
cmd.gateway = services["gateway"]
if "netmask" in services:
cmd.netmask = services["netmask"]
- cmd.forvirtualnetwork = services["forvirtualnetwork"]
+ if "forvirtualnetwork" in services:
+ cmd.forvirtualnetwork = services["forvirtualnetwork"]
if "startip" in services:
cmd.startip = services["startip"]
if "endip" in services:
cmd.endip = services["endip"]
- cmd.zoneid = services["zoneid"]
+ if "zoneid" in services:
+ cmd.zoneid = services["zoneid"]
if "podid" in services:
cmd.podid = services["podid"]
- cmd.vlan = services["vlan"]
+ if "vlan" in services:
+ cmd.vlan = services["vlan"]
if "ip6gateway" in services:
cmd.ip6gateway = services["ip6gateway"]
if "ip6cidr" in services:
@@ -3655,6 +3658,8 @@ class PublicIpRange:
cmd.domainid = domainid
if forsystemvms:
cmd.forsystemvms = forsystemvms
+ if networkid:
+ cmd.networkid = networkid
return PublicIpRange(apiclient.createVlanIpRange(cmd).__dict__)