Merge pull request #1023 from ekholabs/fix/egress_state-CLOUDSTACK-8925

CLOUDSTACK-8925 - Default allow for Egress rules is not being configured properly in VR iptables rulesThis PR fixes the router default policy for egress. When the default is DENY, the router still allows outgoing connections.

The test component/test_routers_network_ops.py was improved to cover that case as well. The results were:

Test redundant router internals ... === TestName: test_01_isolate_network_FW_PF_default_routes_egress_true | Status : SUCCESS ===
ok
Test redundant router internals ... === TestName: test_02_isolate_network_FW_PF_default_routes_egress_false | Status : SUCCESS ===
ok
Test redundant router internals ... === TestName: test_01_RVR_Network_FW_PF_SSH_default_routes_egress_true | Status : SUCCESS ===
ok
Test redundant router internals ... === TestName: test_02_RVR_Network_FW_PF_SSH_default_routes_egress_false | Status : SUCCESS ===
ok

----------------------------------------------------------------------
Ran 4 tests in 3636.656s

OK
/tmp//MarvinLogs/test_routers_network_ops_QDL429/results.txt (END)

* pr/1023:
  CLOUDSTACK-8925 - Implement the default egress DENY/ALLOW properly
  CLOUDSTACK-8925 - Improve the default egress tests in order to cover newly entered rules
  CLOUDSTACK-8925 - Add egress dataset to test_data.py
  CLOUDSTACK-8925 - Drop the traffic when default egress is set to false

Signed-off-by: Remi Bergsma <github@remi.nl>
This commit is contained in:
Remi Bergsma 2015-11-04 14:59:02 +01:00
commit f948e96299
3 changed files with 534 additions and 94 deletions

View File

@ -95,14 +95,15 @@ class CsAcl(CsDataBag):
if 'src_port_range' in obj: if 'src_port_range' in obj:
self.rule['first_port'] = obj['src_port_range'][0] self.rule['first_port'] = obj['src_port_range'][0]
self.rule['last_port'] = obj['src_port_range'][1] self.rule['last_port'] = obj['src_port_range'][1]
self.rule['allowed'] = True self.rule['allowed'] = True
self.rule['action'] = "ACCEPT"
if self.rule['type'] == 'all' and not obj['source_cidr_list']: if self.rule['type'] == 'all' and not obj['source_cidr_list']:
self.rule['cidr'] = ['0.0.0.0/0'] self.rule['cidr'] = ['0.0.0.0/0']
else: else:
self.rule['cidr'] = obj['source_cidr_list'] self.rule['cidr'] = obj['source_cidr_list']
self.rule['action'] = "ACCEPT"
logging.debug("AclIP created for rule ==> %s", self.rule) logging.debug("AclIP created for rule ==> %s", self.rule)
def create(self): def create(self):
@ -151,7 +152,25 @@ class CsAcl(CsDataBag):
" -m %s " % rule['protocol'] + " -m %s " % rule['protocol'] +
" --icmp-type %s -j %s" % (icmp_type, self.rule['action'])]) " --icmp-type %s -j %s" % (icmp_type, self.rule['action'])])
else: else:
fwr = " -A FW_EGRESS_RULES" fwr = " -I FW_EGRESS_RULES"
#In case we have a default rule (accept all or drop all), we have to evaluate the action again.
if rule['type'] == 'all' and not rule['source_cidr_list']:
fwr = " -A FW_EGRESS_RULES"
# For default egress ALLOW or DENY, the logic is inverted.
# Having default_egress_policy == True, means that the default rule should have ACCEPT,
# otherwise DROP. The rule should be appended, not inserted.
if self.rule['default_egress_policy']:
self.rule['action'] = "ACCEPT"
else:
self.rule['action'] = "DROP"
else:
# For other rules added, if default_egress_policy == True, following rules should be DROP,
# otherwise ACCEPT
if self.rule['default_egress_policy']:
self.rule['action'] = "DROP"
else:
self.rule['action'] = "ACCEPT"
if rule['protocol'] != "all": if rule['protocol'] != "all":
fwr += " -s %s " % cidr + \ fwr += " -s %s " % cidr + \
" -p %s " % rule['protocol'] + \ " -p %s " % rule['protocol'] + \
@ -226,7 +245,7 @@ class CsAcl(CsDataBag):
self.protocol = rule['protocol'] self.protocol = rule['protocol']
self.action = "DROP" self.action = "DROP"
self.dport = "" self.dport = ""
if 'allowed' in rule.keys() and rule['allowed'] and rule['allowed']: if 'allowed' in rule.keys() and rule['allowed']:
self.action = "ACCEPT" self.action = "ACCEPT"
if 'first_port' in rule.keys(): if 'first_port' in rule.keys():
self.dport = "-m %s --dport %s" % (self.protocol, rule['first_port']) self.dport = "-m %s --dport %s" % (self.protocol, rule['first_port'])

View File

@ -33,7 +33,8 @@ from marvin.lib.base import (ServiceOffering,
PublicIPAddress, PublicIPAddress,
NetworkOffering, NetworkOffering,
Network, Network,
Router) Router,
EgressFireWallRule)
from marvin.lib.common import (get_zone, from marvin.lib.common import (get_zone,
get_template, get_template,
get_domain, get_domain,
@ -50,11 +51,27 @@ from marvin.lib.common import (get_zone,
import time import time
import logging import logging
def check_router_command(virtual_machine, public_ip, ssh_command, check_string, test_case, retries=5):
result = 'failed'
try:
ssh = virtual_machine.get_ssh_client(ipaddress=public_ip, retries=retries)
result = str(ssh.execute(ssh_command))
except Exception as e:
test_case.fail("Failed to SSH into the Virtual Machine: %s" % e)
logging.debug("Result from SSH into the Virtual Machine: %s" % result)
return result.count(check_string)
class TestRedundantIsolateNetworks(cloudstackTestCase): class TestRedundantIsolateNetworks(cloudstackTestCase):
@classmethod @classmethod
def setUpClass(cls): def setUpClass(cls):
cls.logger = logging.getLogger('TestRedundantIsolateNetworks')
cls.stream_handler = logging.StreamHandler()
cls.logger.setLevel(logging.DEBUG)
cls.logger.addHandler(cls.stream_handler)
cls.testClient = super(TestRedundantIsolateNetworks, cls).getClsTestClient() cls.testClient = super(TestRedundantIsolateNetworks, cls).getClsTestClient()
cls.api_client = cls.testClient.getApiClient() cls.api_client = cls.testClient.getApiClient()
@ -82,25 +99,49 @@ class TestRedundantIsolateNetworks(cloudstackTestCase):
cls.services["service_offering"] cls.services["service_offering"]
) )
cls.services["nw_off_persistent_RVR"]["egress_policy"] = "true" cls.services["nw_off_persistent_RVR_egress_true"] = cls.services["nw_off_persistent_RVR"].copy()
cls.services["nw_off_persistent_RVR_egress_true"]["egress_policy"] = "true"
cls.network_offering = NetworkOffering.create( cls.services["nw_off_persistent_RVR_egress_false"] = cls.services["nw_off_persistent_RVR"].copy()
cls.services["nw_off_persistent_RVR_egress_false"]["egress_policy"] = "false"
cls.logger.debug("Creating Network Offering with default egress TRUE")
cls.network_offering_egress_true = NetworkOffering.create(
cls.api_client, cls.api_client,
cls.services["nw_off_persistent_RVR"], cls.services["nw_off_persistent_RVR_egress_true"],
conservemode=True conservemode=True
) )
cls.network_offering.update(cls.api_client, state='Enabled') cls.network_offering_egress_true.update(cls.api_client, state='Enabled')
cls.logger.debug("Creating Network Offering with default egress FALSE")
cls.network_offering_egress_false = NetworkOffering.create(
cls.api_client,
cls.services["nw_off_persistent_RVR_egress_false"],
conservemode=True
)
cls.network_offering_egress_false.update(cls.api_client, state='Enabled')
cls.services["egress_80"] = {
"startport": 80,
"endport": 80,
"protocol": "TCP",
"cidrlist": ["0.0.0.0/0"]
}
cls.services["egress_53"] = {
"startport": 53,
"endport": 53,
"protocol": "UDP",
"cidrlist": ["0.0.0.0/0"]
}
cls._cleanup = [ cls._cleanup = [
cls.service_offering, cls.service_offering,
cls.network_offering, cls.network_offering_egress_true,
cls.network_offering_egress_false,
cls.account
] ]
cls.logger = logging.getLogger('TestRedundantIsolateNetworks')
cls.stream_handler = logging.StreamHandler()
cls.logger.setLevel(logging.DEBUG)
cls.logger.addHandler(cls.stream_handler)
return return
@classmethod @classmethod
@ -113,14 +154,7 @@ class TestRedundantIsolateNetworks(cloudstackTestCase):
def setUp(self): def setUp(self):
self.apiclient = self.testClient.getApiClient() self.apiclient = self.testClient.getApiClient()
self.account = Account.create(
self.apiclient,
self.services["account"],
admin=True,
domainid=self.domain.id
)
self.cleanup = [] self.cleanup = []
self.cleanup.insert(0, self.account)
return return
def tearDown(self): def tearDown(self):
@ -131,17 +165,17 @@ class TestRedundantIsolateNetworks(cloudstackTestCase):
return return
@attr(tags=["advanced", "advancedns", "ssh"], required_hardware="true") @attr(tags=["advanced", "advancedns", "ssh"], required_hardware="true")
def test_RVR_Network_FW_PF_SSH_default_routes(self): def test_01_RVR_Network_FW_PF_SSH_default_routes_egress_true(self):
""" Test redundant router internals """ """ Test redundant router internals """
self.logger.debug("Starting test_RVR_Network_FW_PF_SSH_default_routes...") self.logger.debug("Starting test_01_RVR_Network_FW_PF_SSH_default_routes_egress_true...")
self.logger.debug("Creating network with network offering: %s" % self.network_offering.id) self.logger.debug("Creating network with network offering: %s" % self.network_offering_egress_true.id)
network = Network.create( network = Network.create(
self.apiclient, self.apiclient,
self.services["network"], self.services["network"],
accountid=self.account.name, accountid=self.account.name,
domainid=self.account.domainid, domainid=self.account.domainid,
networkofferingid=self.network_offering.id, networkofferingid=self.network_offering_egress_true.id,
zoneid=self.zone.id zoneid=self.zone.id
) )
self.logger.debug("Created network with ID: %s" % network.id) self.logger.debug("Created network with ID: %s" % network.id)
@ -205,18 +239,161 @@ class TestRedundantIsolateNetworks(cloudstackTestCase):
"Length of the list router should be 2 (Backup & master)" "Length of the list router should be 2 (Backup & master)"
) )
self.logger.debug("Associating public IP for network: %s" % network.name) public_ips = list_publicIP(
public_ip = PublicIPAddress.create( self.apiclient,
account=self.account.name,
domainid=self.account.domainid,
zoneid=self.zone.id
)
public_ip = public_ips[0]
self.assertEqual(
isinstance(public_ips, list),
True,
"Check for list public IPs response return valid data"
)
self.logger.debug("Creating Firewall rule for VM ID: %s" % virtual_machine.id)
FireWallRule.create(
self.apiclient,
ipaddressid=public_ip.id,
protocol=self.services["natrule"]["protocol"],
cidrlist=['0.0.0.0/0'],
startport=self.services["natrule"]["publicport"],
endport=self.services["natrule"]["publicport"]
)
self.logger.debug("Creating NAT rule for VM ID: %s" % virtual_machine.id)
nat_rule = NATRule.create(
self.apiclient,
virtual_machine,
self.services["natrule"],
public_ip.id
)
self.cleanup.insert(0, network)
self.cleanup.insert(0, virtual_machine)
# Test SSH after closing port 22
expected = 1
ssh_command = "ping -c 3 8.8.8.8"
check_string = "3 packets received"
result = check_router_command(virtual_machine, nat_rule.ipaddress, ssh_command, check_string, self)
self.assertEqual(
result,
expected,
"Ping to outside world from VM should be successful!"
)
expected = 1
ssh_command = "wget -t 1 -T 5 www.google.com"
check_string = "HTTP request sent, awaiting response... 200 OK"
result = check_router_command(virtual_machine, nat_rule.ipaddress, ssh_command, check_string, self)
self.assertEqual(
result,
expected,
"Attempt to retrieve google.com index page should be successful!"
)
EgressFireWallRule.create(
self.apiclient,
networkid=network.id,
protocol=self.services["egress_80"]["protocol"],
startport=self.services["egress_80"]["startport"],
endport=self.services["egress_80"]["endport"],
cidrlist=self.services["egress_80"]["cidrlist"]
)
expected = 0
ssh_command = "wget -t 1 -T 1 www.google.com"
check_string = "HTTP request sent, awaiting response... 200 OK"
result = check_router_command(virtual_machine, nat_rule.ipaddress, ssh_command, check_string, self)
self.assertEqual(
result,
expected,
"Attempt to retrieve google.com index page should NOT be successful once rule is added!"
)
return
@attr(tags=["advanced", "advancedns", "ssh"], required_hardware="true")
def test_02_RVR_Network_FW_PF_SSH_default_routes_egress_false(self):
""" Test redundant router internals """
self.logger.debug("Starting test_02_RVR_Network_FW_PF_SSH_default_routes_egress_false...")
self.logger.debug("Creating network with network offering: %s" % self.network_offering_egress_false.id)
network = Network.create(
self.apiclient, self.apiclient,
self.services["network"],
accountid=self.account.name, accountid=self.account.name,
zoneid=self.zone.id,
domainid=self.account.domainid, domainid=self.account.domainid,
networkid=network.id networkofferingid=self.network_offering_egress_false.id,
zoneid=self.zone.id
) )
self.logger.debug("Associated %s with network %s" % ( self.logger.debug("Created network with ID: %s" % network.id)
public_ip.ipaddress.ipaddress,
network.id networks = Network.list(
)) self.apiclient,
id=network.id,
listall=True
)
self.assertEqual(
isinstance(networks, list),
True,
"List networks should return a valid response for created network"
)
nw_response = networks[0]
self.logger.debug("Deploying VM in account: %s" % self.account.name)
virtual_machine = VirtualMachine.create(
self.apiclient,
self.services["virtual_machine"],
templateid=self.template.id,
accountid=self.account.name,
domainid=self.account.domainid,
serviceofferingid=self.service_offering.id,
networkids=[str(network.id)]
)
self.logger.debug("Deployed VM in network: %s" % network.id)
vms = VirtualMachine.list(
self.apiclient,
id=virtual_machine.id,
listall=True
)
self.assertEqual(
isinstance(vms, list),
True,
"List Vms should return a valid list"
)
vm = vms[0]
self.assertEqual(
vm.state,
"Running",
"VM should be in running state after deployment"
)
self.logger.debug("Listing routers for network: %s" % network.name)
routers = Router.list(
self.apiclient,
networkid=network.id,
listall=True
)
self.assertEqual(
isinstance(routers, list),
True,
"list router should return Master and backup routers"
)
self.assertEqual(
len(routers),
2,
"Length of the list router should be 2 (Backup & master)"
)
public_ips = list_publicIP( public_ips = list_publicIP(
self.apiclient, self.apiclient,
@ -231,12 +408,12 @@ class TestRedundantIsolateNetworks(cloudstackTestCase):
"Check for list public IPs response return valid data" "Check for list public IPs response return valid data"
) )
public_ip_1 = public_ips[0] public_ip = public_ips[0]
self.logger.debug("Creating Firewall rule for VM ID: %s" % virtual_machine.id) self.logger.debug("Creating Firewall rule for VM ID: %s" % virtual_machine.id)
FireWallRule.create( FireWallRule.create(
self.apiclient, self.apiclient,
ipaddressid=public_ip_1.id, ipaddressid=public_ip.id,
protocol=self.services["natrule"]["protocol"], protocol=self.services["natrule"]["protocol"],
cidrlist=['0.0.0.0/0'], cidrlist=['0.0.0.0/0'],
startport=self.services["natrule"]["publicport"], startport=self.services["natrule"]["publicport"],
@ -248,27 +425,61 @@ class TestRedundantIsolateNetworks(cloudstackTestCase):
self.apiclient, self.apiclient,
virtual_machine, virtual_machine,
self.services["natrule"], self.services["natrule"],
public_ip_1.id public_ip.id
) )
self.cleanup.insert(0, network) self.cleanup.insert(0, network)
self.cleanup.insert(0, virtual_machine) self.cleanup.insert(0, virtual_machine)
result = 'failed' expected = 0
try: ssh_command = "ping -c 3 8.8.8.8"
ssh_command = "ping -c 3 8.8.8.8" check_string = "3 packets received"
ssh = virtual_machine.get_ssh_client(ipaddress=public_ip.ipaddress.ipaddress, retries=5) result = check_router_command(virtual_machine, nat_rule.ipaddress, ssh_command, check_string, self)
self.logger.debug("Ping to google.com from VM")
result = str(ssh.execute(ssh_command))
self.logger.debug("SSH result: %s; COUNT is ==> %s" % (result, result.count("3 packets received")))
except:
self.fail("Failed to SSH into VM - %s" % (public_ip.ipaddress.ipaddress))
self.assertEqual( self.assertEqual(
result.count("3 packets received"), result,
1, expected,
"Ping to outside world from VM should be successful" "Ping to outside world from VM should NOT be successful"
)
expected = 0
ssh_command = "wget -t 1 -T 1 www.google.com"
check_string = "HTTP request sent, awaiting response... 200 OK"
result = check_router_command(virtual_machine, nat_rule.ipaddress, ssh_command, check_string, self)
self.assertEqual(
result,
expected,
"Attempt to retrieve google.com index page should NOT be successful"
)
EgressFireWallRule.create(
self.apiclient,
networkid=network.id,
protocol=self.services["egress_80"]["protocol"],
startport=self.services["egress_80"]["startport"],
endport=self.services["egress_80"]["endport"],
cidrlist=self.services["egress_80"]["cidrlist"]
)
EgressFireWallRule.create(
self.apiclient,
networkid=network.id,
protocol=self.services["egress_53"]["protocol"],
startport=self.services["egress_53"]["startport"],
endport=self.services["egress_53"]["endport"],
cidrlist=self.services["egress_53"]["cidrlist"]
)
expected = 1
ssh_command = "wget -t 1 -T 5 www.google.com"
check_string = "HTTP request sent, awaiting response... 200 OK"
result = check_router_command(virtual_machine, nat_rule.ipaddress, ssh_command, check_string, self)
self.assertEqual(
result,
expected,
"Attempt to retrieve google.com index page should be successful once rule is added!"
) )
return return
@ -279,6 +490,11 @@ class TestIsolatedNetworks(cloudstackTestCase):
@classmethod @classmethod
def setUpClass(cls): def setUpClass(cls):
cls.logger = logging.getLogger('TestIsolatedNetworks')
cls.stream_handler = logging.StreamHandler()
cls.logger.setLevel(logging.DEBUG)
cls.logger.addHandler(cls.stream_handler)
cls.testClient = super(TestIsolatedNetworks, cls).getClsTestClient() cls.testClient = super(TestIsolatedNetworks, cls).getClsTestClient()
cls.api_client = cls.testClient.getApiClient() cls.api_client = cls.testClient.getApiClient()
@ -287,7 +503,7 @@ class TestIsolatedNetworks(cloudstackTestCase):
cls.domain = get_domain(cls.api_client) cls.domain = get_domain(cls.api_client)
cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests())
cls.services['mode'] = cls.zone.networktype cls.services['mode'] = cls.zone.networktype
template = get_template( cls.template = get_template(
cls.api_client, cls.api_client,
cls.zone.id, cls.zone.id,
cls.services["ostype"] cls.services["ostype"]
@ -306,42 +522,40 @@ class TestIsolatedNetworks(cloudstackTestCase):
cls.services["service_offering"] cls.services["service_offering"]
) )
cls.services["network_offering"]["egress_policy"] = "true" cls.services["network_offering_egress_true"] = cls.services["network_offering"].copy()
cls.services["network_offering_egress_true"]["egress_policy"] = "true"
cls.network_offering = NetworkOffering.create(cls.api_client, cls.services["network_offering_egress_false"] = cls.services["network_offering"].copy()
cls.services["network_offering"], cls.services["network_offering_egress_false"]["egress_policy"] = "false"
cls.logger.debug("Creating Network Offering with default egress TRUE")
cls.network_offering_egress_true = NetworkOffering.create(cls.api_client,
cls.services["network_offering_egress_true"],
conservemode=True) conservemode=True)
cls.network_offering.update(cls.api_client, state='Enabled') cls.network_offering_egress_true.update(cls.api_client, state='Enabled')
cls.network = Network.create(cls.api_client, cls.logger.debug("Creating Network Offering with default egress FALSE")
cls.services["network"], cls.network_offering_egress_false = NetworkOffering.create(cls.api_client,
accountid=cls.account.name, cls.services["network_offering_egress_false"],
domainid=cls.account.domainid, conservemode=True)
networkofferingid=cls.network_offering.id,
zoneid=cls.zone.id)
cls.vm_1 = VirtualMachine.create(cls.api_client, cls.network_offering_egress_false.update(cls.api_client, state='Enabled')
cls.services["virtual_machine"],
templateid=template.id, cls.services["egress_80"] = {
accountid=cls.account.name, "startport": 80,
domainid=cls.domain.id, "endport": 80,
serviceofferingid=cls.service_offering.id, "protocol": "TCP",
networkids=[str(cls.network.id)]) "cidrlist": ["0.0.0.0/0"]
}
cls._cleanup = [ cls._cleanup = [
cls.vm_1, cls.network_offering_egress_true,
cls.network, cls.network_offering_egress_false,
cls.network_offering,
cls.service_offering, cls.service_offering,
cls.account cls.account
] ]
cls.logger = logging.getLogger('TestIsolatedNetworks')
cls.stream_handler = logging.StreamHandler()
cls.logger.setLevel(logging.DEBUG)
cls.logger.addHandler(cls.stream_handler)
return return
@classmethod @classmethod
@ -354,11 +568,40 @@ class TestIsolatedNetworks(cloudstackTestCase):
def setUp(self): def setUp(self):
self.apiclient = self.testClient.getApiClient() self.apiclient = self.testClient.getApiClient()
self.cleanup = []
return
def tearDown(self):
try:
cleanup_resources(self.apiclient, self.cleanup)
except Exception as e:
raise Exception("Warning: Exception during cleanup : %s" % e)
return return
@attr(tags=["advanced", "advancedns", "ssh"], required_hardware="true") @attr(tags=["advanced", "advancedns", "ssh"], required_hardware="true")
def test_isolate_network_FW_PF_default_routes(self): def test_01_isolate_network_FW_PF_default_routes_egress_true(self):
"""Stop existing router, add a PF rule and check we can access the VM """ """ Test redundant router internals """
self.logger.debug("Starting test_01_isolate_network_FW_PF_default_routes_egress_true...")
self.logger.debug("Creating Network with Network Offering ID %s" % self.network_offering_egress_true.id)
network = Network.create(self.apiclient,
self.services["network"],
accountid=self.account.name,
domainid=self.account.domainid,
networkofferingid=self.network_offering_egress_true.id,
zoneid=self.zone.id)
self.logger.debug("Creating Virtual Machine on Network %s" % network.id)
virtual_machine = VirtualMachine.create(self.apiclient,
self.services["virtual_machine"],
templateid=self.template.id,
accountid=self.account.name,
domainid=self.domain.id,
serviceofferingid=self.service_offering.id,
networkids=[str(network.id)])
self.cleanup.insert(0, network)
self.cleanup.insert(0, virtual_machine)
self.logger.debug("Starting test_isolate_network_FW_PF_default_routes...") self.logger.debug("Starting test_isolate_network_FW_PF_default_routes...")
routers = list_routers( routers = list_routers(
@ -402,7 +645,7 @@ class TestIsolatedNetworks(cloudstackTestCase):
public_ip = public_ips[0] public_ip = public_ips[0]
self.logger.debug("Creating Firewall rule for VM ID: %s" % self.vm_1.id) self.logger.debug("Creating Firewall rule for VM ID: %s" % virtual_machine.id)
FireWallRule.create( FireWallRule.create(
self.apiclient, self.apiclient,
ipaddressid=public_ip.id, ipaddressid=public_ip.id,
@ -412,11 +655,11 @@ class TestIsolatedNetworks(cloudstackTestCase):
endport=self.services["natrule"]["publicport"] endport=self.services["natrule"]["publicport"]
) )
self.logger.debug("Creating NAT rule for VM ID: %s" % self.vm_1.id) self.logger.debug("Creating NAT rule for VM ID: %s" % virtual_machine.id)
# Create NAT rule # Create NAT rule
nat_rule = NATRule.create( nat_rule = NATRule.create(
self.apiclient, self.apiclient,
self.vm_1, virtual_machine,
self.services["natrule"], self.services["natrule"],
public_ip.id public_ip.id
) )
@ -436,20 +679,192 @@ class TestIsolatedNetworks(cloudstackTestCase):
"Check list port forwarding rules" "Check list port forwarding rules"
) )
result = 'failed' # Test SSH after closing port 22
try: expected = 1
ssh_command = "ping -c 3 8.8.8.8" ssh_command = "ping -c 3 8.8.8.8"
self.logger.debug("SSH into VM with IP: %s" % nat_rule.ipaddress) check_string = "3 packets received"
result = check_router_command(virtual_machine, nat_rule.ipaddress, ssh_command, check_string, self)
ssh = self.vm_1.get_ssh_client(ipaddress=nat_rule.ipaddress, port=self.services["natrule"]["publicport"], retries=5)
result = str(ssh.execute(ssh_command))
self.logger.debug("SSH result: %s; COUNT is ==> %s" % (result, result.count("3 packets received")))
except:
self.fail("Failed to SSH into VM - %s" % (nat_rule.ipaddress))
self.assertEqual( self.assertEqual(
result.count("3 packets received"), result,
1, expected,
"Ping to outside world from VM should be successful" "Ping to outside world from VM should be successful!"
) )
expected = 1
ssh_command = "wget -t 1 -T 5 www.google.com"
check_string = "HTTP request sent, awaiting response... 200 OK"
result = check_router_command(virtual_machine, nat_rule.ipaddress, ssh_command, check_string, self)
self.assertEqual(
result,
expected,
"Attempt to retrieve google.com index page should be successful!"
)
EgressFireWallRule.create(
self.apiclient,
networkid=network.id,
protocol=self.services["egress_80"]["protocol"],
startport=self.services["egress_80"]["startport"],
endport=self.services["egress_80"]["endport"],
cidrlist=self.services["egress_80"]["cidrlist"]
)
expected = 0
ssh_command = "wget -t 1 -T 1 www.google.com"
check_string = "HTTP request sent, awaiting response... 200 OK"
result = check_router_command(virtual_machine, nat_rule.ipaddress, ssh_command, check_string, self)
self.assertEqual(
result,
expected,
"Attempt to retrieve google.com index page should NOT be successful once rule is added!"
)
return
@attr(tags=["advanced", "advancedns", "ssh"], required_hardware="true")
def test_02_isolate_network_FW_PF_default_routes_egress_false(self):
""" Test redundant router internals """
self.logger.debug("Starting test_02_isolate_network_FW_PF_default_routes_egress_false...")
self.logger.debug("Creating Network with Network Offering ID %s" % self.network_offering_egress_false.id)
network = Network.create(self.apiclient,
self.services["network"],
accountid=self.account.name,
domainid=self.account.domainid,
networkofferingid=self.network_offering_egress_false.id,
zoneid=self.zone.id)
self.logger.debug("Creating Virtual Machine on Network %s" % network.id)
virtual_machine = VirtualMachine.create(self.apiclient,
self.services["virtual_machine"],
templateid=self.template.id,
accountid=self.account.name,
domainid=self.domain.id,
serviceofferingid=self.service_offering.id,
networkids=[str(network.id)])
self.cleanup.insert(0, network)
self.cleanup.insert(0, virtual_machine)
self.logger.debug("Starting test_isolate_network_FW_PF_default_routes...")
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.assertNotEqual(
len(routers),
0,
"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"
)
public_ip = public_ips[0]
self.logger.debug("Creating Firewall rule for VM ID: %s" % virtual_machine.id)
FireWallRule.create(
self.apiclient,
ipaddressid=public_ip.id,
protocol=self.services["natrule"]["protocol"],
cidrlist=['0.0.0.0/0'],
startport=self.services["natrule"]["publicport"],
endport=self.services["natrule"]["publicport"]
)
self.logger.debug("Creating NAT rule for VM ID: %s" % virtual_machine.id)
# Create NAT rule
nat_rule = NATRule.create(
self.apiclient,
virtual_machine,
self.services["natrule"],
public_ip.id
)
nat_rules = list_nat_rules(
self.apiclient,
id=nat_rule.id
)
self.assertEqual(
isinstance(nat_rules, list),
True,
"Check for list NAT rules response return valid data"
)
self.assertEqual(
nat_rules[0].state,
'Active',
"Check list port forwarding rules"
)
expected = 0
ssh_command = "ping -c 3 8.8.8.8"
check_string = "3 packets received"
result = check_router_command(virtual_machine, nat_rule.ipaddress, ssh_command, check_string, self)
self.assertEqual(
result,
expected,
"Ping to outside world from VM should NOT be successful"
)
expected = 0
ssh_command = "wget -t 1 -T 1 www.google.com"
check_string = "HTTP request sent, awaiting response... 200 OK"
result = check_router_command(virtual_machine, nat_rule.ipaddress, ssh_command, check_string, self)
self.assertEqual(
result,
expected,
"Attempt to retrieve google.com index page should NOT be successful"
)
EgressFireWallRule.create(
self.apiclient,
networkid=network.id,
protocol=self.services["egress_80"]["protocol"],
startport=self.services["egress_80"]["startport"],
endport=self.services["egress_80"]["endport"],
cidrlist=self.services["egress_80"]["cidrlist"]
)
expected = 1
ssh_command = "wget -t 1 -T 5 www.google.com"
check_string = "HTTP request sent, awaiting response... 200 OK"
result = check_router_command(virtual_machine, nat_rule.ipaddress, ssh_command, check_string, self)
self.assertEqual(
result,
expected,
"Attempt to retrieve google.com index page should be successful once rule is added!"
)
return return

View File

@ -715,6 +715,12 @@ test_data = {
"publicport": 22, "publicport": 22,
"protocol": "TCP" "protocol": "TCP"
}, },
"egress_80": {
"startport": 80,
"endport": 80,
"protocol": "TCP",
"cidrlist": ["0.0.0.0/0"]
},
"lbrule": { "lbrule": {
"name": "SSH", "name": "SSH",
"alg": "roundrobin", "alg": "roundrobin",