diff --git a/test/integration/component/test_egress_fw_rules.py b/test/integration/component/test_egress_fw_rules.py new file mode 100644 index 00000000000..f7fc1495115 --- /dev/null +++ b/test/integration/component/test_egress_fw_rules.py @@ -0,0 +1,958 @@ +# 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.remoteSSHClient import remoteSSHClient +import time + +def log_test_exceptions(func): + """ + """ + def _log_test_exceptions(self, *args, **kwargs): + try: + func(self, *args, **kwargs) + except Exception as e: + self.debug('Test %s Failed due to Exception=%s' % (func, e)) + raise e + return _log_test_exceptions + +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" : "fr3sca",}, + "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 + "storagetype" : "local", + "memory" : 128}, + #"storagetype" : "local"}, + "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": "false", + } + }, + }, + "network" : { + "name": "Test Network", + "displaytext": "Test Network", + }, + "sleep" : 30, + "ostype": 'CentOS 5.3 (64-bit)', + "host_password": 'fr3sca', + } + +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"]["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, networkid = None, 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: + 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=self.virtual_machine.hostid) + self.assertEqual(isinstance(hosts, list), + True, + "Check list response returns a valid list") + host = hosts[0] + sourceip = host.ipaddress + #Once host or mgt server is reached, SSH to the router connected to VM + # look for Router for Cloudstack VM network. + 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] + 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<