From 2bbce47b28c209f52d73523d28e8613edec7c381 Mon Sep 17 00:00:00 2001 From: Cory Hawkvelt Date: Mon, 7 Nov 2022 14:06:36 +1030 Subject: [PATCH] Ported some of the old code --- .env | 8 ++ myOpenstackApp/OpenStackConnection.py | 98 ++++++++++++++++++ .../OpenStackConnection.cpython-310.pyc | Bin 1088 -> 3455 bytes .../__pycache__/exceptions.cpython-310.pyc | Bin 0 -> 846 bytes .../__pycache__/keystone.cpython-310.pyc | Bin 924 -> 2763 bytes .../__pycache__/logger.cpython-310.pyc | Bin 0 -> 345 bytes .../__pycache__/settings.cpython-310.pyc | Bin 0 -> 207 bytes myOpenstackApp/exceptions.py | 10 ++ myOpenstackApp/keystone.py | 76 ++++++++++++-- myOpenstackApp/logger.py | 6 ++ myOpenstackApp/settings.py | 3 + myOpenstackApp/test_keystone.py | 16 +++ 12 files changed, 210 insertions(+), 7 deletions(-) create mode 100644 .env create mode 100644 myOpenstackApp/__pycache__/exceptions.cpython-310.pyc create mode 100644 myOpenstackApp/__pycache__/logger.cpython-310.pyc create mode 100644 myOpenstackApp/__pycache__/settings.cpython-310.pyc create mode 100644 myOpenstackApp/exceptions.py create mode 100644 myOpenstackApp/logger.py create mode 100644 myOpenstackApp/settings.py create mode 100644 myOpenstackApp/test_keystone.py 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 a8de70ff3e24a2a2b2b27c4d14bceb41cf163bce..7af5cd07fb1ea326a060609e55dfd56e5db3a4a9 100644 GIT binary patch literal 3455 zcmZ`*&37Y55ufh)&}byv@>dLxO;F$wP>AiY?{OgTAZG0io5ZrQ>}(K+VWOV3Wl1wi z&uDEa(gp8z|AReP$NVR7=hWAnd=3xZbAaVnJ(6QPUfEM!T~*y(U0uKGj%Q{(1HUha zM~#C8!}y9i*MBBD@8e5;4#Ykti?T%A-nDK!jEMY%0 zgnh>AIl*d1#ks&dMzz9}*^Up_E;v`@!R3V~3eSwXCzeG~%sgZDf|wO^kQ7Bp%%hzV3t|!NtgzwQ zYifC?8%DJ>XtW;0Q4}`FEB{n7to~3L%8_B(lTo!ng6WTV`X1m*ED&K}E>`^#L|IAL zej;;_YI6C}`cd2o*Bi0yuW!aDQ9BMqg02YHyZ!Vij<&(J*E@Z3Bq2vOy503Vyjtt_ zmFxS>sG0iyGA+$PEH-%K4rBjxZEAYMbqX&H)2_b@MlhVC(P1Nob7VM2-Z4j<8ACQS z&hYuxkWV;UZ_}#k;9#dqoqjy^*>8pYB#omG^3rvA6h93rj#|07zqP5kEWih~cuPxz zWRWzyl_*QkVM-SQZLd||hFIpwGEadC+RY^V9=Zvoc###E$32D^{qXJ>U5&XBBs$xx zAeGTc5t=guXlNX>b3Vr5gEP-9;&f1W^@0XfY-M+4GfL$gddfQt(+2^ZiVtOp1cl@% zKB;1J2YVkQP_}TBm>=ekXD!1tT1>XY0%&`fui*e-u?UZ$J!30|=H`f_QI)0Y zU}ZaKQ80tD3_tIMNm~A5ME}x8P}Iy$&EMVI`EcvOzW-?Rl9dPMPwu~~3J@REw)UzU z+grM`yHTq>-r3t!ixZ8%xwF0TsOpo&Whv-(+s#Hm)nolQiK7a?ETW*KVU(_>{cboY ze!9BROOICf<5n15vUO#Cu(gjI$Q^}&2qm(7cc->r;mQ)o82KiA8!R0}tq3LK%5j?M z;%`tj-$A+!Uf+^3mgOcHBwbX~5Db;8GL@G~Nm3FkTZEtW4wdsHmYpC~JWiB@#0;aS z%1lzJax(0;gGQ(CS=O$#!0HYPl9$Y)axUw(;)37J}s(p zjcnHyPrgR0=P+iMMwmU>mOmy@A?P-@BGHWj6g8JLP(;M8jE_-#A8o2U?cdK_Nhw%5 z7UV^?#oM?qc7j&uPkej}^CxeEEHIZBnZ--o<4e56IJ5reSw-%GcNuAyxW)L(d*vHOK=NR4`3I%N|>gaT{1h%8q%z&yb)k4u}Ed%Pe#N}jH$JQe$7bd z#1bT>3|1#bWx1+hv2n2f2OrgJP+Sj?-s}3rkj&Ikxo&oBG1e2|cI$ zDdh5JMAnGVeJp=Y1T2NlAG3lK)s9y3csNqe`)>8`nUDc`+*BIx{jv*hOxFOf4&Ee~>-Uw8W;u$}@)J6WtbXE{ka09#ehgBvb@`Hi zB*7k$8j*b>xAy-LWT*JPrUUTU;O)EX$z6$Yqpr~9J@sFHg3hbFri}Qm*A)GV^J=eu z1^sQ;w;}t2l!Y1@faUvrL delta 424 zcmZvWzfQw25XNoif0`6p$WUMc2`N)oRG~5y!2nbO#F7P7acHBajbs;C*xDUcehDOA zf{6!U^adMG0e3AD16cBR=ezrUzORiJw_1jwPvE?@1}QP-)vZPyUdMzJPG@kZEFqj- zlGsS+wFYg^pSE`bZgXd5CN2-S%RR_E?(@owBtExbG}Mu*IT8CLYL_0^7665%hBTq8 z>XklFraJ6|dg_riTKKtUL#fSidDn{#VdJ!if-SK$W9EQpFCXWVUXjaeO?|NGQHVvq zpG`VFD3^Uv#X?06%KI+xt}aevs;z686*qrSvK(cTK|bzps%N9=$4r=D?#2~$9yHI8 z{6kBZ>_Z6J!8HLZT!VKPvfck+sn) I8A#pu2AWe@`v3p{ diff --git a/myOpenstackApp/__pycache__/exceptions.cpython-310.pyc b/myOpenstackApp/__pycache__/exceptions.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8095b6b90f2231f76b313c21c8bae82f1b24e6a0 GIT binary patch literal 846 zcmah{!EO^V5cOs^ZAe=wNPNJEOVtD23rBWHo6GYz7$m>fN> zgVm;=w>9R+*2k@pp|mE}nO|n>0p~{4n)CIL^V+JmB72wf(^gd1k!{YEm7HHPH^8Ap z_3L?FVA)(+*X0v?ZYnF3N2qk(bfK{3HJVjkcW)YPd=T-6Hohxy4_tpv);!Iz!0B9>WbMX|QnH*_V`pv((6qEn(-&ps^w}Yxr20gZj z{>xxzqJ^5hjc?%MaDQx|Y@iSxmx7PrroE%~5Z$!X{mFDZc{snD$u1Izlp+&C^Mh`LCgBifOk2~eQwvYzFOD2M}#Bz8zT5?*7XJ5A#L|B zn2U7U)HwZQKSX2tVqk2*qaT8h1ebv&s9g*uM42;2ZABhSbQ#S921Whao%Q+moz_$eae zg4e~Qc8qiH&aUx`khLLZ;n7a8`DFKg@Z{HrZO;a4nuFe<43vESLh978L>q5krZRqM z_%ofv%7X=g8E#OxzjnD(9`^=PeP&}%+hZ;ej2c5@!^m60Jr zUS0@&3BTS2V+#J&V+R0t=D>f;`kblMut{oeWlkkEyrVvbxlKdo*and>b>OU2d%aLX zYLJEsk3@A9M4RVmV6N145T+iKG@k`#6@a-@d;+&eMW7G1H)HXjoc~*x!G6mvfXagP zJAZ%l{XDQfFk1ya-1h{&r(k5{gk;RZ>v{^2%9`lrCT;zZ`z-5*>02pY% z3fN7hpCm&)tr)z#yV(6$L^Bn07{~ulRsj(KoE(xHV5GJtoKh(HaPVPW&Zuzz;1RWuVx90rEpt+S z;tJnZ49`}K8US8{!?E5uTG~>wmqzjaN^hm88>Ut$yLYj)3aLXC4Y6pNnv8o-`x05H z1Cb1RQLI*ACx$G@l`dJ0^Qy1x zECOE7=3z0!jmu)-ZRltJ6&jQ=M)RA$=i{b7RhL%J%t2+MPJ021IG#8`U>ZR%NW_ai z>dhc{{-W2AnjftIbFKJlsV`!&A_58O@P z`rCEmM1x^og0Lc)OV!_wHTc8Xmnz5k@{CW*6mzOgtLiX-!1TY%8X7zJE4DTHGqTH{ ZwQuA9l!Ngz{-0Qm+s#v~aXwvg{sjWclYIaH literal 924 zcmZuvPm9w)6rY)-Z8mL1WDhEciw7Yf%~eEXr3-q{2o^8B3?Vaa;wCe3GF4L6)Aq~w z8T=-5_2gIZ$jw$Oo@d6W0=_xt7P=`N1C-&Lto(ZEy4xNdE()q60@xN1LavAnM9cnfD%w=Uqk zP=)0j>oo`?r0Yk=z|Xdk8K}HlXz##J;9)`G8%lflEOEhGS(c^N8i)*PQz(lD@2FtU zj))n7<$Rgt`UI>F$AqpQ9L0fA2N(_nybt+;{-7x07s9Dv-OV~Vy<~m50L9Llys*#C zDs6gmJmT8DlL1D2_V*>;^rqTe)l!<+>^tpnBj;la9rmwZ8EckR_@MWOqY7BlM7z11Alf$o diff --git a/myOpenstackApp/__pycache__/logger.cpython-310.pyc b/myOpenstackApp/__pycache__/logger.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c908d3aebc7dfd6f395bb27c7b46a7f348ed6476 GIT binary patch literal 345 zcmYk2J5Iwu5QcZxkMK%_I6<0-xWOe9C?X^wO+qAIg%LuFcj6epkf>vMw-W``DaEN-E3|Vw8PaR{>1!M!+&!TPSDK}20;XsB>KxVqCno5VDB_< z2`6%d8@WIu54=YoTyTW<$|z1;lEDAQX>x8iC$sVWWOOr{SZ_Ewy&k{pce>ofWtu@? z+P9sqge6GDYrJcBx)~V56NG?Sf3Ay+m)2Wrf`(<<*oM?elB&e|36!9g1;azuKbu`l z`&ZV%uHAm%CXEML&C}$A6gwzbho4@!&>4iWE~;>-S4wIw45ENAugZm1Q!HheRkIwF lDS74wJQs`blB!aD4*x5+PE=JrR*;QGv^E6&5t%Z06D`&Ow!MqQ{ zdnU_LAUv;iH70$;@Q;K-LFYz995_l)xJ3kkH$dRY2J+5}evo53kf!82ZoJUvRi3oH zpKapE9hxr5m)-@djS{RfO<)Ui(Xr 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"