Add th ability to (un)load wrapper components through API 59/50659/1
authorThomas Duval <thomas.duval@orange.com>
Mon, 15 Jan 2018 20:12:32 +0000 (21:12 +0100)
committerThomas Duval <thomas.duval@orange.com>
Mon, 15 Jan 2018 20:12:32 +0000 (21:12 +0100)
Change-Id: I58a25dbc0479e416d471115885dab7ccfb27e18a

moon_manager/moon_manager/api/slaves.py [new file with mode: 0644]
moon_manager/moon_manager/http_server.py
moon_orchestrator/moon_orchestrator/api/pods.py
moon_orchestrator/moon_orchestrator/api/slaves.py [new file with mode: 0644]
moon_orchestrator/moon_orchestrator/drivers.py
moon_orchestrator/moon_orchestrator/http_server.py
moon_orchestrator/tests/unit_python/test_pods.py
moon_orchestrator/tests/unit_python/test_slaves.py [new file with mode: 0644]
python_moonutilities/Changelog
python_moonutilities/python_moonutilities/__init__.py
python_moonutilities/python_moonutilities/exceptions.py

diff --git a/moon_manager/moon_manager/api/slaves.py b/moon_manager/moon_manager/api/slaves.py
new file mode 100644 (file)
index 0000000..d87b8aa
--- /dev/null
@@ -0,0 +1,110 @@
+# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors
+# This software is distributed under the terms and conditions of the 'Apache-2.0'
+# license which can be found in the file 'LICENSE' in this package distribution
+# or at 'http://www.apache.org/licenses/LICENSE-2.0'.
+"""
+PDP are Policy Decision Point.
+
+"""
+
+from flask import request
+from flask_restful import Resource
+import logging
+import requests
+import time
+from python_moonutilities.security_functions import check_auth
+from python_moondb.core import PDPManager
+from python_moondb.core import PolicyManager
+from python_moondb.core import ModelManager
+from python_moonutilities import configuration, exceptions
+
+__version__ = "4.3.0"
+
+logger = logging.getLogger("moon.manager.api." + __name__)
+
+
+class Slaves(Resource):
+    """
+    Endpoint for pdp requests
+    """
+
+    __urls__ = (
+        "/slaves",
+        "/slaves/",
+        "/slaves/<string:uuid>",
+        "/slaves/<string:uuid>/",
+    )
+
+    def __init__(self, **kwargs):
+        conf = configuration.get_configuration("components/orchestrator")
+        self.orchestrator_hostname = conf["components/orchestrator"].get("hostname",
+                                                                         "orchestrator")
+        self.orchestrator_port = conf["components/orchestrator"].get("port",
+                                                                     80)
+
+    @check_auth
+    def get(self, uuid=None, user_id=None):
+        """Retrieve all slaves
+
+        :param uuid: uuid of the slave
+        :param user_id: user ID who do the request
+        :return: {
+            "slaves": {
+                "XXX": {
+                    "name": "...",
+                    "installed": True
+                },
+                "YYY": {
+                    "name": "...",
+                    "installed": False
+                }
+            }
+        }
+        """
+        req = requests.get("http://{}:{}/slaves".format(
+            self.orchestrator_hostname, self.orchestrator_port
+        ))
+        return {"slaves": req.json()}
+
+    @check_auth
+    def patch(self, uuid=None, user_id=None):
+        """Update a slave
+
+        :param uuid: uuid of the slave to update
+        :param user_id: user ID who do the request
+        :request body: {
+            "op": "replace",
+            "variable": "configured",
+            "value": True,
+        }
+        :return: 204
+        :internal_api: add_pdp
+        """
+        logger.info("Will made a request for {}".format(uuid))
+        if request.json.get("op") == "replace" \
+            and request.json.get("variable") == "configured" \
+                and request.json.get("value"):
+            req = requests.post("http://{}:{}/pods".format(
+                self.orchestrator_hostname, self.orchestrator_port,
+                ),
+                json={"slave_name": uuid}
+            )
+            if req.status_code != 200:
+                logger.warning("Get error from Orchestrator {} {}".format(
+                    req.reason, req.status_code
+                ))
+                return "Orchestrator: " + str(req.reason), req.status_code
+        elif request.json.get("op") == "replace" \
+            and request.json.get("variable") == "configured" \
+                and not request.json.get("value"):
+            req = requests.delete("http://{}:{}/pods/{}".format(
+                self.orchestrator_hostname, self.orchestrator_port, uuid
+            ))
+            if req.status_code != 200:
+                logger.warning("Get error from Orchestrator {} {}".format(
+                    req.reason, req.status_code
+                ))
+                return "Orchestrator: " + str(req.reason), req.status_code
+        else:
+            return "Malformed request", 400
+        return {"slaves": req.json()}
index d67e112..a98cab4 100644 (file)
@@ -14,6 +14,7 @@ from moon_manager.api.generic import Status, Logs, API
 from moon_manager.api.models import Models
 from moon_manager.api.policies import Policies
 from moon_manager.api.pdp import PDP
+from moon_manager.api.slaves import Slaves
 from moon_manager.api.meta_rules import MetaRules
 from moon_manager.api.meta_data import SubjectCategories, ObjectCategories, ActionCategories
 from moon_manager.api.perimeter import Subjects, Objects, Actions
@@ -32,7 +33,7 @@ __API__ = (
     Subjects, Objects, Actions, Rules,
     SubjectAssignments, ObjectAssignments, ActionAssignments,
     SubjectData, ObjectData, ActionData,
-    Models, Policies, PDP
+    Models, Policies, PDP, Slaves
  )
 
 
index 31ae31d..3a01c3a 100644 (file)
@@ -6,6 +6,7 @@
 from flask import request
 from flask_restful import Resource
 from python_moonutilities.security_functions import check_auth
+from python_moonutilities import exceptions
 import logging
 
 logger = logging.getLogger("moon.orchestrator.api.pods")
@@ -17,6 +18,7 @@ class Pods(Resource):
     """
 
     __version__ = "4.3.1"
+    POD_TYPES = ("authz", "wrapper")
 
     __urls__ = (
         "/pods",
@@ -57,6 +59,21 @@ class Pods(Resource):
         except Exception as e:
             return {"result": False, "message": str(e)}, 500
 
+    def __get_pod_with_keystone_pid(self, keystone_pid):
+        for pod_key, pod_values in self.driver.get_pods().items():
+            if pod_values[0]['keystone_project_id'] == keystone_pid:
+                return True
+
+    def __get_wrapper(self, slave_name):
+        for slave in self.driver.get_slaves():
+            if slave_name == slave["name"] \
+                    and slave["configured"]:
+                return True
+
+    def __get_slave_names(self):
+        for slave in self.driver.get_slaves():
+            yield slave["name"]
+
     @check_auth
     def post(self, uuid=None, user_id=None):
         """Create a new pod.
@@ -64,9 +81,14 @@ class Pods(Resource):
         :param uuid: uuid of the pod (not used here)
         :param user_id: user ID who do the request
         :request body: {
-            "name": "...",
-            "description": "...",
-            "type": "plugin_name"
+            "pdp_id": "fa2323f7055d4a88b1b85d31fe5e8369",
+            "name": "pdp_rbac3",
+            "keystone_project_id": "ceacbb5564cc48ad929dd4f00e52bf63",
+            "models": {...},
+            "policies": {...},
+            "description": "test",
+            "security_pipeline": [...],
+            "slave_name": ""
         }
         :return: {
             "pdp_id1": {
@@ -76,25 +98,35 @@ class Pods(Resource):
             }
         }
         """
-        logger.debug("POST param={}".format(request.json))
-        try:
+        pods = {}
+        if "security_pipeline" in request.json:
+            if self.__get_pod_with_keystone_pid(request.json.get("keystone_project_id")):
+                raise exceptions.PipelineConflict
             self.driver.create_pipeline(
                 request.json.get("keystone_project_id"),
                 request.json.get("pdp_id"),
                 request.json.get("security_pipeline"),
                 manager_data=request.json,
-                active_context=None,
-                active_context_name=None)
-            pods = {}
+                slave_name=request.json.get("slave_name"))
             for _pod_key, _pod_values in self.driver.get_pods().items():
                 pods[_pod_key] = []
                 for _pod_value in _pod_values:
                     if _pod_value['namespace'] != "moon":
                         continue
                     pods[_pod_key].append(_pod_value)
-            return {"pods": pods}
-        except Exception as e:
-            return {"result": False, "message": str(e)}, 500
+        else:
+            logger.info("------------------------------------")
+            logger.info(list(self.__get_slave_names()))
+            logger.info("------------------------------------")
+            if self.__get_wrapper(request.json.get("slave_name")):
+                raise exceptions.WrapperConflict
+            if request.json.get("slave_name") not in self.__get_slave_names():
+                raise exceptions.SlaveNameUnknown
+            slave_name = request.json.get("slave_name")
+            if not slave_name:
+                slave_name = self.driver.get_slaves(active=True)
+            self.driver.create_wrappers(slave_name)
+        return {"pods": self.driver.get_pods()}
 
     @check_auth
     def delete(self, uuid=None, user_id=None):
@@ -110,27 +142,31 @@ class Pods(Resource):
         try:
             self.driver.delete_pipeline(uuid)
             return {'result': True}
+        except exceptions.PipelineUnknown:
+            for slave in self.driver.get_slaves():
+                if uuid in (slave['name'], slave["wrapper_name"]):
+                    self.driver.delete_wrapper(name=slave["wrapper_name"])
         except Exception as e:
             return {"result": False, "message": str(e)}, 500
 
-    @check_auth
-    def patch(self, uuid=None, user_id=None):
-        """Update a pod
-
-        :param uuid: uuid of the pdp to update
-        :param user_id: user ID who do the request
-        :request body: {
-            "name": "...",
-            "replicas": "...",
-            "description": "...",
-        }
-        :return: {
-            "pod_id1": {
-                "name": "...",
-                "replicas": "...",
-                "description": "...",
-            }
-        }
-        :internal_api: update_pdp
-        """
-        return {"pods": None}
+    @check_auth
+    def patch(self, uuid=None, user_id=None):
+        """Update a pod
+    #
+        :param uuid: uuid of the pdp to update
+        :param user_id: user ID who do the request
+        :request body: {
+            "name": "...",
+            "replicas": "...",
+            "description": "...",
+        }
+        :return: {
+            "pod_id1": {
+                "name": "...",
+                "replicas": "...",
+                "description": "...",
+            }
+        }
+        :internal_api: update_pdp
+        """
+        return {"pods": None}
diff --git a/moon_orchestrator/moon_orchestrator/api/slaves.py b/moon_orchestrator/moon_orchestrator/api/slaves.py
new file mode 100644 (file)
index 0000000..7453d30
--- /dev/null
@@ -0,0 +1,46 @@
+# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors
+# This software is distributed under the terms and conditions of the 'Apache-2.0'
+# license which can be found in the file 'LICENSE' in this package distribution
+# or at 'http://www.apache.org/licenses/LICENSE-2.0'.
+
+from flask import request
+from flask_restful import Resource
+from python_moonutilities.security_functions import check_auth
+import logging
+
+logger = logging.getLogger("moon.orchestrator.api.slaves")
+
+
+class Slaves(Resource):
+    """
+    Endpoint for slaves requests
+    """
+
+    __version__ = "4.3.1"
+
+    __urls__ = (
+        "/slaves",
+        "/slaves/",
+        "/slaves/<string:uuid>",
+        "/slaves/<string:uuid>/",
+    )
+
+    def __init__(self, **kwargs):
+        self.driver = kwargs.get("driver")
+
+    @check_auth
+    def get(self, uuid=None, user_id=None):
+        """Retrieve all pods
+
+        :param uuid: uuid of the pod
+        :param user_id: user ID who do the request
+        :return: {
+            "pod_id1": {
+                "name": "...",
+                "replicas": "...",
+                "description": "...",
+            }
+        }
+        """
+        slaves = self.driver.get_slaves()
+        return {"slaves": slaves}
index 9c230cc..bb0d0c2 100644 (file)
@@ -159,17 +159,17 @@ class K8S(Driver):
         resp = client.create_namespaced_service(namespace="moon",
                                                 body=service_manifest)
         logger.info("Service {} created!".format(data.get('name')))
-        return resp
+        return service_manifest
 
     def load_deployment_and_service(self, data, api_client=None, ext_client=None, expose=False):
         _client = api_client if api_client else self.client
+        manifest = self.__create_service(client=_client, data=data[0],
+                                         expose=expose)
+        data[0]["external_port"] = manifest['spec']['ports'][0].get('nodePort')
         pod = self.__create_deployment(client=ext_client, data=data)
-        self.__create_service(client=_client, data=data[0],
-                              expose=expose)
         self.cache[pod.metadata.uid] = data
 
-    @staticmethod
-    def delete_deployment(name=None, namespace="moon", ext_client=None):
+    def delete_deployment(self, name=None, namespace="moon", ext_client=None):
         logger.info("Deleting deployment {}".format(name))
         body = client.V1DeleteOptions(propagation_policy='Foreground')
         ret = ext_client.delete_namespaced_deployment(
@@ -177,7 +177,16 @@ class K8S(Driver):
             namespace=namespace,
             body=body
         )
-        logger.info(ret)
+        logger.debug(ret)
+        _uid = None
+        for uid, value in self.cache.items():
+            if value[0]['name'] == name:
+                _uid = uid
+                break
+        if _uid:
+            self.cache.pop(_uid)
+        else:
+            raise exceptions.DockerError("Cannot find and delete pod named {}".format(name))
 
     def delete_service(self, name, namespace="moon", api_client=None):
         if not api_client:
@@ -185,12 +194,45 @@ class K8S(Driver):
         ret = api_client.delete_namespaced_service(name=name, namespace=namespace)
         logger.debug("delete_service {}".format(ret))
 
-    def get_slaves(self):
+    def get_slaves(self, active=False):
+        contexts, active_context = self.get_contexts()
+        pods = self.get_pods()
+        # logger.info("pods = {}".format(pods))
+        slaves = []
+        if active:
+            for key, value in pods.items():
+                # logger.info("ctx={}".format(active_context))
+                # logger.info("value={}".format(value))
+                if active_context["name"] == value[0].get('slave_name'):
+                    data = dict(active_context)
+                    data["wrapper_name"] = value[0]['name']
+                    data["ip"] = value[0].get("ip", "NC")
+                    data["port"] = value[0].get("external_port", "NC")
+                    slaves.append(data)
+                    break
+            return slaves
+        for ctx in contexts:
+            data = dict(ctx)
+            data["configured"] = False
+            for key, value in pods.items():
+                # logger.info("ctx={}".format(ctx))
+                # logger.info("value={}".format(value))
+                if ctx["name"] == value[0].get('slave_name'):
+                    data["wrapper_name"] = value[0]['name']
+                    data["ip"] = value[0].get("ip", "NC")
+                    data["port"] = value[0].get("external_port", "NC")
+                    data["configured"] = True
+                    break
+            slaves.append(data)
+        return slaves
+
+    @staticmethod
+    def get_contexts():
         contexts, active_context = config.list_kube_config_contexts()
         return contexts, active_context
 
-    def create_wrappers(self):
-        contexts, active_context = self.get_slaves()
+    def create_wrappers(self, slave_name=None):
+        contexts, active_context = self.get_contexts()
         logger.debug("contexts: {}".format(contexts))
         logger.debug("active_context: {}".format(active_context))
         conf = configuration.get_configuration("components/wrapper")
@@ -201,6 +243,8 @@ class K8S(Driver):
             "container",
             "wukongsun/moon_wrapper:v4.3")
         for _ctx in contexts:
+            if slave_name and slave_name != _ctx['name']:
+                continue
             _config = config.new_client_from_config(context=_ctx['name'])
             logger.debug("_config={}".format(_config))
             api_client = client.CoreV1Api(_config)
@@ -209,14 +253,56 @@ class K8S(Driver):
                 "name": hostname + "-" + get_random_name(),
                 "container": container,
                 "port": port,
-                "namespace": "moon"
+                "namespace": "moon",
+                "slave_name": _ctx['name']
             }, ]
             self.load_deployment_and_service(data, api_client, ext_client, expose=True)
 
+    def delete_wrapper(self, uuid=None, name=None, namespace="moon",
+                       active_context=None,
+                       active_context_name=None):
+        name_to_delete = None
+        if uuid and uuid in self.get_pods():
+            name_to_delete = self.get_pods()[uuid][0]['name']
+        elif name:
+            for pod_key, pod_list in self.get_pods().items():
+                for pod_value in pod_list:
+                    if pod_value.get("name") == name:
+                        name_to_delete = pod_value.get("name")
+                        break
+        if not name_to_delete:
+            raise exceptions.WrapperUnknown
+        contexts, _active_context = self.get_contexts()
+        if active_context_name:
+            for _context in contexts:
+                if _context["name"] == active_context_name:
+                    active_context = _context
+                    break
+        if active_context:
+            active_context = _active_context
+            _config = config.new_client_from_config(
+                context=active_context['name'])
+            logger.debug("_config={}".format(_config))
+            api_client = client.CoreV1Api(_config)
+            ext_client = client.ExtensionsV1beta1Api(_config)
+            self.delete_deployment(name=name_to_delete, namespace=namespace,
+                                   ext_client=ext_client)
+            self.delete_service(name=name_to_delete, api_client=api_client)
+            return
+        logger.debug("contexts={}".format(contexts))
+        for _ctx in contexts:
+            _config = config.new_client_from_config(context=_ctx['name'])
+            logger.debug("_config={}".format(_config))
+            api_client = client.CoreV1Api(_config)
+            ext_client = client.ExtensionsV1beta1Api(_config)
+            self.delete_deployment(name=name_to_delete, namespace=namespace,
+                                   ext_client=ext_client)
+            self.delete_service(name=name_to_delete, api_client=api_client)
+
     def create_pipeline(self, keystone_project_id,
                         pdp_id, policy_ids, manager_data=None,
                         active_context=None,
-                        active_context_name=None):
+                        slave_name=None):
         """ Create security functions
 
         :param keystone_project_id: the Keystone project id
@@ -225,7 +311,7 @@ class K8S(Driver):
         :param manager_data: data needed to create pods
         :param active_context: if present, add the security function in this
                                context
-        :param active_context_name: if present,  add the security function in
+        :param slave_name: if present,  add the security function in
                                     this context name
         if active_context_name and active_context are not present, add the
         security function in all context (ie, in all slaves)
@@ -295,12 +381,12 @@ class K8S(Driver):
                             "namespace": "moon"
                         })
         logger.debug("data={}".format(data))
-        contexts, _active_context = self.get_slaves()
-        logger.debug("active_context_name={}".format(active_context_name))
+        contexts, _active_context = self.get_contexts()
+        logger.debug("active_context_name={}".format(slave_name))
         logger.debug("active_context={}".format(active_context))
-        if active_context_name:
+        if slave_name:
             for _context in contexts:
-                if _context["name"] == active_context_name:
+                if _context["name"] == slave_name:
                     active_context = _context
                     break
         if active_context:
@@ -314,6 +400,8 @@ class K8S(Driver):
             return
         logger.debug("contexts={}".format(contexts))
         for _ctx in contexts:
+            if slave_name and slave_name != _ctx['name']:
+                continue
             _config = config.new_client_from_config(context=_ctx['name'])
             logger.debug("_config={}".format(_config))
             api_client = client.CoreV1Api(_config)
@@ -342,9 +430,9 @@ class K8S(Driver):
                         name_to_delete = pod_value.get("name")
                         break
         if not name_to_delete:
-            raise exceptions.MoonError("Cannot find pipeline")
+            raise exceptions.PipelineUnknown
         logger.info("Will delete deployment and service named {}".format(name_to_delete))
-        contexts, _active_context = self.get_slaves()
+        contexts, _active_context = self.get_contexts()
         if active_context_name:
             for _context in contexts:
                 if _context["name"] == active_context_name:
index fa5308d..85e29cd 100644 (file)
@@ -10,6 +10,7 @@ import requests
 import time
 from moon_orchestrator import __version__
 from moon_orchestrator.api.pods import Pods
+from moon_orchestrator.api.slaves import Slaves
 from moon_orchestrator.api.generic import Status
 from moon_orchestrator.drivers import get_driver
 from python_moonutilities import configuration, exceptions
@@ -122,7 +123,7 @@ class HTTPServer(Server):
                 if "pdps" in pdp.json():
                     break
         logger.debug("pdp={}".format(pdp))
-        self.driver.create_wrappers()
+        self.driver.create_wrappers()
         for _pdp_key, _pdp_value in pdp.json()['pdps'].items():
             if _pdp_value.get('keystone_project_id'):
                 # TODO: select context to add security function
@@ -151,6 +152,10 @@ class HTTPServer(Server):
                               resource_class_kwargs={
                                   "driver": self.driver
                               })
+        self.api.add_resource(Slaves, *Slaves.__urls__,
+                              resource_class_kwargs={
+                                  "driver": self.driver
+                              })
 
     def run(self):
         self.app.run(host=self._host, port=self._port)  # nosec
index f760aa6..678645b 100644 (file)
@@ -31,7 +31,7 @@ def test_get_pods_failure(context, monkeypatch):
     assert not data["pods"]
 
 
-def test_add_pods(context, monkeypatch):
+def test_add_pods_with_pipeline(context, monkeypatch):
     patch_k8s(monkeypatch)
 
     import moon_orchestrator.server
@@ -52,6 +52,60 @@ def test_add_pods(context, monkeypatch):
     assert data["pods"]
 
 
+def test_add_pods_without_pipeline_with_bad_slave_name(context, monkeypatch):
+    patch_k8s(monkeypatch)
+
+    import moon_orchestrator.server
+    server = moon_orchestrator.server.create_server()
+    _client = server.app.test_client()
+    data = {
+        "slave_name": "test",
+    }
+    req = _client.post("/pods", data=json.dumps(data),
+                       headers={'Content-Type': 'application/json'})
+    assert req.status_code == 400
+    assert req.data
+    data = get_json(req.data)
+    assert isinstance(data, dict)
+    assert 'The slave is unknown.' in data['message']
+
+
+def test_add_pods_without_pipeline_with_good_slave_name(context, monkeypatch):
+    patch_k8s(monkeypatch)
+
+    import moon_orchestrator.server
+    server = moon_orchestrator.server.create_server()
+    _client = server.app.test_client()
+    data = {
+        "slave_name": "active_context",
+    }
+    req = _client.post("/pods", data=json.dumps(data),
+                       headers={'Content-Type': 'application/json'})
+    assert req.status_code == 200
+    assert req.data
+    data = get_json(req.data)
+    assert isinstance(data, dict)
+    assert "pods" in data
+    assert data["pods"]
+
+
+def test_add_pods_without_pipeline_without_slave_name(context, monkeypatch):
+    patch_k8s(monkeypatch)
+
+    import moon_orchestrator.server
+    server = moon_orchestrator.server.create_server()
+    _client = server.app.test_client()
+    data = {
+    }
+    req = _client.post("/pods", data=json.dumps(data),
+                       headers={'Content-Type': 'application/json'})
+    assert req.status_code == 400
+    assert req.data
+    data = get_json(req.data)
+    assert isinstance(data, dict)
+    assert 'The slave is unknown.' in data['message']
+
+
 def test_add_pods_with_no_data(context, monkeypatch):
     patch_k8s(monkeypatch)
     import moon_orchestrator.server
@@ -59,10 +113,10 @@ def test_add_pods_with_no_data(context, monkeypatch):
     _client = server.app.test_client()
     req = _client.post("/pods", data=json.dumps({}),
                        headers={'Content-Type': 'application/json'})
-    assert req.status_code == 500
+    assert req.status_code == 400
     assert req.data
     data = get_json(req.data)
-    assert '400: Policy Unknown' in data['message']
+    assert 'The slave is unknown.' in data['message']
 
 
 def test_add_pods_with_no_policies_no_models(context, monkeypatch, no_requests):
diff --git a/moon_orchestrator/tests/unit_python/test_slaves.py b/moon_orchestrator/tests/unit_python/test_slaves.py
new file mode 100644 (file)
index 0000000..88ff7e5
--- /dev/null
@@ -0,0 +1,17 @@
+import json
+from mock_pods import patch_k8s
+from utilities import get_json
+
+
+def test_get_slaves(context, monkeypatch):
+    patch_k8s(monkeypatch)
+
+    import moon_orchestrator.server
+    server = moon_orchestrator.server.create_server()
+    _client = server.app.test_client()
+    req = _client.get("/slaves")
+    assert req.status_code == 200
+    assert req.data
+    data = get_json(req.data)
+    assert isinstance(data, dict)
+    assert "slaves" in data
index 2c4c02a..ffc0380 100644 (file)
@@ -78,3 +78,7 @@ CHANGES
 1.4.5
 -----
 - Add PdpKeystoneMappingConflict exception
+
+1.4.6
+-----
+- Add WrapperConflict, PipelineConflict, SlaveNameUnknown exceptions
index bcd7e54..741ba4f 100644 (file)
@@ -3,6 +3,6 @@
 # license which can be found in the file 'LICENSE' in this package distribution
 # or at 'http://www.apache.org/licenses/LICENSE-2.0'.
 
-__version__ = "1.4.5"
+__version__ = "1.4.6"
 
 
index 6db7bf0..1298f9e 100644 (file)
@@ -535,6 +535,41 @@ class ContainerMissing(DockerError):
     logger = "ERROR"
 
 
+class WrapperConflict(MoonError):
+    description = _("A Wrapper already exist for the specified slave.")
+    code = 409
+    title = 'Wrapper conflict'
+    logger = "ERROR"
+
+
+class PipelineConflict(MoonError):
+    description = _("A Pipeline already exist for the specified slave.")
+    code = 409
+    title = 'Pipeline conflict'
+    logger = "ERROR"
+
+
+class PipelineUnknown(MoonError):
+    description = _("This Pipeline is unknown from the system.")
+    code = 400
+    title = 'Pipeline Unknown'
+    logger = "ERROR"
+
+
+class WrapperUnknown(MoonError):
+    description = _("This Wrapper is unknown from the system.")
+    code = 400
+    title = 'Wrapper Unknown'
+    logger = "ERROR"
+
+
+class SlaveNameUnknown(MoonError):
+    description = _("The slave is unknown.")
+    code = 400
+    title = 'Slave Unknown'
+    logger = "Error"
+
+
 class PdpUnknown(MoonError):
     description = _("The pdp is unknown.")
     code = 400