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