Просмотр исходного кода

Raise error directly from API service on duplicated instances lists.

Nashwan Azhari 5 лет назад
Родитель
Сommit
c71dbc6710
3 измененных файлов с 31 добавлено и 3 удалено
  1. 2 1
      coriolis/api/v1/migrations.py
  2. 3 2
      coriolis/api/v1/replicas.py
  3. 26 0
      coriolis/api/v1/utils.py

+ 2 - 1
coriolis/api/v1/migrations.py

@@ -61,7 +61,8 @@ class MigrationController(api_wsgi.Controller):
             'destination_minion_pool_id')
         instance_osmorphing_minion_pool_mappings = migration.get(
             'instance_osmorphing_minion_pool_mappings', {})
-        instances = migration["instances"]
+        instances = api_utils.validate_instances_list_for_transfer(
+            migration.get('instances'))
         extras = [
             instance
             for instance in instance_osmorphing_minion_pool_mappings

+ 3 - 2
coriolis/api/v1/replicas.py

@@ -60,7 +60,9 @@ class ReplicaController(api_wsgi.Controller):
         destination_endpoint_id = replica["destination_endpoint_id"]
         destination_environment = replica.get(
             "destination_environment", {})
-        instances = replica["instances"]
+        instances = api_utils.validate_instances_list_for_transfer(
+            replica.get('instances'))
+
         notes = replica.get("notes")
 
         source_environment = replica.get("source_environment", {})
@@ -83,7 +85,6 @@ class ReplicaController(api_wsgi.Controller):
                 "provided for instances (%s) which are not part of the "
                 "Replicas's declared instances (%s)" % (extras, instances))
 
-
         # TODO(aznashwan): until the provider plugin interface is updated
         # to have separate 'network_map' and 'storage_mappings' fields,
         # we add them as part of the destination environment:

+ 26 - 0
coriolis/api/v1/utils.py

@@ -125,3 +125,29 @@ def normalize_user_scripts(user_scripts, instances):
             user_scripts.pop(instance, None)
 
     return user_scripts
+
+
+def validate_instances_list_for_transfer(instances):
+    if not instances:
+        raise exception.InvalidInput(
+            "No instance identifiers provided for transfer action.")
+
+    if not isinstance(instances, list):
+        raise exception.InvalidInput(
+            "Instances must be a list. Got type %s: %s" % (
+                type(instances), instances))
+
+    appearances = {}
+    for instance in instances:
+        if instance in appearances:
+            appearances[instance] = appearances[instance] + 1
+        else:
+            appearances[instance] = 1
+    duplicates = {
+        inst: count for (inst, count) in appearances.items() if count > 1}
+    if duplicates:
+        raise exception.InvalidInput(
+            "Transfer action instances (%s) list contained duplicates: %s " % (
+                instances, duplicates))
+
+    return instances