Fresh repo

This commit is contained in:
Cory Hawkvelt 2022-11-20 21:27:48 +10:30
commit ca6af4f849
10 changed files with 388 additions and 0 deletions

56
main.py Normal file
View File

@ -0,0 +1,56 @@
import os, sys
sys.path.append(os.path.join(os.path.dirname(__file__), "lib"))
from myOpenstackApp.logger import log
import myOpenstackApp
testProjectName="SmokeTest"
testProjectExists=False
testProject=""
cleanupResourcesOnCompletion=True
y=myOpenstackApp.OSC
y.initalise()
# y.ks.getCatalog()
# print(y.something())
# print(y._keystone)
log.info("Starting")
allProjects=y.ks.getAllProjects()
#Does my test project ID already exist?
for _project in allProjects['projects']:
if _project['name']==testProjectName:
testProject=_project
testProjectExists=True
if testProjectExists:
log.error("Project already exists")
log.info(testProject['id'])
else:
# Create test project
log.info("{} project does not exist, creating".format(testProjectName))
testProject=y.ks.createProject(testProjectName,"Description goes here")['project']
log.info(testProject['id'])
#Does my test network exist?
allNetworks=y.neutron.getAllNetworks(testProject['id'])
log.info(allNetworks)
def cleanUp():
log.info("Cleaning up")
log.info("Deleting project")
y.ks.deleteProject(testProject['id'])
#Delete VM
#Delete router
#Delete Network
#Delete project
pass
if cleanupResourcesOnCompletion:
cleanUp()

View File

@ -0,0 +1,141 @@
import requests
# import redis
import json
import os
from myOpenstackApp.logger import log
from myOpenstackApp import exceptions
class OpenStackConnection_x:
someProp=0
ks=False
nova=False
neutron=False
catalogData=""
novaURL=""
interface=""
token=""
"""
It's important not to initalise any of the submodules during the init cycle becuase thic causes cirtucalr import loops
The initalise function exists for this reas and should be caled by the client application using this module
"""
def __init__(self) -> None:
pass
def initalise(self) -> None:
log.info("Initalising connection")
from myOpenstackApp.keystone import myopenstack_keystone
from myOpenstackApp.nova import myopenstack_nova
from myOpenstackApp.neutron import myopenstack_neutron
self.ks=myopenstack_keystone(self)
self.nova=myopenstack_nova(self)
self.neutron=myopenstack_neutron(self)
self.interface=os.getenv("OS_INTERFACE")
pass
def something(_self):
print(1)
_self.ks.getCatalog()
print(_self.nova.getAllServers(os.getenv("OS_PROJECT_ID"),True))
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== "":
if len(str(os.getenv("OS_PROJECT_ID")))<8:
raise Exception("No OS_PROJECT_ID provided")
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)
elif getPost=="DELETE":
response = requests.delete(url, 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.lookupToken(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.saveToken( 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 lookupToken(_self, username, authDomain, scopeDomain, scopeProject):
if _self.token!="":
return _self.token
raise exceptions.ItemNotFoundError("OpenstackToken not found in redis")
def saveToken(_self, username, authDomain, scopeDomain, scopeProject,token):
_self.token=token
#raise exceptions.ItemNotSavedError("OpenstackToken not saved in redis")

View File

@ -0,0 +1,3 @@
from myOpenstackApp import OpenStackConnection
OSC=OpenStackConnection.OpenStackConnection_x()

View File

@ -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"'''

View File

@ -0,0 +1,86 @@
import imp
import json
import os
from myOpenstackApp.logger import log
import myOpenstackApp.settings
import myOpenstackApp.OpenStackConnection
class myopenstack_keystone():
def __init__(self,conn: myOpenstackApp.OpenStackConnection.OpenStackConnection_x ) -> None:
self.serviceData={}
self.catalogData={}
self.projectData={}
self.connection=conn
def getAllProjects(_self):
_self.projectData=_self.connection.make_request("GET", "projects", "",
os.getenv("OS_AUTH_URL")).json()
return _self.projectData
def getCatalog(_self):
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 getEndpointByNameAndInterface(_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.connection.make_request("POST", "projects", data,
os.getenv("OS_AUTH_URL")).json()
return _self.newProjectData
def deleteProject(_self,id):
log.info("Deleting a project")
_self.newProjectData=_self.connection.make_request("DELETE", "projects/"+id, "",
os.getenv("OS_AUTH_URL"))
return _self.newProjectData

6
myOpenstackApp/logger.py Normal file
View File

@ -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)

33
myOpenstackApp/neutron.py Normal file
View File

@ -0,0 +1,33 @@
import imp
import json
import myOpenstackApp.OpenStackConnection
class myopenstack_neutron():
def __init__(self,conn: myOpenstackApp.OpenStackConnection.OpenStackConnection_x ) -> None:
self.conn=conn
def getAllNetworks(_self, projectID):
result_Data=_self.conn.make_request("GET", "networks?project_id="+projectID, "",
_self.conn.ks.getEndpointByNameAndInterface("neutron",_self.conn.interface)["url"]).json()
return result_Data
def listAllFloatingIPsByProject(_self,projectID):
result_Data=_self.conn.make_request("GET", "floatingips?project_id="+projectID, "",
_self.conn.ks.getEndpointByNameAndInterface("neutron",_self.conn.interface)["url"]).json()
return result_Data
def ipInSubnet(_self,network,netmask,ip):
#Network, netmask and ip must be supplied in integer form
return (ip & netmask) == network
def createNetwork(_self,name,project_id,description=""):
data={
"network": {
"name": name,
"admin_state_up": true,
"tenant_id": project_id,
"description": description
}
}
newNetwork=_self.requestor.make_request("POST", "projects", data, )
return newNetwork

34
myOpenstackApp/nova.py Normal file
View File

@ -0,0 +1,34 @@
import myOpenstackApp.OpenStackConnection
class myopenstack_nova():
def __init__(self,conn: myOpenstackApp.OpenStackConnection.OpenStackConnection_x ) -> None:
self.conn=conn
def addNewVM(_self,Name, flavor):
return(Name)
def getKeystone(_self):
_self.myOpenstackObject.keystone.echo()
def showNovaURL(_self):
return _self.conn.ks.getEndpointByNameAndInterface("nova",_self.conn.interface)["url"]
def getAllServers(_self,projectID,all_tenants):
queryString=""
if all_tenants:
queryString="/servers/detail?all_tenants=True"
else:
queryString="/servers/detail?project_id="+projectID,
return _self.conn.make_request("GET", queryString,"",_self.conn.ks.getEndpointByNameAndInterface("nova",_self.conn.interface)["url"] ).json()
def getAllFlavors(_self):
return ng_openstack.openstackRequest.openstackRequest("GET", "/flavors/detail",
"", "http://172.25.110.147:8774/v2.1").json()

View File

@ -0,0 +1,3 @@
from dotenv import load_dotenv
load_dotenv()

View File

@ -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"