Create security groups with ICMP and SSH rules for vPing tests 71/9071/1
authorjose.lausuch <jose.lausuch@ericsson.com>
Tue, 2 Feb 2016 16:49:57 +0000 (17:49 +0100)
committerJose Lausuch <jose.lausuch@ericsson.com>
Tue, 2 Feb 2016 17:27:11 +0000 (17:27 +0000)
JIRA: FUNCTEST-133

Some installers don't allow icmp and TCP port 22 (SSH)
in the default security group. To avoid any dependency
with the installer, vPing will create its own security
group with those rules and delete it afterwards.

Change-Id: I6f31f21c240d80eed8bead638af51aa7e1e92aad
Signed-off-by: jose.lausuch <jose.lausuch@ericsson.com>
(cherry picked from commit ab3413a15aeb3b3669da94fa383ec07212eeb915)

testcases/functest_utils.py
testcases/vPing/CI/libraries/vPing2.py

index debdc38..57ec186 100644 (file)
@@ -423,6 +423,58 @@ def get_security_groups(neutron_client):
         return None
 
 
+def create_security_group(neutron_client, sg_name, sg_description):
+    json_body= {'security_group' : { 'name' : sg_name, \
+                                    'description' : sg_description }}
+    try:
+        secgroup = neutron_client.create_security_group(json_body)
+        return secgroup['security_group']
+    except Exception, e:
+        print "Error [create_security_group(neutron_client, '%s', '%s')]:" % \
+            (sg_name,sg_description), e
+        return False
+
+
+def create_secgroup_rule(neutron_client, sg_id, direction, protocol,
+                         port_range_min = None, port_range_max = None):
+    if port_range_min == None and port_range_max == None:
+        json_body = { 'security_group_rule' : \
+                         { 'direction' : direction, \
+                          'security_group_id' : sg_id, \
+                          'protocol' : protocol } }
+    elif port_range_min != None and port_range_max != None:
+        json_body = { 'security_group_rule' : \
+                             { 'direction' : direction, \
+                              'security_group_id' : sg_id, \
+                              'port_range_min': port_range_min, \
+                              'port_range_max' : port_range_max, \
+                              'protocol' : protocol } }
+    else:
+        print "Error [create_secgroup_rule(neutron_client, '%s', '%s', "\
+            "'%s', '%s', '%s', '%s')]:" %(neutron_client, sg_id, direction, \
+                                port_range_min, port_range_max, protocol),\
+                                " Invalid values for port_range_min, port_range_max"
+        return False
+    try:
+        neutron_client.create_security_group_rule(json_body)
+        return True
+    except Exception, e:
+        print "Error [create_secgroup_rule(neutron_client, '%s', '%s', "\
+            "'%s', '%s', '%s', '%s')]:" %(neutron_client, sg_id, direction, \
+                                port_range_min, port_range_max, protocol), e
+        return False
+
+
+def add_secgroup_to_instance(nova_client, instance_id, secgroup_id):
+    try:
+        nova_client.servers.add_security_group(instance_id, secgroup_id)
+        return True
+    except Exception, e:
+        print "Error [add_secgroup_to_instance(nova_client, '%s', '%s')]: " % \
+            (instance_id, secgroup_id), e
+        return False
+
+
 def update_sg_quota(neutron_client, tenant_id, sg_quota, sg_rule_quota):
     json_body = {"quota": {
         "security_group": sg_quota,
@@ -449,6 +501,7 @@ def delete_security_group(neutron_client, secgroup_id):
 
 
 
+
 #*********************************************
 #   GLANCE
 #*********************************************
index c14be43..1ce6dc9 100644 (file)
@@ -197,7 +197,7 @@ def create_private_neutron_net(neutron):
     return network_dic
 
 
-def cleanup(nova, neutron, image_id, network_dic, port_id1, port_id2):
+def cleanup(nova, neutron, image_id, network_dic, port_id1, port_id2, secgroup_id):
 
     # delete both VMs
     logger.info("Cleaning up...")
@@ -232,7 +232,7 @@ def cleanup(nova, neutron, image_id, network_dic, port_id1, port_id2):
             logger.debug("Instance %s terminated." % NAME_VM_2)
 
     # delete created network
-    logger.info("Deleting network '%s'..." % NEUTRON_PRIVATE_NET_NAME)
+    logger.debug("Deleting network '%s'..." % NEUTRON_PRIVATE_NET_NAME)
     net_id = network_dic["net_id"]
     subnet_id = network_dic["subnet_id"]
     router_id = network_dic["router_id"]
@@ -274,6 +274,12 @@ def cleanup(nova, neutron, image_id, network_dic, port_id1, port_id2):
     logger.debug(
         "Network '%s' deleted successfully" % NEUTRON_PRIVATE_NET_NAME)
 
+    if not functest_utils.delete_security_group(neutron, secgroup_id):
+        logger.error("Unable to delete security group '%s'" % secgroup_id)
+        return False
+    logger.debug(
+        "Security group '%s' deleted successfully" % secgroup_id)
+
     return True
 
 def push_results(start_time_ts, duration, test_status):
@@ -316,7 +322,8 @@ def main():
     if not image_id:
         logger.error("Failed to create a Glance image...")
         return(EXIT_CODE)
-
+    logger.debug("Image '%s' with ID=%s created successfully." %\
+                  (GLANCE_IMAGE_NAME, image_id))
     # Check if the given image exists
     image = functest_utils.get_image_id(glance_client, GLANCE_IMAGE_NAME)
     if image == '':
@@ -353,6 +360,36 @@ def main():
             logger.info("Instance %s found. Deleting..." % server.name)
             server.delete()
 
+    SECGROUP_NAME = "vPing-sg"
+    SECGROUP_DESCR = "Security group for vPing test case"
+    logger.info("Creating security group  '%s'..." % SECGROUP_NAME)
+    SECGROUP = functest_utils.create_security_group(neutron_client,
+                                          SECGROUP_NAME,
+                                          SECGROUP_DESCR)
+    SECGROUP_ID = SECGROUP['id']
+    if not SECGROUP:
+        logger.error("Failed to create the security group...")
+        return(EXIT_CODE)
+    logger.debug("Security group '%s' with ID=%s created successfully." %\
+                  (SECGROUP['name'], SECGROUP_ID))
+
+    logger.debug("Adding ICMP rules in security group '%s'..." % SECGROUP_NAME)
+    if not functest_utils.create_secgroup_rule(neutron_client, SECGROUP_ID, \
+                    'ingress', 'icmp'):
+        logger.error("Failed to create the security group rule...")
+        return(EXIT_CODE)
+
+    logger.debug("Adding SSH rules in security group '%s'..." % SECGROUP_NAME)
+    if not functest_utils.create_secgroup_rule(neutron_client, SECGROUP_ID, \
+                    'ingress', 'tcp', '22', '22'):
+        logger.error("Failed to create the security group rule...")
+        return(EXIT_CODE)
+
+    if not functest_utils.create_secgroup_rule(neutron_client, SECGROUP_ID, \
+                    'egress', 'tcp', '22', '22'):
+        logger.error("Failed to create the security group rule...")
+        return(EXIT_CODE)
+
     # boot VM 1
     # basic boot
     # tune (e.g. flavor, images, network) to your specific
@@ -387,10 +424,10 @@ def main():
 
     # wait until VM status is active
     if not waitVmActive(nova_client, vm1):
-
         logger.error("Instance '%s' cannot be booted. Status is '%s'" % (
             NAME_VM_1, functest_utils.get_instance_status(nova_client, vm1)))
-        cleanup(nova_client, neutron_client, image_id, network_dic, port_id1)
+        cleanup(nova_client, neutron_client, image_id, network_dic,
+                port_id1, SECGROUP_ID)
         return (EXIT_CODE)
     else:
         logger.info("Instance '%s' is ACTIVE." % NAME_VM_1)
@@ -405,6 +442,9 @@ def main():
     test_ip = IP_1
     logger.debug("Instance '%s' got %s" % (NAME_VM_1, test_ip))
 
+    logger.info("Adding '%s' to security group '%s'..." % (NAME_VM_1, SECGROUP_NAME))
+    functest_utils.add_secgroup_to_instance(nova_client, vm1.id, SECGROUP['id'])
+
     # boot VM 2
     # we will boot then execute a ping script with cloud-init
     # the long chain corresponds to the ping procedure converted with base 64
@@ -424,8 +464,8 @@ def main():
 
     logger.info("Creating instance '%s' with IP %s..." % (NAME_VM_2, IP_2))
     logger.debug(
-        "Configuration:\n name=%s \n flavor=%s \n image=%s \n network=%s "
-        "\n" % (NAME_VM_2, flavor, image, network_id))
+        "Configuration:\n name=%s \n flavor=%s \n image=%s \n "
+        "network=%s \n" % (NAME_VM_2, flavor, image, network_id))
     vm2 = nova_client.servers.create(
         name=NAME_VM_2,
         flavor=flavor,
@@ -437,25 +477,28 @@ def main():
         logger.error("Instance '%s' cannot be booted. Status is '%s'" % (
             NAME_VM_2, functest_utils.get_instance_status(nova_client, vm2)))
         cleanup(nova_client, neutron_client, image_id, network_dic,
-                port_id1, port_id2)
+                port_id1, port_id2, SECGROUP_ID)
         return (EXIT_CODE)
     else:
         logger.info("Instance '%s' is ACTIVE." % NAME_VM_2)
 
-    logger.info("Creating floating IP for the second VM...")
+    logger.info("Adding '%s' to security group '%s'..." % (NAME_VM_2, SECGROUP_NAME))
+    functest_utils.add_secgroup_to_instance(nova_client, vm2.id, SECGROUP['id'])
+
+    logger.info("Creating floating IP for VM '%s'..." % NAME_VM_2)
     floatip = functest_utils.create_floating_ip(neutron_client)
     if floatip == None:
         logger.error("Cannot create floating IP.")
         cleanup(nova_client, neutron_client, image_id, network_dic,
-            port_id1, port_id2)
+            port_id1, port_id2, SECGROUP_ID)
         return (EXIT_CODE)
     logger.info("Floating IP created: '%s'" % floatip)
 
-    logger.info("Associating floating ip: '%s' to VM2 " % floatip)
+    logger.info("Associating floating ip: '%s' to VM '%s' " % (floatip, NAME_VM_2))
     if not functest_utils.add_floating_ip(nova_client, vm2.id, floatip):
         logger.error("Cannot associate floating IP to VM.")
         cleanup(nova_client, neutron_client, image_id, network_dic,
-            port_id1, port_id2)
+            port_id1, port_id2, SECGROUP_ID)
         return (EXIT_CODE)
 
     logger.info("Trying to establish SSH connection to %s..." % floatip)
@@ -479,7 +522,7 @@ def main():
     if timeout == 0: # 300 sec timeout (5 min)
         logger.error("Cannot establish connection to IP '%s'. Aborting" % floatip)
         cleanup(nova_client, neutron_client, image_id, network_dic,
-            port_id1, port_id2)
+            port_id1, port_id2, SECGROUP_ID)
         return (EXIT_CODE)
 
     scp = SCPClient(ssh.get_transport())
@@ -531,7 +574,7 @@ def main():
                 # we consider start time at VM1 booting
                 end_time_ts = time.time()
                 duration = round(end_time_ts - start_time_ts, 1)
-                logger.info("vPing duration:'%s'" % duration)
+                logger.info("vPing duration:'%s' s." % duration)
                 EXIT_CODE = 0
                 flag = True
                 break
@@ -544,6 +587,8 @@ def main():
         logger.debug("Pinging %s. Waiting for response..." % IP_1)
         sec += 1
 
+    cleanup(nova_client, neutron_client, image_id, network_dic,
+            port_id1, port_id2, SECGROUP_ID)
 
     test_status = "NOK"
     if EXIT_CODE == 0:
@@ -553,9 +598,6 @@ def main():
         duration = 0
         logger.error("vPing FAILED")
 
-    cleanup(nova_client, neutron_client, image_id, network_dic,
-            port_id1, port_id2)
-
     if args.report:
         push_results(start_time_ts, duration, test_status)