diff --git a/.env b/.env new file mode 100644 index 0000000..496197b --- /dev/null +++ b/.env @@ -0,0 +1,8 @@ +OS_USERNAME=admin +OS_PASSWORD= +OS_PROJECT_NAME=admin +OS_USER_DOMAIN_NAME=Default +OS_PROJECT_DOMAIN_NAME=Default +OS_AUTH_URL=http://10.10.110.251:5000/v3 +OS_IDENTITY_API_VERSION=3 +OS_INTERFACE=internal diff --git a/myOpenstackApp/OpenStackConnection.py b/myOpenstackApp/OpenStackConnection.py index 1328b22..5c706cd 100644 --- a/myOpenstackApp/OpenStackConnection.py +++ b/myOpenstackApp/OpenStackConnection.py @@ -1,3 +1,11 @@ +import requests +# import redis +import json +import os +from myOpenstackApp.logger import log + + +from myOpenstackApp import exceptions class OpenStackConnection_x: someProp=0 ks=False @@ -25,3 +33,93 @@ class OpenStackConnection_x: print(1) _self.ks.getCatalog() _self.nova.showNovaURL() + + + def make_request(_self, getPost, url, data, apiEndpoint, scopedProjectID=""): + log.debug("Making a request {} {} ".format(apiEndpoint,url)) + # Default the scope project to the value set in .env.example, allow the user to override if required(EG creating backups) + if scopedProjectID== "": + scopedProjectID=os.getenv("OS_PROJECT_ID") + else: + scopedProjectID=scopedProjectID + + str(url).replace(" ","%20") + + data_json = json.dumps(data) + + token = _self.getToken(os.getenv("OS_USERNAME"), os.getenv("OS_PASSWORD"), + os.getenv("OS_USER_DOMAIN_NAME"), os.getenv("OS_USER_DOMAIN_NAME"), + scopedProjectID) + # print (token) + headers = {'Content-type': 'application/json', 'X-Auth-Token': token} + + url = apiEndpoint + "/" + url + + if getPost=="GET": + response = requests.get(url, headers=headers) + elif getPost=="POST": + response = requests.post(url, data=data_json, headers=headers) + else: + raise ValueError("Unknown request type") + + if 200<= response.status_code <= 300 : + return response + else: + raise ValueError ("Error in response return code" + str(response.status_code) + str(response.content)) + + def getToken(_self,username, password, authDomain, scopeDomain, scopeProject): + + try: + return _self.lookupTokenFromRedis(username, authDomain, scopeDomain, scopeProject) + except exceptions.ItemNotFoundError: + + url = os.getenv("OS_AUTH_URL") + '/auth/tokens' + xdata = { + "auth": { + "scope": { + "project": { + "domain": { + "name": scopeDomain + }, + "id": scopeProject + } + }, + "identity": { + "password": { + "user": { + "domain": { + "name": authDomain + }, + "password": password, + "name": username + } + }, + "methods": [ + "password" + ] + } + } + } + + response = requests.post(url) + headers = {'Content-type': 'application/json'} + response = requests.post(url, headers=headers, + data=json.dumps(xdata), + verify=False, + timeout=4) + + if response.status_code == 201: + try: + _self.saveTokenToRedis( username, authDomain, scopeDomain, scopeProject, response.headers['X-Subject-Token']) + except exceptions.ItemNotSavedError: + log.warn("Error saving token to redis..meh") + return response.headers['X-Subject-Token'] + else: + raise ValueError("Error in token response to token request:"+response.text) + + def lookupTokenFromRedis(_self, username, authDomain, scopeDomain, scopeProject): + raise exceptions.ItemNotFoundError("OpenstackToken not found in redis") + + def saveTokenToRedis(_self, username, authDomain, scopeDomain, scopeProject,token): + raise exceptions.ItemNotSavedError("OpenstackToken not saved in redis") + diff --git a/myOpenstackApp/__pycache__/OpenStackConnection.cpython-310.pyc b/myOpenstackApp/__pycache__/OpenStackConnection.cpython-310.pyc index a8de70f..7af5cd0 100644 Binary files a/myOpenstackApp/__pycache__/OpenStackConnection.cpython-310.pyc and b/myOpenstackApp/__pycache__/OpenStackConnection.cpython-310.pyc differ diff --git a/myOpenstackApp/__pycache__/exceptions.cpython-310.pyc b/myOpenstackApp/__pycache__/exceptions.cpython-310.pyc new file mode 100644 index 0000000..8095b6b Binary files /dev/null and b/myOpenstackApp/__pycache__/exceptions.cpython-310.pyc differ diff --git a/myOpenstackApp/__pycache__/keystone.cpython-310.pyc b/myOpenstackApp/__pycache__/keystone.cpython-310.pyc index 6400607..d7c93bf 100644 Binary files a/myOpenstackApp/__pycache__/keystone.cpython-310.pyc and b/myOpenstackApp/__pycache__/keystone.cpython-310.pyc differ diff --git a/myOpenstackApp/__pycache__/logger.cpython-310.pyc b/myOpenstackApp/__pycache__/logger.cpython-310.pyc new file mode 100644 index 0000000..c908d3a Binary files /dev/null and b/myOpenstackApp/__pycache__/logger.cpython-310.pyc differ diff --git a/myOpenstackApp/__pycache__/settings.cpython-310.pyc b/myOpenstackApp/__pycache__/settings.cpython-310.pyc new file mode 100644 index 0000000..6af37b7 Binary files /dev/null and b/myOpenstackApp/__pycache__/settings.cpython-310.pyc differ diff --git a/myOpenstackApp/exceptions.py b/myOpenstackApp/exceptions.py new file mode 100644 index 0000000..5d8b692 --- /dev/null +++ b/myOpenstackApp/exceptions.py @@ -0,0 +1,10 @@ +class ItemNotFoundError(ValueError): + '''Used when looking up REDIS or SQL or any other database to indicate to the calling routine that the object + cant be found and to move along and try bother some other function + ''' +class ItemNotSavedError(ValueError): + '''Item cant be saved to Redis + ''' + +class DeadIPFound(ValueError): + ''''An ip has been saved to redis as being 'DEAD"''' diff --git a/myOpenstackApp/keystone.py b/myOpenstackApp/keystone.py index db54fcf..0e5b5a7 100644 --- a/myOpenstackApp/keystone.py +++ b/myOpenstackApp/keystone.py @@ -1,16 +1,78 @@ +import imp +import json +import os +from myOpenstackApp.logger import log +import myOpenstackApp.settings import myOpenstackApp.OpenStackConnection class myopenstack_keystone(): + def __init__(self, connection): + self.serviceData={} + self.catalogData={} + self.projectData={} + self.connection=connection + - def __init__(self,conn ) -> None: - self.conn=conn - def echo(_self): - print("Helllooo") + def getAllProjects(_self): + _self.projectData=_self.connection.make_request("GET", "projects", "", + os.getenv("OS_AUTH_URL")).json() + return _self.projectData + def getCatalog(_self): - catalog="Some shit, more shit" - _self.conn.catalogData=catalog - _self.conn.novaURL="http://nova" + catalogData=_self.connection.make_request("GET", "endpoints", "", + os.getenv("OS_AUTH_URL")).json() + + serviceData=_self.connection.make_request("GET", "services", "", + os.getenv("OS_AUTH_URL")).json() + # print(serviceData) + _self.serviceData=serviceData + _self.catalogData=catalogData + return catalogData + + + def getServicebyID(_self,id): + # print(_self.serviceData) + for _service in _self.serviceData['services']: + if str(_service['id']).lower()==str(id).lower(): + # print(_service) + return(_service) + + def getServicebyName(_self,name): + for _service in _self.serviceData['services']: + if str(_service['name']).lower()==str(name).lower(): + # print(_service) + return(_service) + + + def getEndpointByServiceIDAndInterface(_self,id,interface): + for _endpoint in _self.catalogData['endpoints']: + if str(_endpoint['service_id']).lower()==str(id).lower(): + if str(_endpoint['interface']).lower()==str(interface).lower(): + # print(_endpoint) + return(_endpoint) + + def getEndpointByNameIDAndInterface(_self,name,interface): + id=_self.getServicebyName(name)['id'] + for _endpoint in _self.catalogData['endpoints']: + if str(_endpoint['service_id']).lower()==str(id).lower(): + if str(_endpoint['interface']).lower()==str(interface).lower(): + # print(_endpoint) + return(_endpoint) + + def createProject(_self,name,description): + log.info("Creating a project") + data={ + "project": { + "description": description, + "enabled": True, + "is_domain": False, + "name": name + } + } + _self.newProjectData=_self.requestor.make_request("POST", "projects", data, + os.getenv("OS_AUTH_URL")).json() + return _self.newProjectData \ No newline at end of file diff --git a/myOpenstackApp/logger.py b/myOpenstackApp/logger.py new file mode 100644 index 0000000..b1420dc --- /dev/null +++ b/myOpenstackApp/logger.py @@ -0,0 +1,6 @@ +import os,logging +##LOGGING OPTIONS +LOG_LEVEL = os.getenv("LOG_LEVEL") or "DEBUG" +FORMAT = '%(asctime)s [%(levelname)s] %(message)s' +log = logging +log.basicConfig(format=FORMAT,level=LOG_LEVEL) \ No newline at end of file diff --git a/myOpenstackApp/settings.py b/myOpenstackApp/settings.py new file mode 100644 index 0000000..eff8b63 --- /dev/null +++ b/myOpenstackApp/settings.py @@ -0,0 +1,3 @@ +from dotenv import load_dotenv + +load_dotenv() \ No newline at end of file diff --git a/myOpenstackApp/test_keystone.py b/myOpenstackApp/test_keystone.py new file mode 100644 index 0000000..db54fcf --- /dev/null +++ b/myOpenstackApp/test_keystone.py @@ -0,0 +1,16 @@ +import myOpenstackApp.OpenStackConnection + + +class myopenstack_keystone(): + + def __init__(self,conn ) -> None: + self.conn=conn + + def echo(_self): + print("Helllooo") + + + def getCatalog(_self): + catalog="Some shit, more shit" + _self.conn.catalogData=catalog + _self.conn.novaURL="http://nova"