blob: 92b35ad3fa4ffc69f04d56909805ee86ef35f04a [file] [log] [blame]
# 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.
""" P1 tests for Dedicating Public IP addresses
"""
#Import Local Modules
import marvin
from nose.plugins.attrib import attr
from marvin.cloudstackTestCase import *
from marvin.cloudstackAPI import *
from marvin.lib.utils import *
from marvin.lib.base import *
from marvin.lib.common import *
import datetime
from socket import inet_aton
from struct import unpack
class TestDedicatePublicIPRange(cloudstackTestCase):
@classmethod
def setUpClass(cls):
cls.testClient = super(TestDedicatePublicIPRange, cls).getClsTestClient()
cls.apiclient = cls.testClient.getApiClient()
cls.services = cls.testClient.getParsedTestDataConfig()
# Get Zone, Domain
cls.domain = get_domain(cls.apiclient)
cls.zone = get_zone(cls.apiclient, cls.testClient.getZoneForTests())
cls.services["zoneid"] = cls.zone.id
cls.pod = get_pod(cls.apiclient, cls.zone.id)
# Create Account
cls.account = Account.create(
cls.apiclient,
cls.services["account"],
domainid=cls.domain.id
)
cls._cleanup = [
cls.account,
]
return
@classmethod
def tearDownClass(cls):
try:
# Cleanup resources used
cleanup_resources(cls.apiclient, cls._cleanup)
except Exception as e:
raise Exception("Warning: Exception during cleanup : %s" % e)
return
def setUp(self):
self.apiclient = self.testClient.getApiClient()
self.dbclient = self.testClient.getDbConnection()
self.cleanup = []
return
def tearDown(self):
try:
# Clean up
cleanup_resources(self.apiclient, self.cleanup)
except Exception as e:
raise Exception("Warning: Exception during cleanup : %s" % e)
return
@attr(tags = ["advanced", "publiciprange", "dedicate", "release"], required_hardware="false")
def test_dedicatePublicIpRange(self):
"""Test public IP range dedication
"""
# Validate the following:
# 1. Create a Public IP range
# 2. Created IP range should be present, verify with listVlanIpRanges
# 3. Dedicate the created IP range to user account
# 4. Verify IP range is dedicated, verify with listVlanIpRanges
# 5. Release the dedicated Public IP range back to the system
# 6. Verify IP range has been released, verify with listVlanIpRanges
# 7. Delete the Public IP range
self.debug("Creating Public IP range")
self.public_ip_range = PublicIpRange.create(
self.apiclient,
self.services
)
list_public_ip_range_response = PublicIpRange.list(
self.apiclient,
id=self.public_ip_range.vlan.id
)
self.debug(
"Verify listPublicIpRanges response for public ip ranges: %s" \
% self.public_ip_range.vlan.id
)
self.assertEqual(
isinstance(list_public_ip_range_response, list),
True,
"Check for list Public IP range response"
)
public_ip_response = list_public_ip_range_response[0]
self.assertEqual(
public_ip_response.id,
self.public_ip_range.vlan.id,
"Check public ip range response id is in listVlanIpRanges"
)
self.debug("Dedicating Public IP range");
dedicate_public_ip_range_response = PublicIpRange.dedicate(
self.apiclient,
self.public_ip_range.vlan.id,
account=self.account.name,
domainid=self.account.domainid
)
list_public_ip_range_response = PublicIpRange.list(
self.apiclient,
id=self.public_ip_range.vlan.id
)
public_ip_response = list_public_ip_range_response[0]
self.assertEqual(
public_ip_response.account,
self.account.name,
"Check account name is in listVlanIpRanges as the account public ip range is dedicated to"
)
self.debug("Releasing Public IP range");
self.public_ip_range.release(self.apiclient)
list_public_ip_range_response = PublicIpRange.list(
self.apiclient,
id=self.public_ip_range.vlan.id
)
public_ip_response = list_public_ip_range_response[0]
self.assertEqual(
public_ip_response.account,
"system",
"Check account name is system account in listVlanIpRanges"
)
self.debug("Deleting Public IP range");
self.public_ip_range.delete(self.apiclient)
return
@attr(tags = ["advanced", "publiciprange", "dedicate", "release"], required_hardware="false")
def test_dedicate_public_ip_range_for_system_vms(self):
"""Test public IP range dedication for SSVM and CPVM
"""
# Validate the following:
# 1. Create a Public IP range for system vms
# 2. Created IP range should be present and marked as forsystemvms=true, verify with listVlanIpRanges
# 7. Delete the Public IP range
services = {
"gateway":"192.168.99.1",
"netmask":"255.255.255.0",
"startip":"192.168.99.2",
"endip":"192.168.99.200",
"forvirtualnetwork":self.services["forvirtualnetwork"],
"zoneid":self.services["zoneid"],
"vlan":self.services["vlan"]
}
public_ip_range = PublicIpRange.create(
self.apiclient,
services,
forsystemvms = True
)
created_ip_range_response = PublicIpRange.list(
self.apiclient,
id = public_ip_range.vlan.id
)
self.assertEqual(
len(created_ip_range_response),
1,
"Check listVlanIpRanges response"
)
self.assertTrue(
created_ip_range_response[0].forsystemvms,
"Check forsystemvms parameter in created vlan ip range"
)
# Delete range
public_ip_range.delete(self.apiclient)
def get_ip_as_number(self, ip_string):
""" Return numeric value for ip (passed as a string)
"""
packed_ip = inet_aton(ip_string)
return unpack(">L", packed_ip)[0]
def is_ip_in_range(self, start_ip, end_ip, ip_to_test):
""" Check whether ip_to_test belongs to IP range between start_ip and end_ip
"""
start = self.get_ip_as_number(start_ip)
end = self.get_ip_as_number(end_ip)
ip = self.get_ip_as_number(ip_to_test)
return start <= ip and ip <= end
def wait_for_system_vm_start(self, domain_id, systemvmtype):
""" Wait until system vm is Running
"""
def checkSystemVMUp():
response = list_ssvms(
self.apiclient,
systemvmtype=systemvmtype,
domainid=domain_id
)
if isinstance(response, list):
if response[0].state == 'Running':
return True, response[0].id
return False, None
res, systemvmId = wait_until(3, 200, checkSystemVMUp)
if not res:
raise Exception("Failed to wait for systemvm to be running")
return systemvmId
def base_system_vm(self, services, systemvmtype):
"""
Base for CPVM or SSVM depending on systemvmtype parameter
"""
# Create range for system vms
self.debug("Creating Public IP range for system vms")
public_ip_range = PublicIpRange.create(
self.apiclient,
services,
forsystemvms = True
)
# List Running System VM
list_systemvm_response = list_ssvms(
self.apiclient,
systemvmtype=systemvmtype,
state='Running',
domainid=public_ip_range.vlan.domainid
)
self.assertTrue(
isinstance(list_systemvm_response, list),
"Check list response returns a valid list"
)
self.assertEqual(
len(list_systemvm_response),
1,
"Check list response size"
)
# Delete System VM
systemvm = list_systemvm_response[0]
self.debug("Destroying System VM: %s" % systemvm.id)
cmd = destroySystemVm.destroySystemVmCmd()
cmd.id = systemvm.id
self.apiclient.destroySystemVm(cmd)
# Wait for CPVM to start
systemvm_id = self.wait_for_system_vm_start(
public_ip_range.vlan.domainid,
systemvmtype
)
self.assertNotEqual(
systemvm_id,
None,
"Check CPVM id is not none"
)
list_systemvm_response = list_ssvms(
self.apiclient,
id=systemvm_id
)
self.assertEqual(
isinstance(list_systemvm_response, list),
True,
"Check list response returns a valid list"
)
systemvm_response = list_systemvm_response[0]
self.debug("System VM state after debug: %s" % systemvm_response.state)
self.assertEqual(
systemvm_response.state,
'Running',
"Check whether System VM is running or not"
)
# Verify System VM got IP in the created range
startip = services["startip"]
endip = services["endip"]
cpvm_ip = systemvm_response.publicip
self.assertTrue(
self.is_ip_in_range(startip, endip, cpvm_ip),
"Check whether System VM Public IP is in range dedicated to system vms"
)
# Delete System VM and IP range, so System VM can get IP from original ranges
self.debug("Destroying System VM: %s" % systemvm_id)
cmd = destroySystemVm.destroySystemVmCmd()
cmd.id = systemvm_id
self.apiclient.destroySystemVm(cmd)
domain_id = public_ip_range.vlan.domainid
public_ip_range.delete(self.apiclient)
# Wait for System VM to start and check System VM public IP
systemvm_id = self.wait_for_system_vm_start(
domain_id,
systemvmtype
)
list_systemvm_response = list_ssvms(
self.apiclient,
id=systemvm_id
)
self.assertFalse(
self.is_ip_in_range(startip, endip, list_systemvm_response[0].publicip),
"Check System VM Public IP is not in range dedicated to system vms"
)
return True
def exists_public_ip_range_for_system_vms(self, zoneid):
"""
Return True if there exists a public IP range dedicated for system vms in zoneid
"""
existing_ip_ranges_response = PublicIpRange.list(
self.apiclient,
zoneid=zoneid
)
for r in existing_ip_ranges_response:
if r.forsystemvms:
return True
return False
@attr(tags = ["advanced", "publiciprange", "dedicate", "release"], required_hardware="false")
def test_dedicate_public_ip_range_for_system_vms_01_ssvm(self):
"""Test SSVM Public IP
"""
self.debug("Precondition: No public IP range dedicated for system vms in the environment")
if self.exists_public_ip_range_for_system_vms(self.services["zoneid"]):
self.skipTest("An existing IP range defined for system vms, aborting test")
services = {
"gateway":"192.168.100.1",
"netmask":"255.255.255.0",
"startip":"192.168.100.2",
"endip":"192.168.100.200",
"forvirtualnetwork":self.services["forvirtualnetwork"],
"zoneid":self.services["zoneid"],
"vlan":self.services["vlan"]
}
self.base_system_vm(
services,
'secondarystoragevm'
)
return
@attr(tags = ["advanced", "publiciprange", "dedicate", "release"], required_hardware="false")
def test_dedicate_public_ip_range_for_system_vms_02_cpvm(self):
"""Test CPVM Public IP
"""
self.debug("Precondition: No public IP range dedicated for system vms in the environment")
if self.exists_public_ip_range_for_system_vms(self.services["zoneid"]):
self.skipTest("An existing IP range defined for system vms, aborting test")
services = {
"gateway":"192.168.200.1",
"netmask":"255.255.255.0",
"startip":"192.168.200.2",
"endip":"192.168.200.200",
"forvirtualnetwork":self.services["forvirtualnetwork"],
"zoneid":self.services["zoneid"],
"vlan":self.services["vlan"]
}
self.base_system_vm(
services,
'consoleproxy'
)
return