Merge "Switch to public keystone endpoint"
[functest.git] / functest / opnfv_tests / vnf / ims / orchestra_openims.py
1 #!/usr/bin/env python
2
3 # Copyright (c) 2016 Orange and others.
4 #
5 # All rights reserved. This program and the accompanying materials
6 # are made available under the terms of the Apache License, Version 2.0
7 # which accompanies this distribution, and is available at
8 # http://www.apache.org/licenses/LICENSE-2.0
9
10 """Orchestra OpenIMS testcase implementation."""
11
12 import json
13 import logging
14 import os
15 import socket
16 import time
17 import pkg_resources
18 import yaml
19
20 import functest.core.vnf as vnf
21 import functest.utils.openstack_utils as os_utils
22 from functest.utils.constants import CONST
23
24 from org.openbaton.cli.errors.errors import NfvoException
25 from org.openbaton.cli.agents.agents import MainAgent
26 from snaps.config.flavor import FlavorConfig
27 from snaps.config.image import ImageConfig
28 from snaps.config.network import NetworkConfig, PortConfig, SubnetConfig
29 from snaps.config.router import RouterConfig
30 from snaps.config.security_group import (
31     Direction, Protocol, SecurityGroupConfig, SecurityGroupRuleConfig)
32 from snaps.config.vm_inst import VmInstanceConfig
33 from snaps.openstack.utils import keystone_utils
34 from snaps.openstack.create_image import OpenStackImage
35 from snaps.openstack.create_flavor import OpenStackFlavor
36 from snaps.openstack.create_security_group import OpenStackSecurityGroup
37 from snaps.openstack.create_network import OpenStackNetwork
38 from snaps.openstack.create_router import OpenStackRouter
39 from snaps.openstack.create_instance import OpenStackVmInstance
40
41 from functest.opnfv_tests.openstack.snaps import snaps_utils
42
43
44 __author__ = "Pauls, Michael <michael.pauls@fokus.fraunhofer.de>"
45 # ----------------------------------------------------------
46 #
47 #               UTILS
48 #
49 # -----------------------------------------------------------
50
51
52 def get_config(parameter, file_path):
53     """
54     Get config parameter.
55
56     Returns the value of a given parameter in file.yaml
57     parameter must be given in string format with dots
58     Example: general.openstack.image_name
59     """
60     with open(file_path) as config_file:
61         file_yaml = yaml.safe_load(config_file)
62     config_file.close()
63     value = file_yaml
64     for element in parameter.split("."):
65         value = value.get(element)
66         if value is None:
67             raise ValueError("The parameter %s is not defined in"
68                              " reporting.yaml", parameter)
69     return value
70
71
72 def servertest(host, port):
73     """Method to test that a server is reachable at IP:port"""
74     args = socket.getaddrinfo(host, port, socket.AF_INET, socket.SOCK_STREAM)
75     for family, socktype, proto, canonname, sockaddr in args:
76         sock = socket.socket(family, socktype, proto)
77         try:
78             sock.connect(sockaddr)
79         except socket.error:
80             return False
81         else:
82             sock.close()
83             return True
84
85
86 def get_userdata(orchestrator=dict):
87     """Build userdata for Open Baton machine"""
88     userdata = "#!/bin/bash\n"
89     userdata += "echo \"Executing userdata...\"\n"
90     userdata += "set -x\n"
91     userdata += "set -e\n"
92     userdata += "echo \"Set nameserver to '8.8.8.8'...\"\n"
93     userdata += "echo \"nameserver   8.8.8.8\" >> /etc/resolv.conf\n"
94     userdata += "echo \"Install curl...\"\n"
95     userdata += "apt-get install curl\n"
96     userdata += "echo \"Inject public key...\"\n"
97     userdata += ("echo \"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCuPXrV3"
98                  "geeHc6QUdyUr/1Z+yQiqLcOskiEGBiXr4z76MK4abiFmDZ18OMQlc"
99                  "fl0p3kS0WynVgyaOHwZkgy/DIoIplONVr2CKBKHtPK+Qcme2PVnCtv"
100                  "EqItl/FcD+1h5XSQGoa+A1TSGgCod/DPo+pes0piLVXP8Ph6QS1k7S"
101                  "ic7JDeRQ4oT1bXYpJ2eWBDMfxIWKZqcZRiGPgMIbJ1iEkxbpeaAd9O"
102                  "4MiM9nGCPESmed+p54uYFjwEDlAJZShcAZziiZYAvMZhvAhe6USljc"
103                  "7YAdalAnyD/jwCHuwIrUw/lxo7UdNCmaUxeobEYyyFA1YVXzpNFZya"
104                  "XPGAAYIJwEq/ openbaton@opnfv\" >> /home/ubuntu/.ssh/aut"
105                  "horized_keys\n")
106     userdata += "echo \"Download bootstrap...\"\n"
107     userdata += ("curl -s %s "
108                  "> ./bootstrap\n" % orchestrator['bootstrap']['url'])
109     userdata += ("curl -s %s" "> ./config_file\n" %
110                  orchestrator['bootstrap']['config']['url'])
111     userdata += ("echo \"Disable usage of mysql...\"\n")
112     userdata += "sed -i s/mysql=.*/mysql=no/g /config_file\n"
113     userdata += ("echo \"Setting 'rabbitmq_broker_ip' to '%s'\"\n"
114                  % orchestrator['details']['fip'].ip)
115     userdata += ("sed -i s/rabbitmq_broker_ip=localhost/rabbitmq_broker_ip"
116                  "=%s/g /config_file\n" % orchestrator['details']['fip'].ip)
117     userdata += "echo \"Set autostart of components to 'false'\"\n"
118     userdata += "export OPENBATON_COMPONENT_AUTOSTART=false\n"
119     userdata += "echo \"Execute bootstrap...\"\n"
120     bootstrap = "sh ./bootstrap release -configFile=./config_file"
121     userdata += bootstrap + "\n"
122     userdata += "echo \"Setting 'nfvo.plugin.timeout' to '300000'\"\n"
123     userdata += ("echo \"nfvo.plugin.timeout=600000\" >> "
124                  "/etc/openbaton/openbaton-nfvo.properties\n")
125     userdata += (
126         "wget %s -O /etc/openbaton/openbaton-vnfm-generic-user-data.sh\n" %
127         orchestrator['gvnfm']['userdata']['url'])
128     userdata += "sed -i '113i"'\ \ \ \ '"sleep 60' " \
129                 "/etc/openbaton/openbaton-vnfm-generic-user-data.sh\n"
130     userdata += ("sed -i s/nfvo.marketplace.port=8082/nfvo.marketplace."
131                  "port=8080/g /etc/openbaton/openbaton-nfvo.properties\n")
132     userdata += "echo \"Starting NFVO\"\n"
133     userdata += "service openbaton-nfvo restart\n"
134     userdata += "echo \"Starting Generic VNFM\"\n"
135     userdata += "service openbaton-vnfm-generic restart\n"
136     userdata += "echo \"...end of userdata...\"\n"
137     return userdata
138
139
140 class OpenImsVnf(vnf.VnfOnBoarding):
141     """OpenIMS VNF deployed with openBaton orchestrator"""
142
143     # logger = logging.getLogger(__name__)
144
145     def __init__(self, **kwargs):
146         if "case_name" not in kwargs:
147             kwargs["case_name"] = "orchestra_openims"
148         super(OpenImsVnf, self).__init__(**kwargs)
149         self.logger = logging.getLogger("functest.ci.run_tests.orchestra")
150         self.logger.info("kwargs %s", (kwargs))
151
152         self.case_dir = pkg_resources.resource_filename(
153             'functest', 'opnfv_tests/vnf/ims/')
154         self.data_dir = CONST.__getattribute__('dir_ims_data')
155         self.test_dir = CONST.__getattribute__('dir_repo_vims_test')
156         self.created_resources = []
157         self.logger.info("%s VNF onboarding test starting", self.case_name)
158
159         try:
160             self.config = CONST.__getattribute__(
161                 'vnf_{}_config'.format(self.case_name))
162         except BaseException:
163             raise Exception("Orchestra VNF config file not found")
164         config_file = self.case_dir + self.config
165
166         self.mano = dict(
167             get_config("mano", config_file),
168             details={}
169         )
170         self.logger.debug("Orchestrator configuration %s", self.mano)
171
172         self.details['orchestrator'] = dict(
173             name=self.mano['name'],
174             version=self.mano['version'],
175             status='ERROR',
176             result=''
177         )
178
179         self.vnf = dict(
180             get_config(self.case_name, config_file),
181         )
182         self.logger.debug("VNF configuration: %s", self.vnf)
183
184         self.details['vnf'] = dict(
185             name=self.vnf['name'],
186         )
187
188         self.details['test_vnf'] = dict(
189             name=self.case_name,
190         )
191
192         # Orchestra base Data directory creation
193         if not os.path.exists(self.data_dir):
194             os.makedirs(self.data_dir)
195
196         self.images = get_config("tenant_images.orchestrator", config_file)
197         self.images.update(get_config("tenant_images.%s" %
198                                       self.case_name, config_file))
199
200     def prepare(self):
201         """Prepare testscase (Additional pre-configuration steps)."""
202         super(OpenImsVnf, self).prepare()
203
204         public_auth_url = keystone_utils.get_endpoint(
205             self.snaps_creds, 'identity')
206
207         self.logger.info("Additional pre-configuration steps")
208         self.creds = {
209                 "tenant": self.tenant_name,
210                 "username": self.tenant_name,
211                 "password": self.tenant_name,
212                 "auth_url": public_auth_url
213                 }
214         self.prepare_images()
215         self.prepare_flavor()
216         self.prepare_security_groups()
217         self.prepare_network()
218         self.prepare_floating_ip()
219
220     def prepare_images(self):
221         """Upload images if they doen't exist yet"""
222         self.logger.info("Upload images if they doen't exist yet")
223         for image_name, image_file in self.images.iteritems():
224             self.logger.info("image: %s, file: %s", image_name, image_file)
225             if image_file and image_name:
226                 image = OpenStackImage(
227                     self.snaps_creds,
228                     ImageConfig(name=image_name,
229                                 image_user='cloud',
230                                 img_format='qcow2',
231                                 image_file=image_file,
232                                 public=True))
233                 image.create()
234                 # self.created_resources.append(image);
235
236     def prepare_security_groups(self):
237         """Create Open Baton security group if it doesn't exist yet"""
238         self.logger.info(
239             "Creating security group for Open Baton if not yet existing...")
240         sg_rules = list()
241         sg_rules.append(
242             SecurityGroupRuleConfig(
243                 sec_grp_name="orchestra-sec-group-allowall",
244                 direction=Direction.ingress,
245                 protocol=Protocol.tcp,
246                 port_range_min=1,
247                 port_range_max=65535))
248         sg_rules.append(
249             SecurityGroupRuleConfig(
250                 sec_grp_name="orchestra-sec-group-allowall",
251                 direction=Direction.egress,
252                 protocol=Protocol.tcp,
253                 port_range_min=1,
254                 port_range_max=65535))
255         sg_rules.append(
256             SecurityGroupRuleConfig(
257                 sec_grp_name="orchestra-sec-group-allowall",
258                 direction=Direction.ingress,
259                 protocol=Protocol.udp,
260                 port_range_min=1,
261                 port_range_max=65535))
262         sg_rules.append(
263             SecurityGroupRuleConfig(
264                 sec_grp_name="orchestra-sec-group-allowall",
265                 direction=Direction.egress,
266                 protocol=Protocol.udp,
267                 port_range_min=1,
268                 port_range_max=65535))
269         security_group = OpenStackSecurityGroup(
270             self.snaps_creds,
271             SecurityGroupConfig(
272                 name="orchestra-sec-group-allowall",
273                 rule_settings=sg_rules))
274
275         security_group_info = security_group.create()
276         self.created_resources.append(security_group)
277         self.mano['details']['sec_group'] = security_group_info.name
278         self.logger.info(
279             "Security group orchestra-sec-group-allowall prepared")
280
281     def prepare_flavor(self):
282         """Create Open Baton flavor if it doesn't exist yet"""
283         self.logger.info(
284             "Create Flavor for Open Baton NFVO if not yet existing")
285
286         flavor_settings = FlavorConfig(
287             name=self.mano['requirements']['flavor']['name'],
288             ram=self.mano['requirements']['flavor']['ram_min'],
289             disk=self.mano['requirements']['flavor']['disk'],
290             vcpus=self.mano['requirements']['flavor']['vcpus'])
291         flavor = OpenStackFlavor(self.snaps_creds, flavor_settings)
292         flavor_info = flavor.create()
293         self.created_resources.append(flavor)
294         self.mano['details']['flavor'] = {}
295         self.mano['details']['flavor']['name'] = flavor_settings.name
296         self.mano['details']['flavor']['id'] = flavor_info.id
297
298     def prepare_network(self):
299         """Create network/subnet/router if they doen't exist yet"""
300         self.logger.info(
301             "Creating network/subnet/router if they doen't exist yet...")
302         subnet_settings = SubnetConfig(
303             name='%s_subnet' %
304             self.case_name,
305             cidr="192.168.100.0/24")
306         network_settings = NetworkConfig(
307             name='%s_net' %
308             self.case_name,
309             subnet_settings=[subnet_settings])
310         orchestra_network = OpenStackNetwork(
311             self.snaps_creds, network_settings)
312         orchestra_network_info = orchestra_network.create()
313         self.mano['details']['network'] = {}
314         self.mano['details']['network']['id'] = orchestra_network_info.id
315         self.mano['details']['network']['name'] = orchestra_network_info.name
316         self.mano['details']['external_net_name'] = \
317             snaps_utils.get_ext_net_name(self.snaps_creds)
318         self.created_resources.append(orchestra_network)
319         orchestra_router = OpenStackRouter(
320             self.snaps_creds,
321             RouterConfig(
322                 name='%s_router' %
323                 self.case_name,
324                 external_gateway=self.mano['details']['external_net_name'],
325                 internal_subnets=[
326                     subnet_settings.name]))
327         orchestra_router.create()
328         self.created_resources.append(orchestra_router)
329         self.logger.info("Created network and router for Open Baton NFVO...")
330
331     def prepare_floating_ip(self):
332         """Select/Create Floating IP if it doesn't exist yet"""
333         self.logger.info("Retrieving floating IP for Open Baton NFVO")
334         neutron_client = snaps_utils.neutron_utils.neutron_client(
335             self.snaps_creds)
336         # Finding Tenant ID to check to which tenant the Floating IP belongs
337         tenant_id = os_utils.get_tenant_id(
338             os_utils.get_keystone_client(self.creds),
339             self.tenant_name)
340         # Use os_utils to retrieve complete information of Floating IPs
341         floating_ips = os_utils.get_floating_ips(neutron_client)
342         my_floating_ips = []
343         # Filter Floating IPs with tenant id
344         for floating_ip in floating_ips:
345             # self.logger.info("Floating IP: %s", floating_ip)
346             if floating_ip.get('tenant_id') == tenant_id:
347                 my_floating_ips.append(floating_ip.get('floating_ip_address'))
348         # Select if Floating IP exist else create new one
349         if len(my_floating_ips) >= 1:
350             # Get Floating IP object from snaps for clean up
351             snaps_floating_ips = snaps_utils.neutron_utils.get_floating_ips(
352                 neutron_client)
353             for my_floating_ip in my_floating_ips:
354                 for snaps_floating_ip in snaps_floating_ips:
355                     if snaps_floating_ip.ip == my_floating_ip:
356                         self.mano['details']['fip'] = snaps_floating_ip
357                         self.logger.info(
358                             "Selected floating IP for Open Baton NFVO %s",
359                             (self.mano['details']['fip'].ip))
360                         break
361                 if self.mano['details']['fip'] is not None:
362                     break
363         else:
364             self.logger.info("Creating floating IP for Open Baton NFVO")
365             self.mano['details']['fip'] = (
366                 snaps_utils.neutron_utils. create_floating_ip(
367                     neutron_client, self.mano['details']['external_net_name']))
368             self.logger.info(
369                 "Created floating IP for Open Baton NFVO %s",
370                 (self.mano['details']['fip'].ip))
371
372     def get_vim_descriptor(self):
373         """"Create VIM descriptor to be used for onboarding"""
374         self.logger.info(
375             "Building VIM descriptor with PoP creds: %s",
376             self.creds)
377         # Depending on API version either tenant ID or project name must be
378         # used
379         if os_utils.is_keystone_v3():
380             self.logger.info(
381                 "Using v3 API of OpenStack... -> Using OS_PROJECT_ID")
382             project_id = os_utils.get_tenant_id(
383                 os_utils.get_keystone_client(),
384                 self.creds.get("project_name"))
385         else:
386             self.logger.info(
387                 "Using v2 API of OpenStack... -> Using OS_TENANT_NAME")
388             project_id = self.creds.get("tenant_name")
389         self.logger.debug("VIM project/tenant id: %s", project_id)
390         vim_json = {
391             "name": "vim-instance",
392             "authUrl": self.creds.get("auth_url"),
393             "tenant": project_id,
394             "username": self.creds.get("username"),
395             "password": self.creds.get("password"),
396             "securityGroups": [
397                 self.mano['details']['sec_group']
398             ],
399             "type": "openstack",
400             "location": {
401                 "name": "opnfv",
402                 "latitude": "52.525876",
403                 "longitude": "13.314400"
404             }
405         }
406         self.logger.info("Built VIM descriptor: %s", vim_json)
407         return vim_json
408
409     def deploy_orchestrator(self):
410         self.logger.info("Deploying Open Baton...")
411         self.logger.info("Details: %s", self.mano['details'])
412         start_time = time.time()
413
414         self.logger.info("Creating orchestra instance...")
415         userdata = get_userdata(self.mano)
416         self.logger.info("flavor: %s\n"
417                          "image: %s\n"
418                          "network_id: %s\n",
419                          self.mano['details']['flavor']['name'],
420                          self.mano['requirements']['image'],
421                          self.mano['details']['network']['id'])
422         self.logger.debug("userdata: %s\n", userdata)
423         # setting up image
424         image_settings = ImageConfig(
425             name=self.mano['requirements']['image'],
426             image_user='ubuntu',
427             exists=True)
428         # setting up port
429         port_settings = PortConfig(
430             name='%s_port' % self.case_name,
431             network_name=self.mano['details']['network']['name'])
432         # build configuration of vm
433         orchestra_settings = VmInstanceConfig(
434             name=self.case_name,
435             flavor=self.mano['details']['flavor']['name'],
436             port_settings=[port_settings],
437             security_group_names=[self.mano['details']['sec_group']],
438             userdata=str(userdata))
439         orchestra_vm = OpenStackVmInstance(self.snaps_creds,
440                                            orchestra_settings,
441                                            image_settings)
442
443         orchestra_vm.create()
444         self.created_resources.append(orchestra_vm)
445         self.mano['details']['id'] = orchestra_vm.get_vm_info()['id']
446         self.logger.info(
447             "Created orchestra instance: %s",
448             self.mano['details']['id'])
449
450         self.logger.info("Associating floating ip: '%s' to VM '%s' ",
451                          self.mano['details']['fip'].ip,
452                          self.case_name)
453         nova_client = os_utils.get_nova_client()
454         if not os_utils.add_floating_ip(
455                 nova_client,
456                 self.mano['details']['id'],
457                 self.mano['details']['fip'].ip):
458             duration = time.time() - start_time
459             self.details["orchestrator"].update(
460                 status='FAIL', duration=duration)
461             self.logger.error("Cannot associate floating IP to VM.")
462             return False
463
464         self.logger.info("Waiting for Open Baton NFVO to be up and running...")
465         timeout = 0
466         while timeout < 20:
467             if servertest(
468                     self.mano['details']['fip'].ip,
469                     "8080"):
470                 break
471             else:
472                 self.logger.info("Open Baton NFVO is not started yet (%ss)",
473                                  (timeout * 60))
474                 time.sleep(60)
475                 timeout += 1
476
477         if timeout >= 20:
478             duration = time.time() - start_time
479             self.details["orchestrator"].update(
480                 status='FAIL', duration=duration)
481             self.logger.error("Open Baton is not started correctly")
482             return False
483
484         self.logger.info("Waiting for all components to be up and running...")
485         time.sleep(60)
486         duration = time.time() - start_time
487         self.details["orchestrator"].update(status='PASS', duration=duration)
488         self.logger.info("Deploy Open Baton NFVO: OK")
489         return True
490
491     def deploy_vnf(self):
492         start_time = time.time()
493         self.logger.info("Deploying %s...", self.vnf['name'])
494
495         main_agent = MainAgent(
496             nfvo_ip=self.mano['details']['fip'].ip,
497             nfvo_port=8080,
498             https=False,
499             version=1,
500             username=self.mano['credentials']['username'],
501             password=self.mano['credentials']['password'])
502
503         self.logger.info(
504             "Create %s Flavor if not existing", self.vnf['name'])
505         flavor_settings = FlavorConfig(
506             name=self.vnf['requirements']['flavor']['name'],
507             ram=self.vnf['requirements']['flavor']['ram_min'],
508             disk=self.vnf['requirements']['flavor']['disk'],
509             vcpus=self.vnf['requirements']['flavor']['vcpus'])
510         flavor = OpenStackFlavor(self.snaps_creds, flavor_settings)
511         flavor_info = flavor.create()
512         self.logger.debug("Flavor id: %s", flavor_info.id)
513
514         self.logger.info("Getting project 'default'...")
515         project_agent = main_agent.get_agent("project", "")
516         for project in json.loads(project_agent.find()):
517             if project.get("name") == "default":
518                 self.mano['details']['project_id'] = project.get("id")
519                 self.logger.info("Found project 'default': %s", project)
520                 break
521
522         vim_json = self.get_vim_descriptor()
523         self.logger.info("Registering VIM: %s", vim_json)
524
525         main_agent.get_agent(
526             "vim", project_id=self.mano['details']['project_id']).create(
527                 entity=json.dumps(vim_json))
528
529         market_agent = main_agent.get_agent(
530             "market", project_id=self.mano['details']['project_id'])
531
532         try:
533             self.logger.info("sending: %s", self.vnf['descriptor']['url'])
534             nsd = market_agent.create(entity=self.vnf['descriptor']['url'])
535             if nsd.get('id') is None:
536                 self.logger.error("NSD not onboarded correctly")
537                 duration = time.time() - start_time
538                 self.details["vnf"].update(status='FAIL', duration=duration)
539                 return False
540             self.mano['details']['nsd_id'] = nsd.get('id')
541             self.logger.info("Onboarded NSD: " + nsd.get("name"))
542
543             nsr_agent = main_agent.get_agent(
544                 "nsr", project_id=self.mano['details']['project_id'])
545
546             self.mano['details']['nsr'] = nsr_agent.create(
547                 self.mano['details']['nsd_id'])
548         except NfvoException as exc:
549             self.logger.error(exc.message)
550             duration = time.time() - start_time
551             self.details["vnf"].update(status='FAIL', duration=duration)
552             return False
553
554         if self.mano['details']['nsr'].get('code') is not None:
555             self.logger.error(
556                 "%s cannot be deployed: %s -> %s",
557                 self.vnf['name'],
558                 self.mano['details']['nsr'].get('code'),
559                 self.mano['details']['nsr'].get('message'))
560             self.logger.error("%s cannot be deployed", self.vnf['name'])
561             duration = time.time() - start_time
562             self.details["vnf"].update(status='FAIL', duration=duration)
563             return False
564
565         timeout = 0
566         self.logger.info("Waiting for NSR to go to ACTIVE...")
567         while self.mano['details']['nsr'].get("status") != 'ACTIVE' \
568                 and self.mano['details']['nsr'].get("status") != 'ERROR':
569             timeout += 1
570             self.logger.info("NSR is not yet ACTIVE... (%ss)", 60 * timeout)
571             if timeout == 30:
572                 self.logger.error("INACTIVE NSR after %s sec..", 60 * timeout)
573                 duration = time.time() - start_time
574                 self.details["vnf"].update(status='FAIL', duration=duration)
575                 return False
576             time.sleep(60)
577             self.mano['details']['nsr'] = json.loads(
578                 nsr_agent.find(self.mano['details']['nsr'].get('id')))
579
580         duration = time.time() - start_time
581         if self.mano['details']['nsr'].get("status") == 'ACTIVE':
582             self.details["vnf"].update(status='PASS', duration=duration)
583             self.logger.info("Sleep for 60s to ensure that all "
584                              "services are up and running...")
585             time.sleep(60)
586             result = True
587         else:
588             self.details["vnf"].update(status='FAIL', duration=duration)
589             self.logger.error("NSR: %s", self.mano['details'].get('nsr'))
590             result = False
591         return result
592
593     def test_vnf(self):
594         self.logger.info("Testing VNF OpenIMS...")
595         start_time = time.time()
596         self.logger.info(
597             "Testing if %s works properly...",
598             self.mano['details']['nsr'].get('name'))
599         for vnfr in self.mano['details']['nsr'].get('vnfr'):
600             self.logger.info(
601                 "Checking ports %s of VNF %s",
602                 self.vnf['test'][vnfr.get('name')]['ports'],
603                 vnfr.get('name'))
604             for vdu in vnfr.get('vdu'):
605                 for vnfci in vdu.get('vnfc_instance'):
606                     self.logger.debug(
607                         "Checking ports of VNFC instance %s",
608                         vnfci.get('hostname'))
609                     for floating_ip in vnfci.get('floatingIps'):
610                         self.logger.debug(
611                             "Testing %s:%s",
612                             vnfci.get('hostname'),
613                             floating_ip.get('ip'))
614                         for port in self.vnf['test'][vnfr.get(
615                                 'name')]['ports']:
616                             if servertest(floating_ip.get('ip'), port):
617                                 self.logger.info(
618                                     "VNFC instance %s is reachable at %s:%s",
619                                     vnfci.get('hostname'),
620                                     floating_ip.get('ip'),
621                                     port)
622                             else:
623                                 self.logger.error(
624                                     "VNFC instance %s is not reachable "
625                                     "at %s:%s",
626                                     vnfci.get('hostname'),
627                                     floating_ip.get('ip'),
628                                     port)
629                                 duration = time.time() - start_time
630                                 self.details["test_vnf"].update(
631                                     status='FAIL', duration=duration, esult=(
632                                         "Port %s of server %s -> %s is "
633                                         "not reachable",
634                                         port,
635                                         vnfci.get('hostname'),
636                                         floating_ip.get('ip')))
637                                 self.logger.error("Test VNF: ERROR")
638                                 return False
639         duration = time.time() - start_time
640         self.details["test_vnf"].update(status='PASS', duration=duration)
641         self.logger.info("Test VNF: OK")
642         return True
643
644     def clean(self):
645         self.logger.info("Cleaning %s...", self.case_name)
646         try:
647             main_agent = MainAgent(
648                 nfvo_ip=self.mano['details']['fip'].ip,
649                 nfvo_port=8080,
650                 https=False,
651                 version=1,
652                 username=self.mano['credentials']['username'],
653                 password=self.mano['credentials']['password'])
654             self.logger.info("Terminating %s...", self.vnf['name'])
655             if (self.mano['details'].get('nsr')):
656                 main_agent.get_agent(
657                     "nsr",
658                     project_id=self.mano['details']['project_id']).\
659                         delete(self.mano['details']['nsr'].get('id'))
660                 self.logger.info("Sleeping 60 seconds...")
661                 time.sleep(60)
662             else:
663                 self.logger.info("No need to terminate the VNF...")
664         except (NfvoException, KeyError) as exc:
665             self.logger.error('Unexpected error cleaning - %s', exc)
666
667         try:
668             neutron_client = os_utils.get_neutron_client(self.creds)
669             self.logger.info("Deleting Open Baton Port...")
670             port = snaps_utils.neutron_utils.get_port(
671                 neutron_client,
672                 port_name='%s_port' % self.case_name)
673             snaps_utils.neutron_utils.delete_port(neutron_client, port)
674             time.sleep(10)
675         except Exception as exc:  # pylint: disable=broad-except
676             self.logger.error('Unexpected error cleaning - %s', exc)
677         try:
678             self.logger.info("Deleting Open Baton Floating IP...")
679             snaps_utils.neutron_utils.delete_floating_ip(
680                 neutron_client, self.mano['details']['fip'])
681         except Exception as exc:  # pylint: disable=broad-except
682             self.logger.error('Unexpected error cleaning - %s', exc)
683
684         for resource in reversed(self.created_resources):
685             try:
686                 self.logger.info("Cleaning %s", str(resource))
687                 resource.clean()
688             except Exception as exc:
689                 self.logger.error('Unexpected error cleaning - %s', exc)
690         super(OpenImsVnf, self).clean()