# 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 import unittest from nose.plugins.attrib import attr from marvin.cloudstackTestCase import cloudstackTestCase from marvin.integration.lib.base import (Account, Domain, Router, Network, ServiceOffering, NetworkOffering, VirtualMachine) from marvin.integration.lib.common import (get_domain, get_zone, get_template, list_hosts, rebootRouter, list_routers, wait_for_cleanup, cleanup_resources) from marvin.cloudstackAPI.createEgressFirewallRule import createEgressFirewallRuleCmd from marvin.cloudstackAPI.deleteEgressFirewallRule import deleteEgressFirewallRuleCmd from marvin.sshClient import SshClient import time class Services: """Test service data: Egress Firewall rules Tests for Advance Zone. """ def __init__(self): self.services = { "host" : {"username": 'root', # Credentials for SSH "password": 'password', "publicport": 22}, "domain" : {"name": "Domain",}, "account" : {"email" : "test@test.com", "firstname" : "Test", "lastname" : "User", "username" : "test", # Random characters are appended in create account to # ensure unique username generated each time "password" : "password",}, "user" : {"email" : "user@test.com", "firstname": "User", "lastname" : "User", "username" : "User", # Random characters are appended for unique # username "password" : "password",}, "project" : {"name" : "Project", "displaytext" : "Test project",}, "volume" : {"diskname" : "TestDiskServ", "max" : 6,}, "disk_offering" : {"displaytext" : "Small", "name" : "Small", "disksize" : 1}, "virtual_machine" : {"displayname" : "testserver", "username" : "root",# VM creds for SSH "password" : "password", "ssh_port" : 22, "hypervisor" : 'XenServer', "privateport" : 22, "publicport" : 22, "protocol" : 'TCP',}, "service_offering" : {"name" : "Tiny Instance", "displaytext" : "Tiny Instance", "cpunumber" : 1, "cpuspeed" : 100,# in MHz "memory" : 128}, "network_offering": { "name": 'Network offering-VR services', "displaytext": 'Network offering-VR services', "guestiptype": 'Isolated', "supportedservices": 'Dhcp,Dns,SourceNat,PortForwarding,Vpn,Firewall,Lb,UserData,StaticNat', "traffictype": 'GUEST', "availability": 'Optional', "specifyVlan": 'False', "serviceProviderList": { "Dhcp": 'VirtualRouter', "Dns": 'VirtualRouter', "SourceNat": 'VirtualRouter', "PortForwarding": 'VirtualRouter', "Vpn": 'VirtualRouter', "Firewall": 'VirtualRouter', "Lb": 'VirtualRouter', "UserData": 'VirtualRouter', "StaticNat": 'VirtualRouter', }, "serviceCapabilityList": { "SourceNat": { "SupportedSourceNatTypes": "peraccount", "RedundantRouter": "true" } }, }, "network" : { "name": "Test Network", "displaytext": "Test Network", }, "sleep" : 30, "ostype": 'CentOS 5.3 (64-bit)', "host_password": 'password', } class TestEgressFWRules(cloudstackTestCase): @classmethod def setUpClass(cls): cls._cleanup = [] cls.api_client = super(TestEgressFWRules, cls).getClsTestClient().getApiClient() cls.services = Services().services # Get Zone Domain and create Domains and sub Domains. cls.domain = get_domain(cls.api_client, cls.services) cls.zone = get_zone(cls.api_client, cls.services) cls.services['mode'] = cls.zone.networktype # Get and set template id for VM creation. 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 parentDomain = None cls.domain = Domain.create(cls.api_client, cls.services["domain"], parentdomainid=parentDomain.id if parentDomain else None) cls._cleanup.append(cls.domain) # Create an Account associated with domain cls.account = Account.create(cls.api_client, cls.services["account"], domainid=cls.domain.id) cls._cleanup.append(cls.account) # Create service offerings. cls.service_offering = ServiceOffering.create(cls.api_client, cls.services["service_offering"]) # Cleanup cls._cleanup.append(cls.service_offering) @classmethod def tearDownClass(cls): try: cleanup_resources(cls.api_client, reversed(cls._cleanup)) except Exception as e: raise Exception("Warning: Exception during cleanup : %s" % e) def setUp(self): self.apiclient = self.api_client self.dbclient = self.testClient.getDbConnection() self.cleanup = [] self.snapshot = None self.egressruleid = None return def create_network_offering(self, egress_policy=True, RR=False): if egress_policy: self.services["network_offering"]["egress_policy"] = "true" else: self.services["network_offering"]["egress_policy"] = "false" if RR: self.debug("Redundant Router Enabled") self.services["network_offering"]["serviceCapabilityList"]["SourceNat"]["RedundantRouter"] = "true" self.network_offering = NetworkOffering.create(self.apiclient, self.services["network_offering"], conservemode=True) # Cleanup self.cleanup.append(self.network_offering) # Enable Network offering self.network_offering.update(self.apiclient, state='Enabled') def create_vm(self, pfrule=False, egress_policy=True, RR=False): self.create_network_offering(egress_policy, RR) # Creating network using the network offering created self.debug("Creating network with network offering: %s" % self.network_offering.id) self.network = Network.create(self.apiclient, self.services["network"], accountid=self.account.name, domainid=self.account.domainid, networkofferingid=self.network_offering.id, zoneid=self.zone.id) self.debug("Created network with ID: %s" % self.network.id) self.debug("Deploying instance in the account: %s" % self.account.name) project = None try: self.virtual_machine = VirtualMachine.create(self.apiclient, self.services["virtual_machine"], accountid=self.account.name, domainid=self.domain.id, serviceofferingid=self.service_offering.id, mode=self.zone.networktype if pfrule else 'basic', networkids=[str(self.network.id)], projectid=project.id if project else None) except Exception as e: self.debug('error=%s' % e) self.debug("Deployed instance in account: %s" % self.account.name) def exec_script_on_user_vm(self, script, exec_cmd_params, expected_result, negative_test=False): try: vm_network_id = self.virtual_machine.nic[0].networkid vm_ipaddress = self.virtual_machine.nic[0].ipaddress list_routers_response = list_routers(self.apiclient, account=self.account.name, domainid=self.account.domainid, networkid=vm_network_id) self.assertEqual(isinstance(list_routers_response, list), True, "Check for list routers response return valid data") router = list_routers_response[0] #Once host or mgt server is reached, SSH to the router connected to VM # look for Router for Cloudstack VM network. if self.apiclient.hypervisor.lower() == 'vmware': #SSH is done via management server for Vmware sourceip = self.apiclient.connection.mgtSvr else: #For others, we will have to get the ipaddress of host connected to vm hosts = list_hosts(self.apiclient, id=router.hostid) self.assertEqual(isinstance(hosts, list), True, "Check list response returns a valid list") host = hosts[0] sourceip = host.ipaddress self.debug("Sleep %s seconds for network on router to be up" % self.services['sleep']) time.sleep(self.services['sleep']) if self.apiclient.hypervisor.lower() == 'vmware': key_file = " -i /var/cloudstack/management/.ssh/id_rsa " else: key_file = " -i /root/.ssh/id_rsa.cloud " ssh_cmd = "ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o LogLevel=quiet" expect_script = "#!/usr/bin/expect\n" + \ "spawn %s %s -p 3922 root@%s\n" % (ssh_cmd, key_file, router.linklocalip) + \ "expect \"root@%s:~#\"\n" % (router.name) + \ "send \"%s root@%s %s; exit $?\r\"\n" % (ssh_cmd, vm_ipaddress, script) + \ "expect \"root@%s's password: \"\n" % (vm_ipaddress) + \ "send \"password\r\"\n" + \ "interact\n" self.debug("expect_script>>\n%s<