Adding PaaS Service Creation

Adding AbstractPaasConnector and JujuPaasService Classes

Change-Id: I1678a8aa9d9fa453c5e21a340c29c35c82989594
Signed-off-by: Gulsum Atici <gulsum.atici@canonical.com>
diff --git a/osm_lcm/paas_conn.py b/osm_lcm/paas_conn.py
new file mode 100644
index 0000000..78638b3
--- /dev/null
+++ b/osm_lcm/paas_conn.py
@@ -0,0 +1,213 @@
+#!/usr/bin/python3
+#
+# Copyright 2022 Canonical Ltd.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+#     Unless required by applicable law or agreed to in writing, software
+#     distributed under the License is distributed on an "AS IS" BASIS,
+#     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#     See the License for the specific language governing permissions and
+#     limitations under the License.
+
+import abc
+import asyncio
+import logging
+
+
+def paas_connector_factory(
+    uuid: str,
+    name: str,
+    db: object,
+    fs: object,
+    loop: object,
+    log: object,
+    config: dict,
+    paas_type="juju",
+):
+    """Factory Method to create the paas_connector objects according to PaaS Type.
+    Args:
+        uuid    (str):              Internal id of PaaS account
+        name    (str):              name assigned to PaaS account, can be used for logging
+        db  (object):               Database object to write current operation status
+        fs  (object):               Filesystem object to use during operations
+        loop    (object):           Async event loop object
+        log (object):               Logger for tracing
+        config  (dict):             Dictionary with extra PaaS information.
+        paas_type   (str):          Identifier to create paas_connector object using correct PaaS Connector Class
+
+    Returns:
+        paas_connector  (object):   paas_connector objects created according to given PaaS Type
+
+    Raises:
+        PaasConnException
+    """
+    connectors = {
+        "juju": JujuPaasConnector,
+    }
+    if paas_type not in connectors.keys():
+        raise PaasConnException(f"PaaS type: {paas_type} is not available.")
+
+    return connectors[paas_type](uuid, name, db, fs, loop, log, config)
+
+
+class PaasConnException(Exception):
+    """PaaS Connector Exception Base Class"""
+
+    def __init__(self, message: str = ""):
+        """Constructor of PaaS Connector Exception
+        Args:
+            message (str):  error message to be raised
+        """
+        Exception.__init__(self, message)
+        self.message = message
+
+    def __str__(self):
+        return self.message
+
+    def __repr__(self):
+        return "{}({})".format(type(self), self.message)
+
+
+class JujuPaasConnException(PaasConnException):
+    """Juju PaaS Connector Exception Class"""
+
+
+class AbstractPaasConnector(abc.ABC):
+    """Abstract PaaS Connector class to perform operations using PaaS Orchestrator."""
+
+    def __init__(
+        self,
+        uuid=None,
+        name=None,
+        db=None,
+        fs=None,
+        logger=None,
+        loop=None,
+        config=None,
+    ):
+        """Constructor of PaaS Connector.
+        Args:
+            uuid    (str):      internal id of PaaS account
+            name    (str):      name assigned to this account, can be used for logging
+            db  (object):       database object to write current operation status
+            fs  (object):       Filesystem object to use during operations
+            logger (object):    Logger for tracing
+            loop    (object):   Async event loop object
+            config  (dict):     Dictionary with extra PaaS information.
+        """
+        self.id = uuid
+        self.name = name
+        self.db = db
+        self.fs = fs
+        self.config = config or {}
+        self.logger = logger
+
+    @abc.abstractmethod
+    async def connect(self, endpoints: str, user: str = None, secret: str = None):
+        """Abstract method to connect PaaS account using endpoints, user and secret.
+        Args:
+            endpoints   (str):     Endpoint/URL to connect PaaS account
+            user    (str):         User which is used to connect PaaS account
+            secret  (str):         Used for authentication
+        """
+
+    @abc.abstractmethod
+    async def instantiate(self, nsr_id: str, nslcmop_id: str):
+        """Abstract method to perform PaaS Service instantiation.
+        Args:
+            nsr_id   (str):     NS service record to be used
+            nslcmop_id  (str):  NS LCM operation id
+        """
+
+    @abc.abstractmethod
+    async def terminate(self, nsr_id: str, nslcmop_id: str):
+        """Abstract method to perform PaaS Service termination.
+        Args:
+            nsr_id   (str):     NS service record to be used
+            nslcmop_id  (str):  NS LCM operation id
+        """
+
+    @abc.abstractmethod
+    async def action(self, nsr_id: str, nslcmop_id: str):
+        """Abstract method to perform action on PaaS Service.
+        Args:
+            nsr_id   (str):     NS service record to be used
+            nslcmop_id  (str):  NS LCM operation id
+        """
+
+
+class JujuPaasConnector(AbstractPaasConnector):
+    """Concrete PaaS Connector class to perform operations using the Juju PaaS Orchestrator."""
+
+    def __init__(
+        self,
+        uuid=None,
+        name=None,
+        db=None,
+        fs=None,
+        logger=None,
+        loop=None,
+        config=None,
+    ):
+        self.logger = logging.getLogger("lcm.juju_paas_connector")
+        super(JujuPaasConnector, self).__init__(logger=self.logger)
+
+    async def connect(self, endpoints: str, user: str = None, secret: str = None):
+        """Connect Juju PaaS account using endpoints, user and secret.
+        Args:
+            endpoints   (str):     Endpoint/URL to connect PaaS account
+            user    (str):         User which is used to connect PaaS account
+            secret  (str):         Used for authentication
+
+        Raises:
+            NotImplementedError
+        """
+        raise NotImplementedError(
+            "Juju Paas Connector connect method is not implemented"
+        )
+
+    async def instantiate(self, nsr_id: str, nslcmop_id: str):
+        """Perform Service instantiation.
+        Args:
+            nsr_id   (str):     NS service record to be used
+            nslcmop_id  (str):  NS LCM operation id
+
+        Raises:
+            JujuPaasConnException
+        """
+        # This is not the real implementation
+        # Sample code blocks to validate method execution
+        await asyncio.sleep(1)
+        self.logger.debug("Juju Paas Connector instantiate method is called")
+
+    async def terminate(self, nsr_id: str, nslcmop_id: str):
+        """Perform PaaS Service termination.
+        Args:
+            nsr_id   (str):     NS service record to be used
+            nslcmop_id  (str):  NS LCM operation id
+
+        Raises:
+            JujuPaasConnException
+        """
+        # This is not the real implementation
+        # Sample code blocks to validate method execution
+        await asyncio.sleep(1)
+        self.logger.debug("Juju Paas Connector terminate method is called")
+
+    async def action(self, nsr_id: str, nslcmop_id: str):
+        """Perform action on PaaS Service.
+        Args:
+            nsr_id   (str):     NS service record to be used
+            nslcmop_id  (str):  NS LCM operation id
+
+        Raises:
+            NotImplementedError
+        """
+        raise NotImplementedError(
+            "Juju Paas Connector instantiate method is not implemented"
+        )