3 # Copyright (c) 2017 All rights reserved
4 # This program and the accompanying materials
5 # are made available under the terms of the Apache License, Version 2.0
6 # which accompanies this distribution, and is available at
8 # http://www.apache.org/licenses/LICENSE-2.0
13 import functest.utils.functest_logger as ft_logger
14 import functest.utils.openstack_utils as os_utils
17 from sdnvpn.lib import config as sdnvpn_config
19 logger = ft_logger.Logger("sndvpn_test_utils").getLogger()
21 common_config = sdnvpn_config.CommonConfig()
24 def create_net(neutron_client, name):
25 logger.debug("Creating network %s", name)
26 net_id = os_utils.create_neutron_net(neutron_client, name)
29 "There has been a problem when creating the neutron network")
34 def create_subnet(neutron_client, name, cidr, net_id):
35 logger.debug("Creating subnet %s in network %s with cidr %s",
37 subnet_id = os_utils.create_neutron_subnet(neutron_client,
43 "There has been a problem when creating the neutron subnet")
48 def create_network(neutron_client, net, subnet1, cidr1,
49 router, subnet2=None, cidr2=None):
50 """Network assoc will not work for networks/subnets created by this function.
52 It is an ODL limitation due to it handling routers as vpns.
53 See https://bugs.opendaylight.org/show_bug.cgi?id=6962"""
54 network_dic = os_utils.create_network_full(neutron_client,
61 "There has been a problem when creating the neutron network")
63 net_id = network_dic["net_id"]
64 subnet_id = network_dic["subnet_id"]
65 router_id = network_dic["router_id"]
67 if subnet2 is not None:
68 logger.debug("Creating and attaching a second subnet...")
69 subnet_id = os_utils.create_neutron_subnet(
70 neutron_client, subnet2, cidr2, net_id)
73 "There has been a problem when creating the second subnet")
75 logger.debug("Subnet '%s' created successfully" % subnet_id)
76 return net_id, subnet_id, router_id
79 def create_instance(nova_client,
91 if 'flavor' not in kwargs:
92 kwargs['flavor'] = common_config.default_flavor
94 logger.info("Creating instance '%s'..." % name)
96 "Configuration:\n name=%s \n flavor=%s \n image=%s \n"
97 " network=%s\n secgroup=%s \n hypervisor=%s \n"
98 " fixed_ip=%s\n files=%s\n userdata=\n%s\n"
99 % (name, kwargs['flavor'], image_id, network_id, sg_id,
100 compute_node, fixed_ip, files, userdata))
101 instance = os_utils.create_instance_and_wait_for_active(
108 av_zone=compute_node,
113 logger.error("Error while booting instance.")
116 logger.debug("Instance '%s' booted successfully. IP='%s'." %
117 (name, instance.networks.itervalues().next()[0]))
118 # Retrieve IP of INSTANCE
119 # instance_ip = instance.networks.get(network_id)[0]
122 logger.debug("Adding '%s' to security group '%s'..."
123 % (name, secgroup_name))
125 logger.debug("Adding '%s' to security group '%s'..."
127 os_utils.add_secgroup_to_instance(nova_client, instance.id, sg_id)
132 def generate_ping_userdata(ips_array):
135 ips = ("%s %s" % (ips, ip))
137 ips = ips.replace(' ', ' ')
138 return ("#!/bin/sh\n"
143 " ping -c 1 $ip 2>&1 >/dev/null\n"
145 " if [ \"Z$RES\" = \"Z0\" ] ; then\n"
146 " echo ping $ip OK\n"
147 " else echo ping $ip KO\n"
155 def generate_userdata_common():
156 return ("#!/bin/sh\n"
157 "sudo mkdir -p /home/cirros/.ssh/\n"
158 "sudo chown cirros:cirros /home/cirros/.ssh/\n"
159 "sudo chown cirros:cirros /home/cirros/id_rsa\n"
160 "mv /home/cirros/id_rsa /home/cirros/.ssh/\n"
161 "sudo echo ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgnWtSS98Am516e"
162 "stBsq0jbyOB4eLMUYDdgzsUHsnxFQCtACwwAg9/2uq3FoGUBUWeHZNsT6jcK9"
163 "sCMEYiS479CUCzbrxcd8XaIlK38HECcDVglgBNwNzX/WDfMejXpKzZG61s98rU"
164 "ElNvZ0YDqhaqZGqxIV4ejalqLjYrQkoly3R+2k= "
165 "cirros@test1>/home/cirros/.ssh/authorized_keys\n"
166 "sudo chown cirros:cirros /home/cirros/.ssh/authorized_keys\n"
167 "chmod 700 /home/cirros/.ssh\n"
168 "chmod 644 /home/cirros/.ssh/authorized_keys\n"
169 "chmod 600 /home/cirros/.ssh/id_rsa\n"
173 def generate_userdata_with_ssh(ips_array):
174 u1 = generate_userdata_common()
178 ips = ("%s %s" % (ips, ip))
180 ips = ips.replace(' ', ' ')
186 " hostname=$(ssh -y -i /home/cirros/.ssh/id_rsa "
187 "cirros@$ip 'hostname' </dev/zero 2>/dev/null)\n"
189 " if [ \"Z$RES\" = \"Z0\" ]; then echo $ip $hostname;\n"
190 " else echo $ip 'not reachable';fi;\n"
198 def wait_for_instance(instance):
199 logger.info("Waiting for instance %s to get a DHCP lease..." % instance.id)
200 # The sleep this function replaced waited for 80s
203 pattern = "Lease of .* obtained, lease time"
204 expected_regex = re.compile(pattern)
206 while tries > 0 and not expected_regex.search(console_log):
207 console_log = instance.get_console_output()
208 time.sleep(sleep_time)
211 if not expected_regex.search(console_log):
212 logger.error("Instance %s seems to have failed leasing an IP."
218 def wait_for_instances_up(*args):
219 check = [wait_for_instance(instance) for instance in args]
223 def wait_for_bgp_net_assoc(neutron_client, bgpvpn_id, net_id):
227 logger.debug("Waiting for network %s to associate with BGPVPN %s "
228 % (bgpvpn_id, net_id))
230 while tries > 0 and net_id not in nets:
231 nets = os_utils.get_bgpvpn_networks(neutron_client, bgpvpn_id)
232 time.sleep(sleep_time)
234 if net_id not in nets:
235 logger.error("Association of network %s with BGPVPN %s failed" %
241 def wait_for_bgp_net_assocs(neutron_client, bgpvpn_id, *args):
242 check = [wait_for_bgp_net_assoc(neutron_client, bgpvpn_id, id)
244 # Return True if all associations succeeded
248 def wait_for_bgp_router_assoc(neutron_client, bgpvpn_id, router_id):
252 logger.debug("Waiting for router %s to associate with BGPVPN %s "
253 % (bgpvpn_id, router_id))
254 while tries > 0 and router_id not in routers:
255 routers = os_utils.get_bgpvpn_routers(neutron_client, bgpvpn_id)
256 time.sleep(sleep_time)
258 if router_id not in routers:
259 logger.error("Association of router %s with BGPVPN %s failed" %
260 (router_id, bgpvpn_id))
265 def wait_for_bgp_router_assocs(neutron_client, bgpvpn_id, *args):
266 check = [wait_for_bgp_router_assoc(neutron_client, bgpvpn_id, id)
268 # Return True if all associations succeeded
272 def wait_before_subtest(*args, **kwargs):
273 ''' This is a placeholder.
274 TODO: Replace delay with polling logic. '''
278 def assert_and_get_compute_nodes(nova_client, required_node_number=2):
279 """Get the compute nodes in the deployment
281 Exit if the deployment doesn't have enough compute nodes"""
282 compute_nodes = os_utils.get_hypervisors(nova_client)
284 num_compute_nodes = len(compute_nodes)
285 if num_compute_nodes < 2:
286 logger.error("There are %s compute nodes in the deployment. "
287 "Minimum number of nodes to complete the test is 2."
291 logger.debug("Compute nodes: %s" % compute_nodes)
295 def open_icmp_ssh(neutron_client, security_group_id):
296 os_utils.create_secgroup_rule(neutron_client,
300 os_utils.create_secgroup_rule(neutron_client,