From b83aa2a50bcead9eccc85eac0cd32d416d47d64e Mon Sep 17 00:00:00 2001 From: Abhinandan Prateek Date: Fri, 28 Jul 2017 13:38:57 +0530 Subject: [PATCH] CLOUDSTACK-10021: Marvin test to check VR internal DNS Service (#1784) --- .../smoke/test_router_dnsservice.py | 275 ++++++++++++++++++ 1 file changed, 275 insertions(+) create mode 100644 test/integration/smoke/test_router_dnsservice.py diff --git a/test/integration/smoke/test_router_dnsservice.py b/test/integration/smoke/test_router_dnsservice.py new file mode 100644 index 00000000000..436d9e4382e --- /dev/null +++ b/test/integration/smoke/test_router_dnsservice.py @@ -0,0 +1,275 @@ +# 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 logging +import dns.resolver + +from nose.plugins.attrib import attr +from marvin.cloudstackTestCase import cloudstackTestCase +from marvin.lib.utils import cleanup_resources +from marvin.lib.base import (ServiceOffering, + VirtualMachine, + Account, + NATRule, + FireWallRule, + NetworkOffering, + Network) +from marvin.lib.common import (get_zone, + get_template, + get_domain, + list_routers, + list_nat_rules, + list_publicIP) + +VM1_NAME="drump" +VM2_NAME="dilton" + +class TestRouterDnsService(cloudstackTestCase): + + + @classmethod + def setUpClass(cls): + cls.logger = logging.getLogger('TestRouterDnsService') + cls.stream_handler = logging.StreamHandler() + cls.logger.setLevel(logging.DEBUG) + cls.logger.addHandler(cls.stream_handler) + + cls.testClient = super(TestRouterDnsService, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = cls.testClient.getParsedTestDataConfig() + + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) + cls.services['mode'] = cls.zone.networktype + cls.template = get_template( + cls.api_client, + cls.zone.id, + cls.services["ostype"] + ) + cls.services["virtual_machine"]["zoneid"] = cls.zone.id + + cls.logger.debug("Creating Admin Account for domain %s on zone %s" % (cls.domain.id, cls.zone.id)) + cls.account = Account.create( + cls.api_client, + cls.services["account"], + admin=True, + domainid=cls.domain.id + ) + + cls.logger.debug("Creating Service Offering on zone %s" % (cls.zone.id)) + cls.service_offering = ServiceOffering.create( + cls.api_client, + cls.services["service_offering"] + ) + + cls.logger.debug("Creating Network Offering on zone %s" % (cls.zone.id)) + cls.services["isolated_network_offering"]["egress_policy"] = "true" + cls.network_offering = NetworkOffering.create(cls.api_client, + cls.services["isolated_network_offering"], + conservemode=True) + cls.network_offering.update(cls.api_client, state='Enabled') + + cls.logger.debug("Creating Network for Account %s using offering %s" % (cls.account.name, cls.network_offering.id)) + cls.network = Network.create(cls.api_client, + cls.services["network"], + accountid=cls.account.name, + domainid=cls.account.domainid, + networkofferingid=cls.network_offering.id, + zoneid=cls.zone.id) + + cls.logger.debug("Creating guest VM for Account %s using offering %s" % (cls.account.name, cls.service_offering.id)) + cls.services["virtual_machine"]["displayname"] = VM1_NAME; + cls.services["virtual_machine"]["name"] = VM1_NAME; + cls.vm1 = VirtualMachine.create(cls.api_client, + cls.services["virtual_machine"], + templateid=cls.template.id, + accountid=cls.account.name, + domainid=cls.domain.id, + serviceofferingid=cls.service_offering.id, + networkids=[str(cls.network.id)]) + cls.vm1.password = "password" + cls.logger.debug("Created VM named %s" % VM1_NAME); + + cls.services["virtual_machine"]["displayname"] = VM2_NAME; + cls.services["virtual_machine"]["name"] = VM2_NAME; + cls.vm2 = VirtualMachine.create(cls.api_client, + cls.services["virtual_machine"], + templateid=cls.template.id, + accountid=cls.account.name, + domainid=cls.domain.id, + serviceofferingid=cls.service_offering.id, + networkids=[str(cls.network.id)]) + cls.vm2.password = "password" + cls.logger.debug("Created VM named %s" % VM2_NAME); + + cls.services["natrule1"] = { + "privateport": 22, + "publicport": 22, + "protocol": "TCP" + } + + cls.services["configurableData"] = { + "host": { + "password": "password", + "username": "root", + "port": 22 + }, + "input": "INPUT", + "forward": "FORWARD" + } + + cls._cleanup = [ + cls.vm1, + cls.vm2, + cls.network, + cls.network_offering, + cls.service_offering, + cls.account + ] + + + @classmethod + def tearDownClass(cls): + try: + cleanup_resources(cls.api_client, cls._cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + + + def setUp(self): + self.apiclient = self.testClient.getApiClient() + self.cleanup = [] + + + def tearDown(self): + try: + cleanup_resources(self.apiclient, self.cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + + + def test_router_common(self): + """Performs common router tests and returns router public_ips""" + + routers = list_routers( + self.apiclient, + account=self.account.name, + domainid=self.account.domainid + ) + + self.assertEqual( + isinstance(routers, list), + True, + "Check for list routers response return valid data" + ) + + self.assertTrue( + len(routers) >= 1, + "Check list router response" + ) + + router = routers[0] + + self.assertEqual( + router.state, + 'Running', + "Check list router response for router state" + ) + + public_ips = list_publicIP( + self.apiclient, + account=self.account.name, + domainid=self.account.domainid, + zoneid=self.zone.id + ) + + self.assertEqual( + isinstance(public_ips, list), + True, + "Check for list public IPs response return valid data" + ) + + self.assertTrue( + len(public_ips) >= 1, + "Check public IP list has at least one IP" + ) + return public_ips + + + @attr(tags=["advanced", "advancedns", "ssh"], required_hardware="true") + def test_router_dns_guestipquery(self): + """Checks that guest VM can query VR DNS""" + + self.logger.debug("Starting test_router_dns_guestipquery...") + public_ip = self.test_router_common()[0] + + self.logger.debug("Creating Firewall rule for VM ID: %s" % self.vm1.id) + FireWallRule.create( + self.apiclient, + ipaddressid=public_ip.id, + protocol=self.services["natrule1"]["protocol"], + cidrlist=['0.0.0.0/0'], + startport=self.services["natrule1"]["publicport"], + endport=self.services["natrule1"]["publicport"] + ) + + self.logger.debug("Creating NAT rule for VM ID: %s" % self.vm1.id) + nat_rule1 = NATRule.create( + self.apiclient, + self.vm1, + self.services["natrule1"], + public_ip.id + ) + nat_rules = list_nat_rules( + self.apiclient, + id=nat_rule1.id + ) + self.assertEqual( + isinstance(nat_rules, list), + True, + "Check for list NAT rules response return valid data" + ) + self.assertTrue( + len(nat_rules) >= 1, + "Check for list NAT rules to have at least one rule" + ) + self.assertEqual( + nat_rules[0].state, + 'Active', + "Check list port forwarding rules" + ) + + result1 = None + try: + self.logger.debug("SSH into guest VM with IP: %s" % nat_rule1.ipaddress) + ssh = self.vm1.get_ssh_client(ipaddress=nat_rule1.ipaddress, port=self.services['natrule1']["publicport"], retries=8) + result1 = str(ssh.execute("nslookup %s" % VM1_NAME)) + self.logger.debug("nslookup %s: %s " % (VM1_NAME, result1)) + result2 = str(ssh.execute("nslookup %s" % VM2_NAME)) + self.logger.debug("nslookup %s: %s " % (VM2_NAME, result2)) + except Exception as e: + self.fail("Failed to SSH into VM - %s due to exception: %s" % (nat_rule1.ipaddress, e)) + + if not result1: + self.fail("Did not to receive any response from the guest VM, failing.") + + self.assertTrue(VM1_NAME in result1 and "#53" in result1, + "VR DNS should serve requests from guest network, ping for %s successful." % VM1_NAME) + self.assertTrue(VM2_NAME in result2 and "#53" in result2, + "VR DNS should serve requests from guest network, ping for %s successful." % VM2_NAME) + + return