cloudstack/test/integration/component/test_acquire_specified_public_ip.py
Rakesh 482e7ebf9a New feature: Acquire specific public IP for network (#3775)
Currently in cloudstack, when we click on "Acquire New Ip", it will
randomly acquire IP from the pool. With this enhancement, it is
possible to select the IP from the drop down IP list of that network.
Same thing applies for a VPC as well.
2019-12-24 10:08:53 +01:00

487 lines
18 KiB
Python

# 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.
"""
Tests of acquiring a specified public IP for isolated network or vpc
"""
# Import Local Modules
from nose.plugins.attrib import attr
from marvin.cloudstackTestCase import cloudstackTestCase, unittest
from marvin.cloudstackAPI import createVlanIpRange
from marvin.lib.utils import (validateList,
cleanup_resources)
from marvin.lib.base import (Account,
Domain,
Configurations,
VirtualMachine,
ServiceOffering,
VpcOffering,
Zone,
Network,
VPC,
PublicIPAddress,
PublicIpRange)
from marvin.lib.common import (get_domain,
get_zone,
get_free_vlan,
get_template)
import logging
import random
class TestAcquireSpecifiedPublicIp(cloudstackTestCase):
@classmethod
def setUpClass(cls):
cls.testClient = super(
TestAcquireSpecifiedPublicIp,
cls).getClsTestClient()
cls.apiclient = cls.testClient.getApiClient()
cls.services = cls.testClient.getParsedTestDataConfig()
zone = get_zone(cls.apiclient, cls.testClient.getZoneForTests())
cls.zone = Zone(zone.__dict__)
cls.template = get_template(cls.apiclient, cls.zone.id)
cls._cleanup = []
if str(cls.zone.securitygroupsenabled) == "True":
sys.exit(1)
cls.logger = logging.getLogger("TestAcquireSpecifiedPublicIp")
cls.stream_handler = logging.StreamHandler()
cls.logger.setLevel(logging.DEBUG)
cls.logger.addHandler(cls.stream_handler)
# Get Zone, Domain and templates
cls.domain = get_domain(cls.apiclient)
# Create new domain1
cls.domain1 = Domain.create(
cls.apiclient,
services=cls.services["acl"]["domain1"],
parentdomainid=cls.domain.id)
# Create account1
cls.account1 = Account.create(
cls.apiclient,
cls.services["acl"]["accountD1"],
domainid=cls.domain1.id
)
# Create domain2
cls.domain2 = Domain.create(
cls.apiclient,
services=cls.services["acl"]["domain2"],
parentdomainid=cls.domain.id)
# Create account2
cls.account2 = Account.create(
cls.apiclient,
cls.services["acl"]["accountD2"],
domainid=cls.domain2.id
)
cls.services["publiciprange"]["zoneid"] = cls.zone.id
cls.services["publiciprange"]["forvirtualnetwork"] = "true"
# Create public ip range 1
cls.services["publiciprange"]["vlan"] = get_free_vlan(
cls.apiclient,
cls.zone.id)[1]
random_subnet_number = random.randrange(10,20)
cls.services["publiciprange"]["gateway"] = "172.16." + \
str(random_subnet_number) + ".1"
cls.services["publiciprange"]["startip"] = "172.16." + \
str(random_subnet_number) + ".2"
cls.services["publiciprange"]["endip"] = "172.16." + \
str(random_subnet_number) + ".10"
cls.services["publiciprange"]["netmask"] = "255.255.255.0"
cls.public_ip_range1 = PublicIpRange.create(
cls.apiclient,
cls.services["publiciprange"]
)
PublicIpRange.dedicate(
cls.apiclient,
cls.public_ip_range1.vlan.id,
domainid=cls.account1.domainid
)
# Create public ip range 2
cls.services["publiciprange"]["vlan"] = get_free_vlan(
cls.apiclient,
cls.zone.id)[1]
cls.services["publiciprange"]["gateway"] = "172.16." + \
str(random_subnet_number + 1) + ".1"
cls.services["publiciprange"]["startip"] = "172.16." + \
str(random_subnet_number + 1) + ".2"
cls.services["publiciprange"]["endip"] = "172.16." + \
str(random_subnet_number + 1) + ".10"
cls.services["publiciprange"]["netmask"] = "255.255.255.0"
cls.public_ip_range2 = PublicIpRange.create(
cls.apiclient,
cls.services["publiciprange"]
)
PublicIpRange.dedicate(
cls.apiclient,
cls.public_ip_range2.vlan.id,
account=cls.account1.name,
domainid=cls.account1.domainid
)
# Create public ip range 3
cls.services["publiciprange"]["vlan"] = get_free_vlan(
cls.apiclient,
cls.zone.id)[1]
cls.services["publiciprange"]["gateway"] = "172.16." + \
str(random_subnet_number + 2) + ".1"
cls.services["publiciprange"]["startip"] = "172.16." + \
str(random_subnet_number + 2) + ".2"
cls.services["publiciprange"]["endip"] = "172.16." + \
str(random_subnet_number + 2) + ".10"
cls.services["publiciprange"]["netmask"] = "255.255.255.0"
cls.public_ip_range3 = PublicIpRange.create(
cls.apiclient,
cls.services["publiciprange"]
)
PublicIpRange.dedicate(
cls.apiclient,
cls.public_ip_range3.vlan.id,
domainid=cls.account2.domainid
)
# Create public ip range 4
cls.services["publiciprange"]["vlan"] = get_free_vlan(
cls.apiclient,
cls.zone.id)[1]
cls.services["publiciprange"]["gateway"] = "172.16." + \
str(random_subnet_number + 3) + ".1"
cls.services["publiciprange"]["startip"] = "172.16." + \
str(random_subnet_number + 3) + ".2"
cls.services["publiciprange"]["endip"] = "172.16." + \
str(random_subnet_number + 3) + ".10"
cls.services["publiciprange"]["netmask"] = "255.255.255.0"
cls.public_ip_range4 = PublicIpRange.create(
cls.apiclient,
cls.services["publiciprange"]
)
PublicIpRange.dedicate(
cls.apiclient,
cls.public_ip_range4.vlan.id,
account=cls.account2.name,
domainid=cls.account2.domainid
)
# Create public ip range 5
cls.services["publiciprange"]["vlan"] = get_free_vlan(
cls.apiclient,
cls.zone.id)[1]
cls.services["publiciprange"]["gateway"] = "172.16." + \
str(random_subnet_number + 4) + ".1"
cls.services["publiciprange"]["startip"] = "172.16." + \
str(random_subnet_number + 4) + ".2"
cls.services["publiciprange"]["endip"] = "172.16." + \
str(random_subnet_number + 4) + ".10"
cls.services["publiciprange"]["netmask"] = "255.255.255.0"
cls.public_ip_range5 = PublicIpRange.create(
cls.apiclient,
cls.services["publiciprange"]
)
cls._cleanup.append(cls.account1)
cls._cleanup.append(cls.domain1)
cls._cleanup.append(cls.account2)
cls._cleanup.append(cls.domain2)
cls._cleanup.append(cls.public_ip_range1)
cls._cleanup.append(cls.public_ip_range2)
cls._cleanup.append(cls.public_ip_range3)
cls._cleanup.append(cls.public_ip_range4)
cls._cleanup.append(cls.public_ip_range5)
@classmethod
def tearDownClass(cls):
try:
cleanup_resources(cls.apiclient, cls._cleanup)
except Exception as e:
raise Exception("Warning: Exception during cleanup : %s" % e)
return
def setUp(cls):
cls.apiclient = cls.testClient.getApiClient()
cls.cleanup = []
return
def tearDown(cls):
try:
cleanup_resources(cls.apiclient, cls.cleanup)
except Exception as e:
raise Exception("Warning: Exception during cleanup : %s" % e)
return
@attr(tags=["advanced"], required_hardware="false")
def test_01_acquire_public_ip_in_isolated_network(self):
# Validate the following
# 1. create a vm . it will create a network as well.
# 2. assign a specified IP from subnet which is dedicated to domain1, it should succeed
# 3. assign a specified IP from subnet which is dedicated to domain1/account1, it should succeed
# 4. assign a specified IP from subnet which is dedicated to domain2, it should fail
# 5. assign a specified IP from subnet which is dedicated to domain2/account2, it should fail
# 6. update account setting use.system.public.ips to false, assign a specified IP from subnet which is public, it should fail
# 7. update account setting use.system.public.ips to true, assign a specified IP from subnet which is public, it should succeed
self.service_offering = ServiceOffering.create(
self.apiclient,
self.services["service_offering"]
)
self.cleanup.append(self.service_offering)
self.virtual_machine = VirtualMachine.create(
self.apiclient,
self.services["small"],
templateid=self.template.id,
accountid=self.account1.name,
domainid=self.account1.domainid,
serviceofferingid=self.service_offering.id,
zoneid=self.zone.id
)
networks = Network.list(
self.apiclient,
account=self.account1.name,
domainid=self.account1.domainid,
listall=True
)
self.assertEqual(
isinstance(networks, list),
True,
"List networks should return a valid response for created network"
)
network = networks[0]
# Associate IP in range dedicated to domain1
ip_address_1 = self.get_free_ipaddress(self.public_ip_range1.vlan.id)
ipaddress = PublicIPAddress.create(
self.apiclient,
zoneid=self.zone.id,
networkid=network.id,
ipaddress=ip_address_1
)
self.assertIsNotNone(
ipaddress,
"Failed to Associate IP Address"
)
self.cleanup.append(ipaddress)
self.assertEqual(ipaddress.ipaddress.ipaddress, ip_address_1, "Associated IP is not same as specified")
# Associate IP in range dedicated to domain1/account1
ip_address_2 = self.get_free_ipaddress(self.public_ip_range2.vlan.id)
ipaddress = PublicIPAddress.create(
self.apiclient,
zoneid=self.zone.id,
networkid=network.id,
ipaddress=ip_address_2
)
self.assertIsNotNone(
ipaddress,
"Failed to Associate IP Address"
)
self.cleanup.append(ipaddress)
self.assertEqual(ipaddress.ipaddress.ipaddress, ip_address_2, "Associated IP is not same as specified")
# Associate IP in range dedicated to domain2
ip_address_3 = self.get_free_ipaddress(self.public_ip_range3.vlan.id)
with self.assertRaises(Exception):
ipaddress = PublicIPAddress.create(
self.apiclient,
zoneid=self.zone.id,
networkid=network.id,
ipaddress=ip_address_3
)
# Associate IP in range dedicated to domain2/account2
ip_address_4 = self.get_free_ipaddress(self.public_ip_range4.vlan.id)
with self.assertRaises(Exception):
ipaddress = PublicIPAddress.create(
self.apiclient,
zoneid=self.zone.id,
networkid=network.id,
ipaddress=ip_address_4
)
# Associate IP in public IP pool
Configurations.update(
self.apiclient,
name="use.system.public.ips",
value="false",
accountid=self.account1.id
)
ip_address_5 = self.get_free_ipaddress(self.public_ip_range5.vlan.id)
with self.assertRaises(Exception):
ipaddress = PublicIPAddress.create(
self.apiclient,
zoneid=self.zone.id,
networkid=network.id,
ipaddress=ip_address_5
)
Configurations.update(
self.apiclient,
name="use.system.public.ips",
value="true",
accountid=self.account1.id
)
ipaddress = PublicIPAddress.create(
self.apiclient,
zoneid=self.zone.id,
networkid=network.id,
ipaddress=ip_address_5
)
self.assertIsNotNone(
ipaddress,
"Failed to Associate IP Address"
)
self.cleanup.append(ipaddress)
self.assertEqual(ipaddress.ipaddress.ipaddress, ip_address_5, "Associated IP is not same as specified")
self.cleanup.append(self.virtual_machine)
self.cleanup.append(self.service_offering)
return
@attr(tags=["advanced"], required_hardware="false")
def test_02_acquire_public_ip_in_vpc(self):
# Validate the following
# 1. create a VPC with default offering.
# 2. assign a specified IP from subnet which is dedicated to domain1, it should succeed
# 3. assign a specified IP from subnet which is dedicated to domain1/account1, it should succeed
# 4. assign a specified IP from subnet which is dedicated to domain2, it should fail
# 5. assign a specified IP from subnet which is dedicated to domain2/account2, it should fail
# 6. update account setting use.system.public.ips to false, assign a specified IP from subnet which is public, it should fail
# 7. update account setting use.system.public.ips to true, assign a specified IP from subnet which is public, it should succeed
vpcOffering = VpcOffering.list(self.apiclient, name="Default VPC offering")
vpc = VPC.create(
apiclient=self.apiclient,
services=self.services["vpc"],
vpcofferingid=vpcOffering[0].id,
zoneid=self.zone.id,
account=self.account1.name,
domainid=self.account1.domainid
)
# Associate IP in range dedicated to domain1
ip_address_1 = self.get_free_ipaddress(self.public_ip_range1.vlan.id)
ipaddress = PublicIPAddress.create(
self.apiclient,
zoneid=self.zone.id,
vpcid=vpc.id,
ipaddress=ip_address_1
)
self.assertIsNotNone(
ipaddress,
"Failed to Associate IP Address"
)
self.cleanup.append(ipaddress)
self.assertEqual(ipaddress.ipaddress.ipaddress, ip_address_1, "Associated IP is not same as specified")
# Associate IP in range dedicated to domain1/account1
ip_address_2 = self.get_free_ipaddress(self.public_ip_range2.vlan.id)
ipaddress = PublicIPAddress.create(
self.apiclient,
zoneid=self.zone.id,
vpcid=vpc.id,
ipaddress=ip_address_2
)
self.assertIsNotNone(
ipaddress,
"Failed to Associate IP Address"
)
self.cleanup.append(ipaddress)
self.assertEqual(ipaddress.ipaddress.ipaddress, ip_address_2, "Associated IP is not same as specified")
# Associate IP in range dedicated to domain2
ip_address_3 = self.get_free_ipaddress(self.public_ip_range3.vlan.id)
with self.assertRaises(Exception):
ipaddress = PublicIPAddress.create(
self.apiclient,
zoneid=self.zone.id,
vpcid=vpc.id,
ipaddress=ip_address_3
)
# Associate IP in range dedicated to domain2/account2
ip_address_4 = self.get_free_ipaddress(self.public_ip_range4.vlan.id)
with self.assertRaises(Exception):
ipaddress = PublicIPAddress.create(
self.apiclient,
zoneid=self.zone.id,
vpcid=vpc.id,
ipaddress=ip_address_4
)
# Associate IP in public IP pool
Configurations.update(
self.apiclient,
name="use.system.public.ips",
value="false",
accountid=self.account1.id
)
ip_address_5 = self.get_free_ipaddress(self.public_ip_range5.vlan.id)
with self.assertRaises(Exception):
ipaddress = PublicIPAddress.create(
self.apiclient,
zoneid=self.zone.id,
vpcid=vpc.id,
ipaddress=ip_address_5
)
Configurations.update(
self.apiclient,
name="use.system.public.ips",
value="true",
accountid=self.account1.id
)
ipaddress = PublicIPAddress.create(
self.apiclient,
zoneid=self.zone.id,
vpcid=vpc.id,
ipaddress=ip_address_5
)
self.assertIsNotNone(
ipaddress,
"Failed to Associate IP Address"
)
self.cleanup.append(ipaddress)
self.assertEqual(ipaddress.ipaddress.ipaddress, ip_address_5, "Associated IP is not same as specified")
self.cleanup.append(vpc)
return
def get_free_ipaddress(self, vlanId):
ipaddresses = PublicIPAddress.list(
self.apiclient,
vlanid=vlanId,
state='Free'
)
self.assertEqual(
isinstance(ipaddresses, list),
True,
"List ipaddresses should return a valid response for Free ipaddresses"
)
random.shuffle(ipaddresses)
return ipaddresses[0].ipaddress