Integration test for advanced zone with security groups

Description:
This patch includes three parts for advancedsg:
(1) Marvin support.
(2) devcloud support.
(3) integration test scripts

Testing Done:
devcloud testing ok.

Signed-off-by: Anthony Xu <anthony.xu@citrix.com>
This commit is contained in:
Wei Zhou 2013-05-22 15:39:22 -07:00 committed by Anthony Xu
parent 297115cac5
commit e6863c612b
11 changed files with 1461 additions and 24 deletions

185
setup/dev/advancedsg.cfg Normal file
View File

@ -0,0 +1,185 @@
# 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.
{
"zones": [
{
"name": "Sandbox-Simulator",
"dns1": "10.147.28.6",
"physical_networks": [
{
"name": "Sandbox-pnet",
"tags": [
"cloud-simulator-pnet"
],
"broadcastdomainrange": "Zone",
"providers": [
{
"broadcastdomainrange": "ZONE",
"name": "VirtualRouter"
},
{
"broadcastdomainrange": "ZONE",
"name": "SecurityGroupProvider"
}
],
"traffictypes": [
{
"typ": "Guest"
},
{
"typ": "Management",
"simulator": "cloud-simulator-mgmt"
}
],
"isolationmethods": [
"VLAN"
]
}
],
"securitygroupenabled": "true",
"ipranges": [
{
"startip": "10.147.31.150",
"endip": "10.147.31.159",
"netmask": "255.255.255.0",
"vlan": "31",
"gateway": "10.147.31.1"
}
],
"networktype": "Advanced",
"pods": [
{
"endip": "10.147.29.159",
"name": "POD0",
"startip": "10.147.29.150",
"netmask": "255.255.255.0",
"clusters": [
{
"clustername": "C0",
"hypervisor": "Simulator",
"hosts": [
{
"username": "root",
"url": "http://simulator0",
"password": "password"
}
],
"clustertype": "CloudManaged",
"primaryStorages": [
{
"url": "nfs://10.147.28.6:/export/home/sandbox/primary",
"name": "PS0"
}
]
}
],
"gateway": "10.147.29.1"
}
],
"internaldns1": "10.147.28.6",
"secondaryStorages": [
{
"url": "nfs://10.147.28.6:/export/home/sandbox/sstor"
}
]
}
],
"dbSvr": {
"dbSvr": "localhost",
"passwd": "cloud",
"db": "cloud",
"port": 3306,
"user": "cloud"
},
"logger": [
{
"name": "TestClient",
"file": "testclient.log"
},
{
"name": "TestCase",
"file": "testcase.log"
}
],
"globalConfig": [
{
"name": "storage.cleanup.interval",
"value": "300"
},
{
"name": "direct.agent.load.size",
"value": "1000"
},
{
"name": "default.page.size",
"value": "10000"
},
{
"name": "instance.name",
"value": "QA"
},
{
"name": "workers",
"value": "10"
},
{
"name": "vm.op.wait.interval",
"value": "5"
},
{
"name": "account.cleanup.interval",
"value": "600"
},
{
"name": "guest.domain.suffix",
"value": "sandbox.simulator"
},
{
"name": "expunge.delay",
"value": "60"
},
{
"name": "vm.allocation.algorithm",
"value": "random"
},
{
"name": "expunge.interval",
"value": "60"
},
{
"name": "expunge.workers",
"value": "3"
},
{
"name": "secstorage.allowed.internal.sites",
"value": "10.147.28.0/24"
},
{
"name": "check.pod.cidrs",
"value": "true"
}
],
"mgtSvr": [
{
"mgtSvrIp": "localhost",
"passwd": "password",
"user": "root",
"port": 8096
}
]
}

View File

@ -0,0 +1,753 @@
# 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 networks in advanced zone with security groups
"""
#Import Local Modules
import marvin
from marvin.cloudstackTestCase import *
from marvin.cloudstackAPI import *
from marvin.integration.lib.utils import *
from marvin.integration.lib.base import *
from marvin.integration.lib.common import *
from marvin.remoteSSHClient import remoteSSHClient
import datetime
import netaddr
class Services:
""" Test networks in advanced zone with security groups"""
def __init__(self):
self.services = {
"domain": {
"name": "DOM",
},
"project": {
"name": "Project",
"displaytext": "Test project",
},
"account": {
"email": "admin-XABU1@test.com",
"firstname": "admin-XABU1",
"lastname": "admin-XABU1",
"username": "admin-XABU1",
# Random characters are appended for unique
# username
"password": "fr3sca",
},
"service_offering": {
"name": "Tiny Instance",
"displaytext": "Tiny Instance",
"cpunumber": 1,
"cpuspeed": 100, # in MHz
"memory": 128, # In MBs
},
"shared_network_offering_sg": {
"name": 'MySharedOffering-sg',
"displaytext": 'MySharedOffering-sg',
"guestiptype": 'Shared',
"supportedservices": 'Dhcp,Dns,UserData,SecurityGroup',
"specifyVlan" : "False",
"specifyIpRanges" : "False",
"traffictype": 'GUEST',
"serviceProviderList" : {
"Dhcp": 'VirtualRouter',
"Dns": 'VirtualRouter',
"UserData": 'VirtualRouter',
"SecurityGroup": 'SecurityGroupProvider'
},
},
"shared_network_offering": {
"name": 'MySharedOffering',
"displaytext": 'MySharedOffering',
"guestiptype": 'Shared',
"supportedservices": 'Dhcp,Dns,UserData',
"specifyVlan" : "False",
"specifyIpRanges" : "False",
"traffictype": 'GUEST',
"serviceProviderList" : {
"Dhcp": 'VirtualRouter',
"Dns": 'VirtualRouter',
"UserData": 'VirtualRouter'
},
},
"shared_network_sg": {
"name": "MyIsolatedNetwork - Test",
"displaytext": "MyIsolatedNetwork",
"networkofferingid":"1",
"vlan" :1200,
"gateway" :"172.16.15.1",
"netmask" :"255.255.255.0",
"startip" :"172.16.15.2",
"endip" :"172.16.15.20",
"acltype" : "Domain",
"scope":"all",
},
"shared_network": {
"name": "MySharedNetwork - Test",
"displaytext": "MySharedNetwork",
"vlan" :1201,
"gateway" :"172.16.15.1",
"netmask" :"255.255.255.0",
"startip" :"172.16.15.21",
"endip" :"172.16.15.41",
"acltype" : "Domain",
"scope":"all",
},
"isolated_network_offering": {
"name": 'Network offering-DA services',
"displaytext": 'Network offering-DA services',
"guestiptype": 'Isolated',
"supportedservices": 'Dhcp,Dns,SourceNat,PortForwarding,Vpn,Firewall,Lb,UserData,StaticNat',
"traffictype": 'GUEST',
"availability": 'Optional',
"serviceProviderList": {
"Dhcp": 'VirtualRouter',
"Dns": 'VirtualRouter',
"SourceNat": 'VirtualRouter',
"PortForwarding": 'VirtualRouter',
"Vpn": 'VirtualRouter',
"Firewall": 'VirtualRouter',
"Lb": 'VirtualRouter',
"UserData": 'VirtualRouter',
"StaticNat": 'VirtualRouter',
},
},
"isolated_network": {
"name": "Isolated Network",
"displaytext": "Isolated Network",
},
"virtual_machine": {
"displayname": "Test VM",
"username": "root",
"password": "password",
"ssh_port": 22,
"hypervisor": 'XenServer',
# Hypervisor type should be same as
# hypervisor type of cluster
"privateport": 22,
"publicport": 22,
"protocol": 'TCP',
},
"ostype": 'CentOS 5.3 (64-bit)',
# Cent OS 5.3 (64 bit)
"sleep": 90,
"timeout": 10,
"mode": 'advanced',
"securitygroupenabled": 'true'
}
class TestNetworksInAdvancedSG(cloudstackTestCase):
@classmethod
def setUpClass(cls):
cls.api_client = super(
TestSharedNetworks,
cls
).getClsTestClient().getApiClient()
cls.services = Services().services
# Get Zone, Domain and templates
cls.domain = get_domain(cls.api_client, cls.services)
cls.zone = get_zone(cls.api_client, cls.services)
cls.template = get_template(
cls.api_client,
cls.zone.id,
cls.services["ostype"]
)
cls.services["virtual_machine"]["zoneid"] = cls.zone.id
cls.services["virtual_machine"]["template"] = cls.template.id
cls.service_offering = ServiceOffering.create(
cls.api_client,
cls.services["service_offering"]
)
cls._cleanup = [
cls.service_offering,
]
return
@classmethod
def tearDownClass(cls):
try:
#Cleanup resources used
cleanup_resources(cls.api_client, cls._cleanup)
except Exception as e:
raise Exception("Warning: Exception during cleanup : %s" % e)
return
def setUp(self):
self.api_client = self.testClient.getApiClient()
self.dbclient = self.testClient.getDbConnection()
self.cleanup = []
self.cleanup_networks = []
self.cleanup_accounts = []
self.cleanup_domains = []
self.cleanup_projects = []
self.cleanup_vms = []
return
def tearDown(self):
try:
#Clean up, terminate the created network offerings
cleanup_resources(self.api_client, self.cleanup)
except Exception as e:
raise Exception("Warning: Exception during cleanup : %s" % e)
#below components is not a part of cleanup because to mandate the order and to cleanup network
try:
for vm in self.cleanup_vms:
vm.delete(self.api_client)
except Exception as e:
raise Exception("Warning: Exception during virtual machines cleanup : %s" % e)
try:
for project in self.cleanup_projects:
project.delete(self.api_client)
except Exception as e:
raise Exception("Warning: Exception during project cleanup : %s" % e)
try:
for account in self.cleanup_accounts:
account.delete(self.api_client)
except Exception as e:
raise Exception("Warning: Exception during account cleanup : %s" % e)
try:
for domain in self.cleanup_domains:
domain.delete(self.api_client)
except Exception as e:
raise Exception("Warning: Exception during domain cleanup : %s" % e)
#Wait till all resources created are cleaned up completely and then attempt to delete Network
time.sleep(self.services["sleep"])
try:
for network in self.cleanup_networks:
network.delete(self.api_client)
except Exception as e:
raise Exception("Warning: Exception during network cleanup : %s" % e)
return
def test_createIsolatedNetwork(self):
""" Test Isolated Network """
# Steps,
# 1. create an Admin Account - admin-XABU1
# 2. listPhysicalNetworks in available zone
# 3. createNetworkOffering:
# 4. Enable network offering - updateNetworkOffering - state=Enabled
# 5. createNetwork
# Validations,
# 1. listAccounts name=admin-XABU1, state=enabled returns your account
# 2. listPhysicalNetworks should return at least one active physical network
# 4. listNetworkOfferings - name=myisolatedoffering, should list enabled offering
# 5. network creation should FAIL since isolated network is not supported in advanced zone with security groups.
#Create admin account
self.admin_account = Account.create(
self.api_client,
self.services["account"],
admin=True,
domainid=self.domain.id
)
self.cleanup_accounts.append(self.admin_account)
#verify that the account got created with state enabled
list_accounts_response = Account.list(
self.api_client,
id=self.admin_account.account.id,
listall=True
)
self.assertEqual(
isinstance(list_accounts_response, list),
True,
"listAccounts returned invalid object in response."
)
self.assertNotEqual(
len(list_accounts_response),
0,
"listAccounts returned empty list."
)
self.assertEqual(
list_accounts_response[0].state,
"enabled",
"The admin account created is not enabled."
)
self.debug("Admin type account created: %s" % self.admin_account.name)
#Create an user account
self.user_account = Account.create(
self.api_client,
self.services["account"],
admin=False,
domainid=self.domain.id
)
self.cleanup_accounts.append(self.user_account)
#verify that the account got created with state enabled
list_accounts_response = Account.list(
self.api_client,
id=self.user_account.account.id,
listall=True
)
self.assertEqual(
isinstance(list_accounts_response, list),
True,
"listAccounts returned invalid object in response."
)
self.assertNotEqual(
len(list_accounts_response),
0,
"listAccounts returned empty list."
)
self.assertEqual(
list_accounts_response[0].state,
"enabled",
"The user account created is not enabled."
)
self.debug("User type account created: %s" % self.user_account.name)
#Verify that there should be at least one physical network present in zone.
list_physical_networks_response = PhysicalNetwork.list(
self.api_client,
zoneid=self.zone.id
)
self.assertEqual(
isinstance(list_physical_networks_response, list),
True,
"listPhysicalNetworks returned invalid object in response."
)
self.assertNotEqual(
len(list_physical_networks_response),
0,
"listPhysicalNetworks should return at least one physical network."
)
physical_network = list_physical_networks_response[0]
self.debug("Physical network found: %s" % physical_network.id)
#Create Network Offering
self.isolated_network_offering = NetworkOffering.create(
self.api_client,
self.services["isolated_network_offering"],
conservemode=False
)
self.cleanup.append(self.isolated_network_offering)
#Verify that the network offering got created
list_network_offerings_response = NetworkOffering.list(
self.api_client,
id=self.isolated_network_offering.id
)
self.assertEqual(
isinstance(list_network_offerings_response, list),
True,
"listNetworkOfferings returned invalid object in response."
)
self.assertNotEqual(
len(list_network_offerings_response),
0,
"listNetworkOfferings returned empty list."
)
self.assertEqual(
list_network_offerings_response[0].state,
"Disabled",
"The network offering created should be bydefault disabled."
)
self.debug("Isolated Network offering created: %s" % self.isolated_network_offering.id)
#Update network offering state from disabled to enabled.
network_offering_update_response = NetworkOffering.update(
self.isolated_network_offering,
self.api_client,
id=self.isolated_network_offering.id,
state="enabled"
)
#Verify that the state of the network offering is updated
list_network_offerings_response = NetworkOffering.list(
self.api_client,
id=self.isolated_network_offering.id
)
self.assertEqual(
isinstance(list_network_offerings_response, list),
True,
"listNetworkOfferings returned invalid object in response."
)
self.assertNotEqual(
len(list_network_offerings_response),
0,
"listNetworkOfferings returned empty list."
)
self.assertEqual(
list_network_offerings_response[0].state,
"Enabled",
"The network offering state should get updated to Enabled."
)
#create network using the isolated network offering created
try:
self.isolated_network = Network.create(
self.api_client,
self.services["isolated_network"],
networkofferingid=self.isolated_network_offering.id,
zoneid=self.zone.id,
)
self.cleanup_networks.append(self.isolated_network)
self.fail("Create isolated network is invalid in advanced zone with security groups.")
except Exception as e:
self.debug("Network creation failed because create isolated network is invalid in advanced zone with security groups.")
def test_createSharedNetwork_withoutSG(self):
""" Test Shared Network with used vlan 01 """
# Steps,
# 1. create an Admin account
# 2. create a shared NetworkOffering
# 3. enable the network offering
# 4. listPhysicalNetworks
# 5. createNetwork
# Validations,
# 1. listAccounts state=enabled returns your account
# 2. listNetworkOfferings - name=mysharedoffering , should list offering in disabled state
# 3. listNetworkOfferings - name=mysharedoffering, should list enabled offering
# 4. listPhysicalNetworks should return at least one active physical network
# 5. network creation should FAIL since there is no SecurityProvide in the network offering
#Create admin account
self.admin_account = Account.create(
self.api_client,
self.services["account"],
admin=True,
domainid=self.domain.id
)
self.cleanup_accounts.append(self.admin_account)
#verify that the account got created with state enabled
list_accounts_response = Account.list(
self.api_client,
id=self.admin_account.account.id,
listall=True
)
self.assertEqual(
isinstance(list_accounts_response, list),
True,
"listAccounts returned invalid object in response."
)
self.assertNotEqual(
len(list_accounts_response),
0,
"listAccounts returned empty list."
)
self.assertEqual(
list_accounts_response[0].state,
"enabled",
"The admin account created is not enabled."
)
self.debug("Domain admin account created: %s" % self.admin_account.account.id)
#Verify that there should be at least one physical network present in zone.
list_physical_networks_response = PhysicalNetwork.list(
self.api_client,
zoneid=self.zone.id
)
self.assertEqual(
isinstance(list_physical_networks_response, list),
True,
"listPhysicalNetworks returned invalid object in response."
)
self.assertNotEqual(
len(list_physical_networks_response),
0,
"listPhysicalNetworks should return at least one physical network."
)
physical_network = list_physical_networks_response[0]
self.debug("Physical Network found: %s" % physical_network.id)
self.services["shared_network_offering"]["specifyVlan"] = "True"
self.services["shared_network_offering"]["specifyIpRanges"] = "True"
#Create Network Offering
self.shared_network_offering = NetworkOffering.create(
self.api_client,
self.services["shared_network_offering"],
conservemode=False
)
self.cleanup.append(self.shared_network_offering)
#Verify that the network offering got created
list_network_offerings_response = NetworkOffering.list(
self.api_client,
id=self.shared_network_offering.id
)
self.assertEqual(
isinstance(list_network_offerings_response, list),
True,
"listNetworkOfferings returned invalid object in response."
)
self.assertNotEqual(
len(list_network_offerings_response),
0,
"listNetworkOfferings returned empty list."
)
self.assertEqual(
list_network_offerings_response[0].state,
"Disabled",
"The network offering created should be bydefault disabled."
)
self.debug("Shared Network Offering created: %s" % self.shared_network_offering.id)
#Update network offering state from disabled to enabled.
network_offering_update_response = NetworkOffering.update(
self.shared_network_offering,
self.api_client,
id=self.shared_network_offering.id,
state="enabled"
)
#Verify that the state of the network offering is updated
list_network_offerings_response = NetworkOffering.list(
self.api_client,
id=self.shared_network_offering.id
)
self.assertEqual(
isinstance(list_network_offerings_response, list),
True,
"listNetworkOfferings returned invalid object in response."
)
self.assertNotEqual(
len(list_network_offerings_response),
0,
"listNetworkOfferings returned empty list."
)
self.assertEqual(
list_network_offerings_response[0].state,
"Enabled",
"The network offering state should get updated to Enabled."
)
#create network using the shared network offering created
self.services["shared_network"]["acltype"] = "domain"
self.services["shared_network"]["networkofferingid"] = self.shared_network_offering.id
self.services["shared_network"]["physicalnetworkid"] = physical_network.id
try:
self.shared_network = Network.create(
self.api_client,
self.services["shared_network"],
networkofferingid=self.shared_network_offering.id,
zoneid=self.zone.id
)
self.cleanup_networks.append(self.shared_network)
self.fail("Network created without SecurityProvider , which is invalid")
except Exception as e:
self.debug("Network creation failed because there is no SecurityProvider in the network offering.")
def test_deployVM_SharedwithSG(self):
""" Test VM deployment in shared networks with SecurityProvider """
# Steps,
# 0. create a user account
# 1. Create one shared Network (scope=ALL, different IP ranges)
# 2. deployVirtualMachine in the above networkid within the user account
# 3. delete the user account
# Validations,
# 1. shared network should be created successfully
# 2. VM should deploy successfully
#Create admin account
self.admin_account = Account.create(
self.api_client,
self.services["account"],
admin=True,
domainid=self.domain.id
)
self.cleanup_accounts.append(self.admin_account)
#verify that the account got created with state enabled
list_accounts_response = Account.list(
self.api_client,
id=self.admin_account.account.id,
liistall=True
)
self.assertEqual(
isinstance(list_accounts_response, list),
True,
"listAccounts returned invalid object in response."
)
self.assertNotEqual(
len(list_accounts_response),
0,
"listAccounts returned empty list."
)
self.assertEqual(
list_accounts_response[0].state,
"enabled",
"The admin account created is not enabled."
)
self.debug("Admin type account created: %s" % self.admin_account.name)
self.services["shared_network_offering_sg"]["specifyVlan"] = "True"
self.services["shared_network_offering_sg"]["specifyIpRanges"] = "True"
#Create Network Offering
self.shared_network_offering_sg = NetworkOffering.create(
self.api_client,
self.services["shared_network_offering_sg"],
conservemode=False
)
self.cleanup.append(self.shared_network_offering_sg)
#Verify that the network offering got created
list_network_offerings_response = NetworkOffering.list(
self.api_client,
id=self.shared_network_offering_sg.id
)
self.assertEqual(
isinstance(list_network_offerings_response, list),
True,
"listNetworkOfferings returned invalid object in response."
)
self.assertNotEqual(
len(list_network_offerings_response),
0,
"listNetworkOfferings returned empty list."
)
self.assertEqual(
list_network_offerings_response[0].state,
"Disabled",
"The network offering created should be bydefault disabled."
)
self.debug("Shared Network offering created: %s" % self.shared_network_offering_sg.id)
#Update network offering state from disabled to enabled.
network_offering_update_response = NetworkOffering.update(
self.shared_network_offering_sg,
self.api_client,
id=self.shared_network_offering_sg.id,
state="enabled"
)
#Verify that the state of the network offering is updated
list_network_offerings_response = NetworkOffering.list(
self.api_client,
id=self.shared_network_offering_sg.id
)
self.assertEqual(
isinstance(list_network_offerings_response, list),
True,
"listNetworkOfferings returned invalid object in response."
)
self.assertNotEqual(
len(list_network_offerings_response),
0,
"listNetworkOfferings returned empty list."
)
self.assertEqual(
list_network_offerings_response[0].state,
"Enabled",
"The network offering state should get updated to Enabled."
)
physical_network = list_physical_networks_response[0]
#create network using the shared network offering created
self.services["shared_network_sg"]["acltype"] = "domain"
self.services["shared_network_sg"]["networkofferingid"] = self.shared_network_offering_sg.id
self.services["shared_network_sg"]["physicalnetworkid"] = physical_network.id
self.shared_network_sg = Network.create(
self.api_client,
self.services["shared_network_sg"],
domainid=self.admin_account.account.domainid,
networkofferingid=self.shared_network_offering_sg.id,
zoneid=self.zone.id
)
self.cleanup_networks.append(self.shared_network_sg)
list_networks_response = Network.list(
self.api_client,
id=self.shared_network_sg.id
)
self.assertEqual(
isinstance(list_networks_response, list),
True,
"listNetworks returned invalid object in response."
)
self.assertNotEqual(
len(list_networks_response),
0,
"listNetworks returned empty list."
)
self.assertEqual(
list_networks_response[0].specifyipranges,
True,
"The network is created with ip range but the flag is set to False."
)
self.debug("Shared Network created: %s" % self.shared_network_sg.id)
self.shared_network_admin_account_virtual_machine = VirtualMachine.create(
self.api_client,
self.services["virtual_machine"],
accountid=self.admin_account.name,
domainid=self.admin_account.account.domainid,
networkids=self.shared_network_sg.id,
serviceofferingid=self.service_offering.id
)
vms = VirtualMachine.list(
self.api_client,
id=self.shared_network_admin_account_virtual_machine.id,
listall=True
)
self.assertEqual(
isinstance(vms, list),
True,
"listVirtualMachines returned invalid object in response."
)
self.assertNotEqual(
len(vms),
0,
"listVirtualMachines returned empty list."
)
self.debug("Virtual Machine created: %s" % self.shared_network_admin_account_virtual_machine.id)
ip_range = list(netaddr.iter_iprange(unicode(self.services["shared_network_sg"]["startip"]), unicode(self.services["shared_network_sg"]["endip"])))
if netaddr.IPAddress(unicode(vms[0].nic[0].ipaddress)) not in ip_range:
self.fail("Virtual machine ip should be from the ip range assigned to network created.")

View File

@ -194,7 +194,7 @@ class TestDefaultSecurityGroupEgress(cloudstackTestCase):
return
@attr(tags = ["sg", "eip"])
@attr(tags = ["sg", "eip", "advancedsg"])
def test_deployVM_InDefaultSecurityGroup(self):
"""Test deploy VM in default security group with no egress rules
"""
@ -351,7 +351,7 @@ class TestAuthorizeIngressRule(cloudstackTestCase):
return
@attr(tags = ["sg", "eip"])
@attr(tags = ["sg", "eip", "advancedsg"])
def test_authorizeIngressRule(self):
"""Test authorize ingress rule
"""
@ -509,7 +509,7 @@ class TestDefaultGroupEgress(cloudstackTestCase):
return
@attr(tags = ["sg", "eip"])
@attr(tags = ["sg", "eip", "advancedsg"])
def test_01_default_group_with_egress(self):
"""Test default group with egress rule before VM deploy and ping, ssh
"""
@ -710,7 +710,7 @@ class TestDefaultGroupEgressAfterDeploy(cloudstackTestCase):
return
@attr(tags = ["sg", "eip"])
@attr(tags = ["sg", "eip", "advancedsg"])
def test_01_default_group_with_egress(self):
""" Test default group with egress rule added after vm deploy and ping,
ssh test
@ -893,7 +893,7 @@ class TestRevokeEgressRule(cloudstackTestCase):
return
@attr(tags = ["sg", "eip"])
@attr(tags = ["sg", "eip", "advancedsg"])
def test_revoke_egress_rule(self):
"""Test revoke security group egress rule
"""
@ -1155,7 +1155,7 @@ class TestInvalidAccountAuthroize(cloudstackTestCase):
return
@attr(tags = ["sg", "eip"])
@attr(tags = ["sg", "eip", "advancedsg"])
def test_invalid_account_authroize(self):
"""Test invalid account authroize
"""
@ -1283,7 +1283,7 @@ class TestMultipleAccountsEgressRuleNeg(cloudstackTestCase):
return
@attr(tags = ["sg", "eip"])
@attr(tags = ["sg", "eip", "advancedsg"])
def test_multiple_account_egress_rule_negative(self):
"""Test multiple account egress rules negative case
"""
@ -1531,7 +1531,7 @@ class TestMultipleAccountsEgressRule(cloudstackTestCase):
return
@attr(tags = ["sg", "eip"])
@attr(tags = ["sg", "eip", "advancedsg"])
def test_multiple_account_egress_rule_positive(self):
"""Test multiple account egress rules positive case
"""
@ -1822,7 +1822,7 @@ class TestStartStopVMWithEgressRule(cloudstackTestCase):
return
@attr(tags = ["sg", "eip"])
@attr(tags = ["sg", "eip", "advancedsg"])
def test_start_stop_vm_egress(self):
""" Test stop start Vm with egress rules
"""
@ -2034,7 +2034,7 @@ class TestInvalidParametersForEgress(cloudstackTestCase):
return
@attr(tags = ["sg", "eip"])
@attr(tags = ["sg", "eip", "advancedsg"])
def test_invalid_parameters(self):
""" Test invalid parameters for egress rules
"""

View File

@ -164,7 +164,7 @@ class TestDefaultSecurityGroup(cloudstackTestCase):
return
@attr(tags = ["sg", "eip"])
@attr(tags = ["sg", "eip", "advancedsg"])
def test_01_deployVM_InDefaultSecurityGroup(self):
"""Test deploy VM in default security group
"""
@ -243,7 +243,7 @@ class TestDefaultSecurityGroup(cloudstackTestCase):
)
return
@attr(tags = ["sg", "eip"])
@attr(tags = ["sg", "eip", "advancedsg"])
def test_02_listSecurityGroups(self):
"""Test list security groups for admin account
"""
@ -278,7 +278,7 @@ class TestDefaultSecurityGroup(cloudstackTestCase):
)
return
@attr(tags = ["sg", "eip"])
@attr(tags = ["sg", "eip", "advancedsg"])
def test_03_accessInDefaultSecurityGroup(self):
"""Test access in default security group
"""
@ -435,7 +435,7 @@ class TestAuthorizeIngressRule(cloudstackTestCase):
return
@attr(tags = ["sg", "eip"])
@attr(tags = ["sg", "eip", "advancedsg"])
def test_01_authorizeIngressRule(self):
"""Test authorize ingress rule
"""
@ -571,7 +571,7 @@ class TestRevokeIngressRule(cloudstackTestCase):
return
@attr(tags = ["sg", "eip"])
@attr(tags = ["sg", "eip", "advancedsg"])
def test_01_revokeIngressRule(self):
"""Test revoke ingress rule
"""
@ -868,7 +868,7 @@ class TestdeployVMWithUserData(cloudstackTestCase):
return
@attr(tags = ["sg", "eip"])
@attr(tags = ["sg", "eip", "advancedsg"])
def test_01_deployVMWithUserData(self):
"""Test Deploy VM with User data"""
@ -1044,7 +1044,7 @@ class TestDeleteSecurityGroup(cloudstackTestCase):
return
@attr(tags = ["sg", "eip"])
@attr(tags = ["sg", "eip", "advancedsg"])
def test_01_delete_security_grp_running_vm(self):
"""Test delete security group with running VM"""
@ -1128,7 +1128,7 @@ class TestDeleteSecurityGroup(cloudstackTestCase):
)
return
@attr(tags = ["sg", "eip"])
@attr(tags = ["sg", "eip", "advancedsg"])
def test_02_delete_security_grp_withoout_running_vm(self):
"""Test delete security group without running VM"""
@ -1290,7 +1290,7 @@ class TestIngressRule(cloudstackTestCase):
return
@attr(tags = ["sg", "eip"])
@attr(tags = ["sg", "eip", "advancedsg"])
def test_01_authorizeIngressRule_AfterDeployVM(self):
"""Test delete security group with running VM"""
@ -1402,7 +1402,7 @@ class TestIngressRule(cloudstackTestCase):
% (ingress_rule_2["id"], e))
return
@attr(tags = ["sg", "eip"])
@attr(tags = ["sg", "eip", "advancedsg"])
def test_02_revokeIngressRule_AfterDeployVM(self):
"""Test Revoke ingress rule after deploy VM"""
@ -1556,7 +1556,7 @@ class TestIngressRule(cloudstackTestCase):
% (icmp_rule["ruleid"], e))
return
@attr(tags = ["sg", "eip"])
@attr(tags = ["sg", "eip", "advancedsg"])
def test_03_stopStartVM_verifyIngressAccess(self):
"""Test Start/Stop VM and Verify ingress rule"""

View File

@ -0,0 +1,119 @@
# 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.
#
# This configuration is meant for running advanced networking with security groups, with management server on the laptop.
# It requires that the user run a DNS resolver within devcloud via 'apt-get install dnsmasq'
{
"zones": [
{
"localstorageenabled": "true",
"name": "testzone",
"dns1": "8.8.8.8",
"physical_networks": [
{
"broadcastdomainrange": "Zone",
"name": "shared",
"traffictypes": [
{
"typ": "Management"
},
{
"typ": "Guest"
}
],
"providers": [
{
"broadcastdomainrange": "ZONE",
"name": "VirtualRouter"
},
{
"broadcastdomainrange": "ZONE",
"name": "SecurityGroupProvider"
}
],
"isolationmethods": [
"VLAN"
]
}
],
"securitygroupenabled": "true",
"ipranges": [
{
"startip": "10.0.3.100",
"endip": "10.0.3.199",
"netmask": "255.255.255.0",
"vlan": "1003",
"gateway": "10.0.3.2"
}
],
"networktype": "Advanced",
"pods": [
{
"endip": "192.168.56.249",
"name": "testpod",
"startip": "192.168.56.200",
"netmask": "255.255.255.0",
"clusters": [
{
"clustername": "testcluster",
"hypervisor": "XenServer",
"hosts": [
{
"username": "root",
"url": "http://192.168.56.10/",
"password": "password"
}
],
"clustertype": "CloudManaged"
}
],
"gateway": "192.168.56.1"
}
],
"internaldns1": "192.168.56.10",
"secondaryStorages": [
{
"url": "nfs://192.168.56.10/opt/storage/secondary"
}
]
}
],
"dbSvr": {
"dbSvr": "localhost",
"passwd": "cloud",
"db": "cloud",
"port": 3306,
"user": "cloud"
},
"logger": [
{
"name": "TestClient",
"file": "/var/log/testclient.log"
},
{
"name": "TestCase",
"file": "/var/log/testcase.log"
}
],
"mgtSvr": [
{
"mgtSvrIp": "127.0.0.1",
"port": 8096
}
]
}

View File

@ -638,6 +638,126 @@ def describe_setup_in_advanced_mode():
return zs
'''sample code to generate setup configuration file'''
def describe_setup_in_advancedsg_mode():
zs = cloudstackConfiguration()
for l in range(1):
z = zone()
z.dns1 = "8.8.8.8"
z.dns2 = "4.4.4.4"
z.internaldns1 = "192.168.110.254"
z.internaldns2 = "192.168.110.253"
z.name = "test"+str(l)
z.networktype = 'Advanced'
z.vlan = "100-2000"
z.securitygroupenabled = "true"
pn = physical_network()
pn.name = "test-network"
pn.traffictypes = [traffictype("Guest"), traffictype("Management")]
#If security groups are reqd
sgprovider = provider()
sgprovider.broadcastdomainrange = 'ZONE'
sgprovider.name = 'SecurityGroupProvider'
pn.providers.append(sgprovider)
z.physical_networks.append(pn)
'''create 10 pods'''
for i in range(2):
p = pod()
p.name = "test" +str(l) + str(i)
p.gateway = "192.168.%d.1"%i
p.netmask = "255.255.255.0"
p.startip = "192.168.%d.200"%i
p.endip = "192.168.%d.220"%i
'''add 10 clusters'''
for j in range(2):
c = cluster()
c.clustername = "test"+str(l)+str(i) + str(j)
c.clustertype = "CloudManaged"
c.hypervisor = "Simulator"
'''add 10 hosts'''
for k in range(2):
h = host()
h.username = "root"
h.password = "password"
memory = 8*1024*1024*1024
localstorage=1*1024*1024*1024*1024
#h.url = "http://sim/%d%d%d%d/cpucore=1&cpuspeed=8000&memory=%d&localstorage=%d"%(l,i,j,k,memory,localstorage)
h.url = "http://sim/%d%d%d%d"%(l,i,j,k)
c.hosts.append(h)
'''add 2 primary storages'''
for m in range(2):
primary = primaryStorage()
primary.name = "primary"+str(l) + str(i) + str(j) + str(m)
#primary.url = "nfs://localhost/path%s/size=%d"%(str(l) + str(i) + str(j) + str(m), size)
primary.url = "nfs://localhost/path%s"%(str(l) + str(i) + str(j) + str(m))
c.primaryStorages.append(primary)
p.clusters.append(c)
z.pods.append(p)
'''add two secondary'''
for i in range(5):
secondary = secondaryStorage()
secondary.url = "nfs://localhost/path"+str(l) + str(i)
z.secondaryStorages.append(secondary)
'''add default guest network'''
ips = iprange()
ips.vlan = "26"
ips.startip = "172.16.26.2"
ips.endip = "172.16.26.100"
ips.gateway = "172.16.26.1"
ips.netmask = "255.255.255.0"
z.ipranges.append(ips)
zs.zones.append(z)
'''Add one mgt server'''
mgt = managementServer()
mgt.mgtSvrIp = "localhost"
zs.mgtSvr.append(mgt)
'''Add a database'''
db = dbServer()
db.dbSvr = "localhost"
zs.dbSvr = db
'''add global configuration'''
global_settings = {'expunge.delay': '60',
'expunge.interval': '60',
'expunge.workers': '3',
}
for k,v in global_settings.iteritems():
cfg = configuration()
cfg.name = k
cfg.value = v
zs.globalConfig.append(cfg)
''''add loggers'''
testClientLogger = logger()
testClientLogger.name = "TestClient"
testClientLogger.file = "/tmp/testclient.log"
testCaseLogger = logger()
testCaseLogger.name = "TestCase"
testCaseLogger.file = "/tmp/testcase.log"
zs.logger.append(testClientLogger)
zs.logger.append(testCaseLogger)
return zs
def generate_setup_config(config, file=None):
describe = config
if file is None:
@ -666,6 +786,7 @@ if __name__ == "__main__":
parser.add_option("-i", "--input", action="store", default=None , dest="inputfile", help="input file")
parser.add_option("-a", "--advanced", action="store_true", default=False, dest="advanced", help="use advanced networking")
parser.add_option("-s", "--advancedsg", action="store_true", default=False, dest="advancedsg", help="use advanced networking with security groups")
parser.add_option("-o", "--output", action="store", default="./datacenterCfg", dest="output", help="the path where the json config file generated, by default is ./datacenterCfg")
(options, args) = parser.parse_args()
@ -674,6 +795,8 @@ if __name__ == "__main__":
config = get_setup_config(options.inputfile)
if options.advanced:
config = describe_setup_in_advanced_mode()
elif options.advancedsg:
config = describe_setup_in_advancedsg_mode()
else:
config = describe_setup_in_basic_mode()

View File

@ -300,7 +300,8 @@ class deployDataCenters():
createzone.securitygroupenabled = zone.securitygroupenabled
createzone.localstorageenabled = zone.localstorageenabled
createzone.networktype = zone.networktype
createzone.guestcidraddress = zone.guestcidraddress
if zone.securitygroupenabled != "true":
createzone.guestcidraddress = zone.guestcidraddress
zoneresponse = self.apiClient.createZone(createzone)
zoneId = zoneresponse.id
@ -334,10 +335,37 @@ class deployDataCenters():
self.createVlanIpRanges(zone.networktype, zone.ipranges, \
zoneId, forvirtualnetwork=True)
if zone.networktype == "Advanced":
if zone.networktype == "Advanced" and zone.securitygroupenabled != "true":
self.createpods(zone.pods, zoneId)
self.createVlanIpRanges(zone.networktype, zone.ipranges, \
zoneId)
elif zone.networktype == "Advanced" and zone.securitygroupenabled == "true":
listnetworkoffering = listNetworkOfferings.listNetworkOfferingsCmd()
listnetworkoffering.name = "DefaultSharedNetworkOfferingWithSGService"
if zone.networkofferingname is not None:
listnetworkoffering.name = zone.networkofferingname
listnetworkofferingresponse = \
self.apiClient.listNetworkOfferings(listnetworkoffering)
networkcmd = createNetwork.createNetworkCmd()
networkcmd.displaytext = "Shared SG enabled network"
networkcmd.name = "Shared SG enabled network"
networkcmd.networkofferingid = listnetworkofferingresponse[0].id
networkcmd.zoneid = zoneId
ipranges = zone.ipranges
if ipranges:
iprange = ipranges.pop()
networkcmd.startip = iprange.startip
networkcmd.endip = iprange.endip
networkcmd.gateway = iprange.gateway
networkcmd.netmask = iprange.netmask
networkcmd.vlan = iprange.vlan
networkcmdresponse = self.apiClient.createNetwork(networkcmd)
networkId = networkcmdresponse.id
self.createpods(zone.pods, zoneId, networkId)
self.createSecondaryStorages(zone.secondaryStorages, zoneId)

View File

@ -0,0 +1,18 @@
# 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.

View File

@ -0,0 +1,150 @@
#!/usr/bin/env 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.
'''
############################################################
# Experimental state of scripts
# * Need to be reviewed
# * Only a sandbox
############################################################
'''
import random
import marvin
from ConfigParser import SafeConfigParser
from optparse import OptionParser
from marvin.configGenerator import *
def getGlobalSettings(config):
for k, v in dict(config.items('globals')).iteritems():
cfg = configuration()
cfg.name = k
cfg.value = v
yield cfg
def describeResources(config):
zs = cloudstackConfiguration()
z = zone()
z.dns1 = config.get('environment', 'dns')
z.internaldns1 = config.get('environment', 'dns')
z.name = 'Sandbox-%s'%(config.get('cloudstack', 'hypervisor'))
z.networktype = 'Advanced'
z.securitygroupenabled = 'true'
sgprovider = provider()
sgprovider.broadcastdomainrange = 'ZONE'
sgprovider.name = 'SecurityGroupProvider'
pn = physical_network()
pn.name = "Sandbox-pnet"
pn.tags = ["cloud-simulator-pnet"]
pn.traffictypes = [traffictype("Guest"),
traffictype("Management", {"simulator" : "cloud-simulator-mgmt"})]
pn.isolationmethods = ["VLAN"]
pn.providers.append(sgprovider)
z.physical_networks.append(pn)
p = pod()
p.name = 'POD0'
p.gateway = config.get('cloudstack', 'private.gateway')
p.startip = config.get('cloudstack', 'private.pod.startip')
p.endip = config.get('cloudstack', 'private.pod.endip')
p.netmask = config.get('cloudstack', 'private.netmask')
v = iprange()
v.gateway = config.get('cloudstack', 'guest.gateway')
v.startip = config.get('cloudstack', 'guest.vlan.startip')
v.endip = config.get('cloudstack', 'guest.vlan.endip')
v.netmask = config.get('cloudstack', 'guest.netmask')
v.vlan = config.get('cloudstack', 'guest.vlan')
z.ipranges.append(v)
c = cluster()
c.clustername = 'C0'
c.hypervisor = config.get('cloudstack', 'hypervisor')
c.clustertype = 'CloudManaged'
h = host()
h.username = 'root'
h.password = config.get('cloudstack', 'host.password')
h.url = 'http://%s'%(config.get('cloudstack', 'host'))
c.hosts.append(h)
ps = primaryStorage()
ps.name = 'PS0'
ps.url = config.get('cloudstack', 'primary.pool')
c.primaryStorages.append(ps)
p.clusters.append(c)
z.pods.append(p)
secondary = secondaryStorage()
secondary.url = config.get('cloudstack', 'secondary.pool')
z.secondaryStorages.append(secondary)
'''Add zone'''
zs.zones.append(z)
'''Add mgt server'''
mgt = managementServer()
mgt.mgtSvrIp = config.get('environment', 'mshost')
mgt.user = config.get('environment', 'mshost.user')
mgt.passwd = config.get('environment', 'mshost.passwd')
zs.mgtSvr.append(mgt)
'''Add a database'''
db = dbServer()
db.dbSvr = config.get('environment', 'mysql.host')
db.user = config.get('environment', 'mysql.cloud.user')
db.passwd = config.get('environment', 'mysql.cloud.passwd')
zs.dbSvr = db
'''Add some configuration'''
[zs.globalConfig.append(cfg) for cfg in getGlobalSettings(config)]
''''add loggers'''
testClientLogger = logger()
testClientLogger.name = 'TestClient'
testClientLogger.file = 'testclient.log'
testCaseLogger = logger()
testCaseLogger.name = 'TestCase'
testCaseLogger.file = 'testcase.log'
zs.logger.append(testClientLogger)
zs.logger.append(testCaseLogger)
return zs
if __name__ == '__main__':
parser = OptionParser()
parser.add_option('-i', '--input', action='store', default='setup.properties', \
dest='input', help='file containing environment setup information')
parser.add_option('-o', '--output', action='store', default='./sandbox.cfg', \
dest='output', help='path where environment json will be generated')
(opts, args) = parser.parse_args()
cfg_parser = SafeConfigParser()
cfg_parser.read(opts.input)
cfg = describeResources(cfg_parser)
generate_setup_config(cfg, opts.output)

View File

@ -0,0 +1,61 @@
# 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.
[globals]
#global settings in cloudstack
expunge.delay=60
expunge.interval=60
storage.cleanup.interval=300
account.cleanup.interval=600
expunge.workers=3
workers=10
vm.allocation.algorithm=random
vm.op.wait.interval=5
guest.domain.suffix=sandbox.simulator
instance.name=QA
direct.agent.load.size=1000
default.page.size=10000
check.pod.cidrs=true
secstorage.allowed.internal.sites=10.147.28.0/24
[environment]
dns=10.147.28.6
mshost=localhost
mshost.user=root
mshost.passwd=password
mysql.host=localhost
mysql.cloud.user=cloud
mysql.cloud.passwd=cloud
[cloudstack]
#management network
private.gateway=10.147.29.1
private.pod.startip=10.147.29.150
private.pod.endip=10.147.29.159
private.netmask=255.255.255.0
#guest network
guest.gateway=10.147.31.1
guest.vlan=31
guest.vlan.startip=10.147.31.150
guest.vlan.endip=10.147.31.159
guest.netmask=255.255.255.0
#hypervisor host information
hypervisor=Simulator
host=simulator0
host.password=password
#storage pools
primary.pool=nfs://10.147.28.6:/export/home/sandbox/primary
secondary.pool=nfs://10.147.28.6:/export/home/sandbox/sstor

View File

@ -45,7 +45,7 @@ setup(name="Marvin",
url="https://builds.apache.org/job/cloudstack-marvin/",
packages=["marvin", "marvin.cloudstackAPI", "marvin.integration",
"marvin.integration.lib", "marvin.sandbox",
"marvin.sandbox.advanced", "marvin.sandbox.basic"],
"marvin.sandbox.advanced", "marvin.sandbox.advancedsg", "marvin.sandbox.basic"],
license="LICENSE.txt",
install_requires=[
"mysql-connector-python",