aboutsummaryrefslogtreecommitdiffstats
path: root/moon_manager/moon_manager/plugins/moon_openstack_plugin.py
diff options
context:
space:
mode:
Diffstat (limited to 'moon_manager/moon_manager/plugins/moon_openstack_plugin.py')
-rw-r--r--moon_manager/moon_manager/plugins/moon_openstack_plugin.py203
1 files changed, 203 insertions, 0 deletions
diff --git a/moon_manager/moon_manager/plugins/moon_openstack_plugin.py b/moon_manager/moon_manager/plugins/moon_openstack_plugin.py
new file mode 100644
index 00000000..a4b8a237
--- /dev/null
+++ b/moon_manager/moon_manager/plugins/moon_openstack_plugin.py
@@ -0,0 +1,203 @@
+# Software Name: MOON
+
+# Version: 5.4
+
+# SPDX-FileCopyrightText: Copyright (c) 2018-2020 Orange and its contributors
+# SPDX-License-Identifier: Apache-2.0
+
+# This software is distributed under the 'Apache License 2.0',
+# the text of which is available at 'http://www.apache.org/licenses/LICENSE-2.0.txt'
+# or see the "LICENSE" file for more details.
+
+"""
+Abstract plugin to request OpenStack infrastructure
+"""
+
+import json
+import logging
+import time
+import requests
+from moon_manager.pip_driver import InformationDriver
+from moon_manager.api.configuration import get_configuration
+from moon_utilities.exceptions import MoonError
+
+LOGGER = logging.getLogger("moon.manager.plugins.moon_openstack_plugin")
+
+PLUGIN_TYPE = "information"
+_ = str
+
+
+# Keystone exceptions
+
+
+class KeystoneError(MoonError):
+ description = _("There is an error connecting to Keystone.")
+ code = 400
+ title = 'Keystone error'
+ logger = "ERROR"
+
+
+class KeystoneProjectError(KeystoneError):
+ description = _("There is an error retrieving projects from the Keystone service.")
+ code = 400
+ title = 'Keystone project error'
+ logger = "ERROR"
+
+
+class KeystoneUserError(KeystoneError):
+ description = _("There is an error retrieving users from the Keystone service.")
+ code = 400
+ title = 'Keystone user error'
+ logger = "ERROR"
+
+
+class KeystoneUserConflict(KeystoneUserError):
+ description = _("A user with that name already exist.")
+ code = 400
+ title = 'Keystone user error'
+ logger = "ERROR"
+
+
+class OpenStackConnector(InformationDriver):
+
+ def __init__(self, driver_name, engine_name, conf):
+ self.driver_name = driver_name
+ self.engine_name = engine_name
+ self.opst_conf = get_configuration("information")
+
+ if not self.opst_conf:
+ raise Exception("Cannot find OpenStack configuration in configuration file")
+
+ self.__headers = {}
+ self.__user = conf.get("user", self.opst_conf['user'])
+ self.__password = conf.get("password", self.opst_conf['password'])
+ self.__domain = conf.get("domain", self.opst_conf['domain'])
+ self.__project = conf.get("project", self.opst_conf['project'])
+ self.__url = conf.get("url", self.opst_conf['url'])
+
+ def set_auth(self, **kwargs):
+ start_time = time.time()
+ user = kwargs.get("user", self.opst_conf['user'])
+ password = kwargs.get("password", self.opst_conf['password'])
+ domain = kwargs.get("domain", self.opst_conf['domain'])
+ project = kwargs.get("project", self.opst_conf['project'])
+ url = kwargs.get("url", self.opst_conf['url'])
+ headers = {
+ "Content-Type": "application/json"
+ }
+ data_auth = {
+ "auth": {
+ "identity": {
+ "methods": [
+ "password"
+ ],
+ "password": {
+ "user": {
+ "domain": {
+ "id": domain
+ },
+ "name": user,
+ "password": password
+ }
+ }
+ },
+ "scope": {
+ "project": {
+ "domain": {
+ "id": domain
+ },
+ "name": project
+ }
+ }
+ }
+ }
+
+ while True:
+ req = requests.post("{}/auth/tokens".format(url),
+ json=data_auth, headers=headers,
+ verify=kwargs.get("certificate", self.opst_conf['certificate']))
+
+ if req.status_code in (200, 201, 204):
+ self.__headers['X-Auth-Token'] = req.headers['X-Subject-Token']
+ return self.__headers
+ LOGGER.warning("Waiting for Keystone...")
+ if time.time() - start_time == 100:
+ LOGGER.error(req.text)
+ raise KeystoneError
+ time.sleep(5)
+
+ def unset_auth(self, **kwargs):
+ url = kwargs.get("url", self.opst_conf['url'])
+ self.__headers['X-Subject-Token'] = self.__headers['X-Auth-Token']
+ req = requests.delete("{}/auth/tokens".format(url), headers=self.__headers,
+ verify=kwargs.get("certificate", self.opst_conf['certificate']))
+ if req.status_code in (200, 201, 204):
+ return
+ LOGGER.error(req.text)
+ raise KeystoneError
+
+ def _get(self, endpoint, url=None, _exception=KeystoneError):
+ if not url:
+ if not self.__url:
+ LOGGER.warning("Cannot retrieve the URL for the OpenStack endpoint")
+ return {'users': []}
+ url = self.__url
+
+ req = requests.get("{}{}".format(url, endpoint),
+ headers=self.__headers)
+ if req.status_code not in (200, 201):
+ LOGGER.error(req.text)
+ raise _exception
+ data = req.json()
+ return data
+
+ def _post(self, endpoint, url=None, data=None, _exception=KeystoneError):
+ if not url:
+ if not self.__url:
+ LOGGER.warning("Cannot retrieve the URL for the OpenStack endpoint")
+ return {'users': []}
+ url = self.__url
+
+ req = requests.post("{}{}".format(url, endpoint),
+ data=json.dumps(data),
+ headers=self.__headers)
+ if req.status_code == 409:
+ LOGGER.warning(req.text)
+ raise KeystoneUserConflict
+ if req.status_code not in (200, 201):
+ LOGGER.error(req.text)
+ raise _exception
+ data = req.json()
+ return data
+
+ def create_project(self, **tenant_dict):
+ if "name" not in tenant_dict:
+ raise KeystoneProjectError("Cannot get the project name.")
+ _project = {
+ "project": {
+ "description": tenant_dict['description'],
+ "domain_id": tenant_dict['domain'],
+ "enabled": tenant_dict['enabled'],
+ "is_domain": tenant_dict['is_domain'],
+ "name": tenant_dict['name']
+ }
+ }
+ return self._post(endpoint="/projects/",
+ url=self.opst_conf["url"],
+ data=_project,
+ _exception=KeystoneProjectError)
+
+ def get_projects(self):
+ return self._get(endpoint="/projects/", url=self.opst_conf["url"], _exception=KeystoneProjectError)
+
+ def get_items(self, item_id=None, **kwargs):
+ raise NotImplementedError() # pragma: no cover
+
+ def add_item(self, item_id=None, **kwargs):
+ raise NotImplementedError() # pragma: no cover
+
+ def update_item(self, item_id, **kwargs):
+ raise NotImplementedError() # pragma: no cover
+
+ def delete_item(self, item_id, **kwargs):
+ raise NotImplementedError() # pragma: no cover