Fix many pylint warnings
[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 from functest.core import vnf
21 from functest.utils import config
22 from functest.utils import env
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 FloatingIpConfig
33 from snaps.config.vm_inst import VmInstanceConfig
34 from snaps.openstack.utils import keystone_utils
35 from snaps.openstack.create_image import OpenStackImage
36 from snaps.openstack.create_flavor import OpenStackFlavor
37 from snaps.openstack.create_security_group import OpenStackSecurityGroup
38 from snaps.openstack.create_network import OpenStackNetwork
39 from snaps.openstack.create_router import OpenStackRouter
40 from snaps.openstack.create_instance import OpenStackVmInstance
41
42 from functest.opnfv_tests.openstack.snaps import snaps_utils
43
44
45 __author__ = "Pauls, Michael <michael.pauls@fokus.fraunhofer.de>"
46 # ----------------------------------------------------------
47 #
48 #               UTILS
49 #
50 # -----------------------------------------------------------
51
52
53 def get_config(parameter, file_path):
54     """
55     Get config parameter.
56
57     Returns the value of a given parameter in file.yaml
58     parameter must be given in string format with dots
59     Example: general.openstack.image_name
60     """
61     with open(file_path) as config_file:
62         file_yaml = yaml.safe_load(config_file)
63     config_file.close()
64     value = file_yaml
65     for element in parameter.split("."):
66         value = value.get(element)
67         if value is None:
68             raise ValueError("The parameter %s is not defined in"
69                              " reporting.yaml", parameter)
70     return value
71
72
73 def servertest(host, port):
74     """Method to test that a server is reachable at IP:port"""
75     args = socket.getaddrinfo(host, port, socket.AF_INET, socket.SOCK_STREAM)
76     for family, socktype, proto, _, sockaddr in args:
77         sock = socket.socket(family, socktype, proto)
78         try:
79             sock.connect(sockaddr)
80         except socket.error:
81             return False
82         else:
83             sock.close()
84             return True
85
86
87 def get_userdata(orchestrator=dict):
88     """Build userdata for Open Baton machine"""
89     userdata = "#!/bin/bash\n"
90     userdata += "echo \"Executing userdata...\"\n"
91     userdata += "set -x\n"
92     userdata += "set -e\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 \"Set autostart of components to 'false'\"\n"
113     userdata += "export OPENBATON_COMPONENT_AUTOSTART=false\n"
114     userdata += "echo \"Execute bootstrap...\"\n"
115     bootstrap = "sh ./bootstrap release -configFile=./config_file"
116     userdata += bootstrap + "\n"
117     userdata += "echo \"Setting 'nfvo.plugin.timeout' to '300000'\"\n"
118     userdata += ("echo \"nfvo.plugin.timeout=600000\" >> "
119                  "/etc/openbaton/openbaton-nfvo.properties\n")
120     userdata += (
121         "wget %s -O /etc/openbaton/openbaton-vnfm-generic-user-data.sh\n" %
122         orchestrator['gvnfm']['userdata']['url'])
123     userdata += "sed -i '113i"'\ \ \ \ '"sleep 60' " \
124                 "/etc/openbaton/openbaton-vnfm-generic-user-data.sh\n"
125     userdata += ("sed -i s/nfvo.marketplace.port=8082/nfvo.marketplace."
126                  "port=8080/g /etc/openbaton/openbaton-nfvo.properties\n")
127     userdata += "echo \"Starting NFVO\"\n"
128     userdata += "service openbaton-nfvo restart\n"
129     userdata += "echo \"Starting Generic VNFM\"\n"
130     userdata += "service openbaton-vnfm-generic restart\n"
131     userdata += "echo \"...end of userdata...\"\n"
132     return userdata
133
134
135 class OpenImsVnf(vnf.VnfOnBoarding):
136     """OpenIMS VNF deployed with openBaton orchestrator"""
137
138     # logger = logging.getLogger(__name__)
139
140     def __init__(self, **kwargs):
141         if "case_name" not in kwargs:
142             kwargs["case_name"] = "orchestra_openims"
143         super(OpenImsVnf, self).__init__(**kwargs)
144         self.logger = logging.getLogger("functest.ci.run_tests.orchestra")
145         self.logger.info("kwargs %s", (kwargs))
146
147         self.case_dir = pkg_resources.resource_filename(
148             'functest', 'opnfv_tests/vnf/ims/')
149         self.data_dir = getattr(config.CONF, 'dir_ims_data')
150         self.test_dir = getattr(config.CONF, 'dir_repo_vims_test')
151         self.created_resources = []
152         self.logger.info("%s VNF onboarding test starting", self.case_name)
153
154         try:
155             self.config = getattr(
156                 config.CONF, 'vnf_{}_config'.format(self.case_name))
157         except BaseException:
158             raise Exception("Orchestra VNF config file not found")
159         config_file = self.case_dir + self.config
160
161         self.mano = dict(
162             get_config("mano", config_file),
163             details={}
164         )
165         self.logger.debug("Orchestrator configuration %s", self.mano)
166
167         self.details['orchestrator'] = dict(
168             name=self.mano['name'],
169             version=self.mano['version'],
170             status='ERROR',
171             result=''
172         )
173
174         self.vnf = dict(
175             get_config(self.case_name, config_file),
176         )
177         self.logger.debug("VNF configuration: %s", self.vnf)
178
179         self.details['vnf'] = dict(
180             name=self.vnf['name'],
181         )
182
183         self.details['test_vnf'] = dict(
184             name=self.case_name,
185         )
186
187         # Orchestra base Data directory creation
188         if not os.path.exists(self.data_dir):
189             os.makedirs(self.data_dir)
190
191         self.images = get_config("tenant_images.orchestrator", config_file)
192         self.images.update(get_config("tenant_images.%s" %
193                                       self.case_name, config_file))
194         self.creds = None
195         self.orchestra_router = None
196
197     def prepare(self):
198         """Prepare testscase (Additional pre-configuration steps)."""
199         super(OpenImsVnf, self).prepare()
200
201         public_auth_url = keystone_utils.get_endpoint(
202             self.snaps_creds, 'identity')
203
204         self.logger.info("Additional pre-configuration steps")
205         self.creds = {
206             "tenant": self.snaps_creds.project_name,
207             "username": self.snaps_creds.username,
208             "password": self.snaps_creds.password,
209             "auth_url": public_auth_url}
210         self.prepare_images()
211         self.prepare_flavor()
212         self.prepare_security_groups()
213         self.prepare_network()
214
215     def prepare_images(self):
216         """Upload images if they doen't exist yet"""
217         self.logger.info("Upload images if they doen't exist yet")
218         for image_name, image_file in self.images.iteritems():
219             self.logger.info("image: %s, file: %s", image_name, image_file)
220             if image_file and image_name:
221                 image = OpenStackImage(
222                     self.snaps_creds,
223                     ImageConfig(name=image_name,
224                                 image_user='cloud',
225                                 img_format='qcow2',
226                                 image_file=image_file,
227                                 public=True))
228                 image.create()
229                 self.created_resources.append(image)
230
231     def prepare_security_groups(self):
232         """Create Open Baton security group if it doesn't exist yet"""
233         self.logger.info(
234             "Creating security group for Open Baton if not yet existing...")
235         sg_rules = list()
236         sg_rules.append(
237             SecurityGroupRuleConfig(
238                 sec_grp_name="orchestra-sec-group-allowall-{}".format(
239                     self.uuid),
240                 direction=Direction.ingress,
241                 protocol=Protocol.tcp,
242                 port_range_min=1,
243                 port_range_max=65535))
244         sg_rules.append(
245             SecurityGroupRuleConfig(
246                 sec_grp_name="orchestra-sec-group-allowall-{}".format(
247                     self.uuid),
248                 direction=Direction.egress,
249                 protocol=Protocol.tcp,
250                 port_range_min=1,
251                 port_range_max=65535))
252         sg_rules.append(
253             SecurityGroupRuleConfig(
254                 sec_grp_name="orchestra-sec-group-allowall-{}".format(
255                     self.uuid),
256                 direction=Direction.ingress,
257                 protocol=Protocol.udp,
258                 port_range_min=1,
259                 port_range_max=65535))
260         sg_rules.append(
261             SecurityGroupRuleConfig(
262                 sec_grp_name="orchestra-sec-group-allowall-{}".format(
263                     self.uuid),
264                 direction=Direction.egress,
265                 protocol=Protocol.udp,
266                 port_range_min=1,
267                 port_range_max=65535))
268         security_group = OpenStackSecurityGroup(
269             self.snaps_creds,
270             SecurityGroupConfig(
271                 name="orchestra-sec-group-allowall-{}".format(
272                     self.uuid),
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='{}_subnet-{}'.format(self.case_name, self.uuid),
304             cidr="192.168.100.0/24",
305             dns_nameservers=[env.get('NAMESERVER')])
306         network_settings = NetworkConfig(
307             name='{}_net-{}'.format(self.case_name, self.uuid),
308             subnet_settings=[subnet_settings])
309         orchestra_network = OpenStackNetwork(
310             self.snaps_creds, network_settings)
311         orchestra_network_info = orchestra_network.create()
312         self.mano['details']['network'] = {}
313         self.mano['details']['network']['id'] = orchestra_network_info.id
314         self.mano['details']['network']['name'] = orchestra_network_info.name
315         self.mano['details']['external_net_name'] = \
316             snaps_utils.get_ext_net_name(self.snaps_creds)
317         self.created_resources.append(orchestra_network)
318         self.orchestra_router = OpenStackRouter(
319             self.snaps_creds,
320             RouterConfig(
321                 name='{}_router-{}'.format(self.case_name, self.uuid),
322                 external_gateway=self.mano['details']['external_net_name'],
323                 internal_subnets=[
324                     subnet_settings.name]))
325         self.orchestra_router.create()
326         self.created_resources.append(self.orchestra_router)
327         self.logger.info("Created network and router for Open Baton NFVO...")
328
329     def get_vim_descriptor(self):
330         """"Create VIM descriptor to be used for onboarding"""
331         self.logger.info(
332             "Building VIM descriptor with PoP creds: %s",
333             self.creds)
334         self.logger.debug("VIM project/tenant id: %s",
335                           self.snaps_creds.project_name)
336         keystone = keystone_utils.keystone_client(self.snaps_creds)
337         project_id = keystone_utils.get_project(
338             keystone=keystone, project_name=self.snaps_creds.project_name).id
339         vim_json = {
340             "name": "vim-instance",
341             "authUrl": self.creds.get("auth_url"),
342             "tenant": project_id,
343             "username": self.creds.get("username"),
344             "password": self.creds.get("password"),
345             "securityGroups": [
346                 self.mano['details']['sec_group']
347             ],
348             "type": "openstack",
349             "location": {
350                 "name": "opnfv",
351                 "latitude": "52.525876",
352                 "longitude": "13.314400"
353             }
354         }
355         self.logger.info("Built VIM descriptor: %s", vim_json)
356         return vim_json
357
358     def deploy_orchestrator(self):
359         self.logger.info("Deploying Open Baton...")
360         self.logger.info("Details: %s", self.mano['details'])
361         start_time = time.time()
362
363         self.logger.info("Creating orchestra instance...")
364         userdata = get_userdata(self.mano)
365         self.logger.info("flavor: %s\n"
366                          "image: %s\n"
367                          "network_id: %s\n",
368                          self.mano['details']['flavor']['name'],
369                          self.mano['requirements']['image'],
370                          self.mano['details']['network']['id'])
371         self.logger.debug("userdata: %s\n", userdata)
372         # setting up image
373         image_settings = ImageConfig(
374             name=self.mano['requirements']['image'],
375             image_user='ubuntu',
376             exists=True)
377         # setting up port
378         port_settings = PortConfig(
379             name='{}_port-{}'.format(self.case_name, self.uuid),
380             network_name=self.mano['details']['network']['name'])
381         # build configuration of vm
382         orchestra_settings = VmInstanceConfig(
383             name='{}-{}'.format(self.case_name, self.uuid),
384             flavor=self.mano['details']['flavor']['name'],
385             port_settings=[port_settings],
386             security_group_names=[self.mano['details']['sec_group']],
387             floating_ip_settings=[FloatingIpConfig(
388                 name='orchestra_fip-{}'.format(self.uuid),
389                 port_name=port_settings.name,
390                 router_name=self.orchestra_router.router_settings.name)],
391             userdata=str(userdata))
392         orchestra_vm = OpenStackVmInstance(
393             self.snaps_creds, orchestra_settings, image_settings)
394         orchestra_vm.create()
395         self.mano['details']['fip'] = orchestra_vm.get_floating_ip()
396         self.created_resources.append(orchestra_vm)
397         self.mano['details']['id'] = orchestra_vm.get_vm_info()['id']
398         self.logger.info(
399             "Created orchestra instance: %s", self.mano['details']['id'])
400         self.logger.info("Waiting for Open Baton NFVO to be up and running...")
401         timeout = 0
402         while timeout < 20:
403             if servertest(
404                     self.mano['details']['fip'].ip,
405                     "8080"):
406                 break
407             else:
408                 self.logger.info("Open Baton NFVO is not started yet (%ss)",
409                                  (timeout * 60))
410                 time.sleep(60)
411                 timeout += 1
412
413         if timeout >= 20:
414             duration = time.time() - start_time
415             self.details["orchestrator"].update(
416                 status='FAIL', duration=duration)
417             self.logger.error("Open Baton is not started correctly")
418             return False
419
420         self.logger.info("Waiting for all components to be up and running...")
421         time.sleep(60)
422         duration = time.time() - start_time
423         self.details["orchestrator"].update(status='PASS', duration=duration)
424         self.logger.info("Deploy Open Baton NFVO: OK")
425         return True
426
427     def deploy_vnf(self):
428         start_time = time.time()
429         self.logger.info("Deploying %s...", self.vnf['name'])
430
431         main_agent = MainAgent(
432             nfvo_ip=self.mano['details']['fip'].ip,
433             nfvo_port=8080,
434             https=False,
435             version=1,
436             username=self.mano['credentials']['username'],
437             password=self.mano['credentials']['password'])
438
439         self.logger.info(
440             "Create %s Flavor if not existing", self.vnf['name'])
441         flavor_settings = FlavorConfig(
442             name=self.vnf['requirements']['flavor']['name'],
443             ram=self.vnf['requirements']['flavor']['ram_min'],
444             disk=self.vnf['requirements']['flavor']['disk'],
445             vcpus=self.vnf['requirements']['flavor']['vcpus'])
446         flavor = OpenStackFlavor(self.snaps_creds, flavor_settings)
447         flavor_info = flavor.create()
448         self.logger.debug("Flavor id: %s", flavor_info.id)
449
450         self.logger.info("Getting project 'default'...")
451         project_agent = main_agent.get_agent("project", "")
452         for project in json.loads(project_agent.find()):
453             if project.get("name") == "default":
454                 self.mano['details']['project_id'] = project.get("id")
455                 self.logger.info("Found project 'default': %s", project)
456                 break
457
458         vim_json = self.get_vim_descriptor()
459         self.logger.info("Registering VIM: %s", vim_json)
460
461         main_agent.get_agent(
462             "vim", project_id=self.mano['details']['project_id']).create(
463                 entity=json.dumps(vim_json))
464
465         market_agent = main_agent.get_agent(
466             "market", project_id=self.mano['details']['project_id'])
467
468         try:
469             self.logger.info("sending: %s", self.vnf['descriptor']['url'])
470             nsd = market_agent.create(entity=self.vnf['descriptor']['url'])
471             if nsd.get('id') is None:
472                 self.logger.error("NSD not onboarded correctly")
473                 duration = time.time() - start_time
474                 self.details["vnf"].update(status='FAIL', duration=duration)
475                 return False
476             self.mano['details']['nsd_id'] = nsd.get('id')
477             self.logger.info("Onboarded NSD: " + nsd.get("name"))
478
479             nsr_agent = main_agent.get_agent(
480                 "nsr", project_id=self.mano['details']['project_id'])
481
482             self.mano['details']['nsr'] = nsr_agent.create(
483                 self.mano['details']['nsd_id'])
484         except NfvoException:
485             self.logger.exception("failed")
486             duration = time.time() - start_time
487             self.details["vnf"].update(status='FAIL', duration=duration)
488             return False
489
490         if self.mano['details']['nsr'].get('code') is not None:
491             self.logger.error(
492                 "%s cannot be deployed: %s -> %s",
493                 self.vnf['name'],
494                 self.mano['details']['nsr'].get('code'),
495                 self.mano['details']['nsr'].get('message'))
496             self.logger.error("%s cannot be deployed", self.vnf['name'])
497             duration = time.time() - start_time
498             self.details["vnf"].update(status='FAIL', duration=duration)
499             return False
500
501         timeout = 0
502         self.logger.info("Waiting for NSR to go to ACTIVE...")
503         while self.mano['details']['nsr'].get("status") != 'ACTIVE' \
504                 and self.mano['details']['nsr'].get("status") != 'ERROR':
505             timeout += 1
506             self.logger.info("NSR is not yet ACTIVE... (%ss)", 60 * timeout)
507             if timeout == 30:
508                 self.logger.error("INACTIVE NSR after %s sec..", 60 * timeout)
509                 duration = time.time() - start_time
510                 self.details["vnf"].update(status='FAIL', duration=duration)
511                 return False
512             time.sleep(60)
513             self.mano['details']['nsr'] = json.loads(
514                 nsr_agent.find(self.mano['details']['nsr'].get('id')))
515
516         duration = time.time() - start_time
517         if self.mano['details']['nsr'].get("status") == 'ACTIVE':
518             self.details["vnf"].update(status='PASS', duration=duration)
519             self.logger.info("Sleep for 60s to ensure that all "
520                              "services are up and running...")
521             time.sleep(60)
522             result = True
523         else:
524             self.details["vnf"].update(status='FAIL', duration=duration)
525             self.logger.error("NSR: %s", self.mano['details'].get('nsr'))
526             result = False
527         return result
528
529     def test_vnf(self):
530         self.logger.info("Testing VNF OpenIMS...")
531         start_time = time.time()
532         self.logger.info(
533             "Testing if %s works properly...",
534             self.mano['details']['nsr'].get('name'))
535         for vnfr in self.mano['details']['nsr'].get('vnfr'):
536             self.logger.info(
537                 "Checking ports %s of VNF %s",
538                 self.vnf['test'][vnfr.get('name')]['ports'],
539                 vnfr.get('name'))
540             for vdu in vnfr.get('vdu'):
541                 for vnfci in vdu.get('vnfc_instance'):
542                     self.logger.debug(
543                         "Checking ports of VNFC instance %s",
544                         vnfci.get('hostname'))
545                     for floating_ip in vnfci.get('floatingIps'):
546                         self.logger.debug(
547                             "Testing %s:%s",
548                             vnfci.get('hostname'),
549                             floating_ip.get('ip'))
550                         for port in self.vnf['test'][vnfr.get(
551                                 'name')]['ports']:
552                             if servertest(floating_ip.get('ip'), port):
553                                 self.logger.info(
554                                     "VNFC instance %s is reachable at %s:%s",
555                                     vnfci.get('hostname'),
556                                     floating_ip.get('ip'),
557                                     port)
558                             else:
559                                 self.logger.error(
560                                     "VNFC instance %s is not reachable "
561                                     "at %s:%s",
562                                     vnfci.get('hostname'),
563                                     floating_ip.get('ip'),
564                                     port)
565                                 duration = time.time() - start_time
566                                 self.details["test_vnf"].update(
567                                     status='FAIL', duration=duration, esult=(
568                                         "Port %s of server %s -> %s is "
569                                         "not reachable",
570                                         port,
571                                         vnfci.get('hostname'),
572                                         floating_ip.get('ip')))
573                                 self.logger.error("Test VNF: ERROR")
574                                 return False
575         duration = time.time() - start_time
576         self.details["test_vnf"].update(status='PASS', duration=duration)
577         self.logger.info("Test VNF: OK")
578         return True
579
580     def clean(self):
581         self.logger.info("Cleaning %s...", self.case_name)
582         try:
583             main_agent = MainAgent(
584                 nfvo_ip=self.mano['details']['fip'].ip,
585                 nfvo_port=8080, https=False, version=1,
586                 username=self.mano['credentials']['username'],
587                 password=self.mano['credentials']['password'])
588             self.logger.info("Terminating %s...", self.vnf['name'])
589             if self.mano['details'].get('nsr'):
590                 main_agent.get_agent(
591                     "nsr",
592                     project_id=self.mano['details']['project_id']).\
593                         delete(self.mano['details']['nsr'].get('id'))
594                 self.logger.info("Sleeping 60 seconds...")
595                 time.sleep(60)
596             else:
597                 self.logger.info("No need to terminate the VNF...")
598         except (NfvoException, KeyError) as exc:
599             self.logger.error('Unexpected error cleaning - %s', exc)
600         super(OpenImsVnf, self).clean()