141 - Support for Package Management in SO
[osm/SO.git] / rwlaunchpad / plugins / rwpkgmgr / rift / tasklets / rwpkgmgr / proxy / filesystem.py
diff --git a/rwlaunchpad/plugins/rwpkgmgr/rift/tasklets/rwpkgmgr/proxy/filesystem.py b/rwlaunchpad/plugins/rwpkgmgr/rift/tasklets/rwpkgmgr/proxy/filesystem.py
new file mode 100644 (file)
index 0000000..a303424
--- /dev/null
@@ -0,0 +1,128 @@
+#
+#   Copyright 2016 RIFT.IO Inc
+#
+#   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.
+#
+# Author(s): Varun Prasad
+# Creation Date: 09/25/2016
+#
+
+import asyncio
+import os
+
+import rift.package.store as store
+import rift.package.package
+
+from .base import AbstractPackageManagerProxy
+
+
+class UnknownPackageType(Exception):
+    pass
+
+
+class FileSystemProxy(AbstractPackageManagerProxy):
+    """Proxy for Filesystem based store.
+    """
+    PACKAGE_TYPE_MAP = {"vnfd": store.VnfdPackageFilesystemStore,
+                        "nsd": store.NsdPackageFilesystemStore}
+
+    # Refer: https://confluence.riftio.com/display/ATG/Launchpad+package+formats
+    SCHEMA = {
+        "nsd": ["icons", "ns_config", "scripts", "vnf_config"],
+        "vnfd": ["charms", "cloud_init", "icons", "images", "scripts"]
+    }
+
+    SCHEMA_TO_PERMS = {'scripts': 0o777}
+
+    def __init__(self, loop, log):
+        self.loop = loop
+        self.log = log
+        self.store_cache = {}
+
+    def _get_store(self, package_type):
+        store_cls = self.PACKAGE_TYPE_MAP[package_type]
+        store = self.store_cache.setdefault(package_type, store_cls(self.log))
+
+        return store
+
+    @asyncio.coroutine
+    def endpoint(self, package_type, package_id):
+        package_type = package_type.lower()
+        if package_type not in self.PACKAGE_TYPE_MAP:
+            raise UnknownPackageType()
+
+        store = self._get_store(package_type)
+
+        package = store._get_package_dir(package_id)
+        rel_path = os.path.relpath(package, start=store.root_dir)
+
+        url = "https://127.0.0.1:4567/api/package/{}/{}".format(package_type, rel_path)
+
+        return url
+
+    @asyncio.coroutine
+    def schema(self, package_type):
+        package_type = package_type.lower()
+        if package_type not in self.PACKAGE_TYPE_MAP:
+            raise UnknownPackageType()
+
+        return self.SCHEMA[package_type]
+
+    def package_file_add(self, new_file, package_type, package_id, package_path):
+        # Get the schema from thr package path
+        # the first part will always be the vnfd/nsd name
+        mode = 0o664
+        components = package_path.split("/")
+        if len(components) > 2:
+            schema = components[1]
+            mode = self.SCHEMA_TO_PERMS.get(schema, mode)
+
+        # Fetch the package object
+        package_type = package_type.lower()
+        store = self._get_store(package_type)
+        package = store.get_package(package_id)
+
+        # Construct abs path of the destination obj
+        path = store._get_package_dir(package_id)
+        dest_file = os.path.join(path, package_path)
+
+        try:
+            package.insert_file(new_file, dest_file, package_path, mode=mode)
+        except rift.package.package.PackageAppendError as e:
+            self.log.exception(e)
+            return False
+
+        return True
+
+    def package_file_delete(self, package_type, package_id, package_path):
+        package_type = package_type.lower()
+        store = self._get_store(package_type)
+        package = store.get_package(package_id)
+
+        # package_path has to be relative, so strip off the starting slash if
+        # provided incorrectly.
+        if package_path[0] == "/":
+            package_path = package_path[1:]
+
+        # Construct abs path of the destination obj
+        path = store._get_package_dir(package_id)
+        dest_file = os.path.join(path, package_path)
+
+        try:
+            package.delete_file(dest_file, package_path)
+        except rift.package.package.PackageAppendError as e:
+            self.log.exception(e)
+            return False
+
+        return True
+