New VNFM supporting ETSI changes
[doctor.git] / doctor_tests / scenario / maintenance.py
index 09795c2..e6cdccc 100644 (file)
@@ -1,5 +1,5 @@
 ##############################################################################
-# Copyright (c) 2018 Nokia Corporation and others.
+# Copyright (c) 2019 Nokia Corporation and others.
 #
 # All rights reserved. This program and the accompanying materials
 # are made available under the terms of the Apache License, Version 2.0
@@ -28,19 +28,25 @@ class Maintenance(object):
     def __init__(self, trasport_url, conf, log):
         self.conf = conf
         self.log = log
+        self.admin_session = get_session()
         self.keystone = keystone_client(
             self.conf.keystone_version, get_session())
         self.nova = nova_client(conf.nova_version, get_session())
         auth = get_identity_auth(project=self.conf.doctor_project)
         self.neutron = neutron_client(get_session(auth=auth))
         self.stack = Stack(self.conf, self.log)
+        if self.conf.installer.type == "devstack":
+            self.endpoint_ip = trasport_url.split("@", 1)[1].split(":", 1)[0]
+        else:
+            self.endpoint_ip = self.conf.admin_tool.ip
+        self.endpoint = "http://%s:12347/" % self.endpoint_ip
         if self.conf.admin_tool.type == 'sample':
             self.admin_tool = get_admin_tool(trasport_url, self.conf, self.log)
-            self.endpoint = 'maintenance'
+            self.endpoint += 'maintenance'
         else:
-            self.endpoint = 'v1/maintenance'
+            self.endpoint += 'v1/maintenance'
         self.app_manager = get_app_manager(self.stack, self.conf, self.log)
-        self.inspector = get_inspector(self.conf, self.log)
+        self.inspector = get_inspector(self.conf, self.log, trasport_url)
 
     def get_external_network(self):
         ext_net = None
@@ -68,8 +74,16 @@ class Maintenance(object):
                 raise Exception('not enough vcpus (%d) on %s' %
                                 (vcpus, hostname))
             if vcpus_used > 0:
-                raise Exception('%d vcpus used on %s'
-                                % (vcpus_used, hostname))
+                if self.conf.test_case == 'all':
+                    # VCPU might not yet be free after fault_management test
+                    self.log.info('%d vcpus used on %s, retry...'
+                                  % (vcpus_used, hostname))
+                    time.sleep(15)
+                    hvisor = self.nova.hypervisors.get(hvisor.id)
+                    vcpus_used = hvisor.__getattr__('vcpus_used')
+                if vcpus_used > 0:
+                    raise Exception('%d vcpus used on %s'
+                                    % (vcpus_used, hostname))
             if prev_vcpus != 0 and prev_vcpus != vcpus:
                 raise Exception('%d vcpus on %s does not match to'
                                 '%d on %s'
@@ -119,8 +133,9 @@ class Maintenance(object):
         else:
             # TBD Now we expect Fenix is running in self.conf.admin_tool.port
             pass
-        self.app_manager.start()
+        # Inspector before app_manager, as floating ip might come late
         self.inspector.start()
+        self.app_manager.start()
 
     def start_maintenance(self):
         self.log.info('start maintenance.......')
@@ -129,57 +144,80 @@ class Maintenance(object):
         for hvisor in hvisors:
             hostname = hvisor.__getattr__('hypervisor_hostname')
             maintenance_hosts.append(hostname)
-
-        url = ('http://%s:%s/%s' %
-               (self.conf.admin_tool.ip,
-                self.conf.admin_tool.port,
-                self.endpoint))
-
-        # let's start maintenance 20sec from now, so projects will have
-        # time to ACK to it before that
-        maintenance_at = (datetime.datetime.utcnow() +
-                          datetime.timedelta(seconds=30)
-                          ).strftime('%Y-%m-%d %H:%M:%S')
-        data = {'hosts': maintenance_hosts,
-                'state': 'MAINTENANCE',
-                'maintenance_at': maintenance_at,
-                'metadata': {'openstack_version': 'Rocky'},
-                'workflow': 'default'}
+        url = self.endpoint
         headers = {
             'Content-Type': 'application/json',
             'Accept': 'application/json'}
-
-        ret = requests.post(url, data=json.dumps(data), headers=headers)
+        if self.conf.admin_tool.type == 'fenix':
+            headers['X-Auth-Token'] = self.admin_session.get_token()
+        self.log.info('url %s headers %s' % (url, headers))
+        retries = 12
+        ret = None
+        while retries > 0:
+            # let's start maintenance 20sec from now, so projects will have
+            # time to ACK to it before that
+            maintenance_at = (datetime.datetime.utcnow() +
+                              datetime.timedelta(seconds=30)
+                              ).strftime('%Y-%m-%d %H:%M:%S')
+
+            data = {'state': 'MAINTENANCE',
+                    'maintenance_at': maintenance_at,
+                    'metadata': {'openstack_version': 'Train'}}
+
+            if self.conf.app_manager.type == 'vnfm':
+                data['workflow'] = 'vnf'
+            else:
+                data['workflow'] = 'default'
+
+            if self.conf.admin_tool.type == 'sample':
+                data['hosts'] = maintenance_hosts
+            else:
+                data['hosts'] = []
+            try:
+                ret = requests.post(url, data=json.dumps(data),
+                                    headers=headers)
+            except Exception:
+                if retries == 0:
+                    raise Exception('admin tool did not respond in 120s')
+                else:
+                    self.log.info('admin tool not ready, retry in 10s')
+                retries = retries - 1
+                time.sleep(10)
+                continue
+            break
+        if not ret:
+            raise Exception("admin tool did not respond")
         if ret.status_code != 200:
             raise Exception(ret.text)
         return ret.json()['session_id']
 
     def remove_maintenance_session(self, session_id):
         self.log.info('remove maintenance session %s.......' % session_id)
-        url = ('http://%s:%s/%s/%s' %
-               (self.conf.admin_tool.ip,
-                self.conf.admin_tool.port,
-                self.endpoint,
-                session_id))
+
+        url = ('%s/%s' % (self.endpoint, session_id))
 
         headers = {
             'Content-Type': 'application/json',
             'Accept': 'application/json'}
 
+        if self.conf.admin_tool.type == 'fenix':
+            headers['X-Auth-Token'] = self.admin_session.get_token()
+
         ret = requests.delete(url, data=None, headers=headers)
         if ret.status_code != 200:
             raise Exception(ret.text)
 
     def get_maintenance_state(self, session_id):
-        url = ('http://%s:%s/%s/%s' %
-               (self.conf.admin_tool.ip,
-                self.conf.admin_tool.port,
-                self.endpoint,
-                session_id))
+
+        url = ('%s/%s' % (self.endpoint, session_id))
 
         headers = {
             'Content-Type': 'application/json',
             'Accept': 'application/json'}
+
+        if self.conf.admin_tool.type == 'fenix':
+            headers['X-Auth-Token'] = self.admin_session.get_token()
+
         ret = requests.get(url, data=None, headers=headers)
         if ret.status_code != 200:
             raise Exception(ret.text)