فهرست منبع

Licensing v2 update fixes.

Daniel Vincze 6 سال پیش
والد
کامیت
de834d8967
2فایلهای تغییر یافته به همراه54 افزوده شده و 36 حذف شده
  1. 35 8
      coriolis/conductor/rpc/server.py
  2. 19 28
      coriolis/licensing/client.py

+ 35 - 8
coriolis/conductor/rpc/server.py

@@ -331,7 +331,8 @@ class ConductorServerEndpoint(object):
             transfer_type, ninstances)
         transfer_action.reservation_id = reservation['id']
 
-    def _check_reservation_for_transfer(self, transfer_action):
+    def _check_reservation_for_transfer(
+            self, transfer_action, reservation_type):
         action_id = transfer_action.base_id
         if not self._licensing_client:
             LOG.warn(
@@ -344,13 +345,37 @@ class ConductorServerEndpoint(object):
             LOG.debug(
                 "Attempting to check reservation with ID '%s' for transfer "
                 "action '%s'", reservation_id, action_id)
-            transfer_action.reservation_id = (
-                self._licensing_client.check_refresh_reservation(
-                    reservation_id)['id'])
+            try:
+                transfer_action.reservation_id = (
+                    self._licensing_client.check_refresh_reservation(
+                        reservation_id)['id'])
+            except Exception as ex:
+                exc_code = getattr(ex, 'code', None)
+                if exc_code in [404, 409]:
+                    if exc_code == 409:
+                        LOG.debug(
+                            "Server-side exception occurred while trying to "
+                            "check the existing reservation '%s' for action "
+                            "'%s'. Attempting to create a new reservation. "
+                            "Trace was: %s",
+                            reservation_id, action_id,
+                            utils.get_exception_details())
+                    elif exc_code == 404:
+                        LOG.debug(
+                            "Could not find previous reservation with ID '%s' "
+                            "for action '%s'. Attempting to create a new "
+                            "reservation. Trace was: %s",
+                            reservation_id, action_id,
+                            utils.get_exception_details())
+                    self._check_create_reservation_for_transfer(
+                        transfer_action, reservation_type)
+                else:
+                    raise ex
         else:
             LOG.debug(
-                "Transfer action '%s' has no reservation ID set. Skipping "
-                "all reservation licensing checks.", action_id)
+                "Transfer action '%s' has no reservation ID set.", action_id)
+            self._check_create_reservation_for_transfer(
+                transfer_action, reservation_type)
 
     def create_endpoint(self, ctxt, name, endpoint_type, description,
                         connection_info, mapped_regions=None):
@@ -922,7 +947,8 @@ class ConductorServerEndpoint(object):
     @replica_synchronized
     def execute_replica_tasks(self, ctxt, replica_id, shutdown_instances):
         replica = self._get_replica(ctxt, replica_id)
-        self._check_reservation_for_transfer(replica)
+        self._check_reservation_for_transfer(
+            replica, licensing_client.RESERVATION_TYPE_REPLICA)
         self._check_replica_running_executions(ctxt, replica)
         self._check_minion_pools_for_action(ctxt, replica)
 
@@ -1487,7 +1513,8 @@ class ConductorServerEndpoint(object):
                                  skip_os_morphing=False,
                                  user_scripts=None):
         replica = self._get_replica(ctxt, replica_id)
-        self._check_reservation_for_transfer(replica)
+        self._check_reservation_for_transfer(
+            replica, licensing_client.RESERVATION_TYPE_REPLICA)
         self._check_replica_running_executions(ctxt, replica)
         self._check_valid_replica_tasks_execution(replica, force)
 

+ 19 - 28
coriolis/licensing/client.py

@@ -3,7 +3,6 @@
 
 import json
 import os
-import uuid
 
 import requests
 
@@ -23,7 +22,7 @@ RESERVATION_TYPE_MIGRATION = "migration"
 class LicensingClient(object):
     """ Class for accessing the Coriolis licensing server API. """
 
-    def __init__(self, base_url, appliance_id, allow_untrusted=False):
+    def __init__(self, base_url, appliance_id=None, allow_untrusted=False):
         """ :param base_url: URL for the API service, including scheme """
         self._base_url = base_url.rstrip('/')
         self._verify = not allow_untrusted
@@ -46,30 +45,16 @@ class LicensingClient(object):
             return None
         allow_untrusted = os.environ.get(
             "LICENSING_SERVER_ALLOW_UNTRUSTED", False)
-        appliance_id_file = os.environ.get("LICENSING_SERVER_APPLIANCE_ID")
-        if appliance_id_file in ["", None, "None", "null"]:
-            LOG.warn(
-                "No 'LICENSING_SERVER_APPLIANCE_ID' env var present. "
-                "Cannot instantiate licensing client.")
-            return None
-
-        if not os.path.exists(appliance_id_file):
-            raise ValueError(
-                "Appliance licensing file '%s' doesn't exist.")
-
-        appliance_id = None
-        with open(appliance_id_file, 'r') as fin:
-            appliance_id = fin.read(36)
-        try:
-            uuid.UUID(hex=appliance_id)
-        except ValueError as ex:
-            raise ValueError(
-                "Improperly formatted appliance ID in '%s' for licensing "
-                "client connection: '%s'" % (
-                    appliance_id_file, appliance_id)) from ex
-
-        # try out client:
-        client = cls(base_url, appliance_id, allow_untrusted=allow_untrusted)
+        client = cls(
+            base_url, appliance_id=None, allow_untrusted=allow_untrusted)
+        appliance_ids = client.get_appliances()
+        if not appliance_ids:
+            client._appliance_id = client.create_appliance().get("id")
+        elif len(appliance_ids) == 1:
+            client._appliance_id = appliance_ids[0].get('id')
+        else:
+            raise exception.CoriolisException(
+                'More than one appliance IDs found.')
         client.get_licence_status()
 
         return client
@@ -140,7 +125,8 @@ class LicensingClient(object):
         return resp_data
 
     def _get(self, resource, response_key=None, appliance_scoped=True):
-        return self._do_req("GET", resource, response_key=response_key)
+        return self._do_req("GET", resource, response_key=response_key,
+                            appliance_scoped=appliance_scoped)
 
     def _post(self, resource, body, response_key=None, appliance_scoped=True):
         return self._do_req(
@@ -170,7 +156,12 @@ class LicensingClient(object):
     def get_appliance(self):
         """ Get the appliance corresponding to this client instance. """
         return self._get(
-            "/%s" % self._appliance_id, response_key="appliance",
+            "/appliances/%s" % self._appliance_id, response_key="appliance",
+            appliance_scoped=False)
+
+    def create_appliance(self):
+        return self._post(
+            "/appliances", body=None, response_key="appliance",
             appliance_scoped=False)
 
     def get_licence_status(self):