Compare commits

...

No commits in common. "2bbce47b28c209f52d73523d28e8613edec7c381" and "master" have entirely different histories.

20 changed files with 313 additions and 45 deletions

8
.env
View File

@ -1,8 +0,0 @@
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

13
.gitignore vendored Normal file
View File

@ -0,0 +1,13 @@
.*egg-info.*
build*
dist*
.*python_netflow_v9_softflowd.egg-info/
*.swp
*.swo
__pycache__
*.json
venv
.idea
.env*
.env
/lib/

14
example.env Normal file
View File

@ -0,0 +1,14 @@
OS_USERNAME=admin
OS_PASSWORD=
OS_PROJECT_NAME=admin
OS_PROJECT_ID=8f526efe5899415f8cede048c5594aa4
OS_USER_DOMAIN_NAME=Default
OS_PROJECT_DOMAIN_NAME=Default
OS_AUTH_URL=https://api.mycloud.com:5000/v3
OS_IDENTITY_API_VERSION=3
OS_INTERFACE=public
EXTERNAL_NETWORK_ID=3578d00b-e6f2-4a5d-b379-b79d4fb2d8d0
FLAVOR_ID=
IMAGE_ID=
REDIS_HOST=127.0.0.1

119
main.py
View File

@ -1,13 +1,124 @@
import os, sys import os, sys,time
sys.path.append(os.path.join(os.path.dirname(__file__), "lib")) sys.path.append(os.path.join(os.path.dirname(__file__), "lib"))
from myOpenstackApp.logger import log
import myOpenstackApp import myOpenstackApp
testProjectName="SmokeTest"
testProjectExists=False
testProject=""
testNetwork=""
testSubnet=""
timingText=""
cleanupResourcesOnCompletion=True
y=myOpenstackApp.OSC y=myOpenstackApp.OSC
y.initalise() y.initalise()
# y.ks.getCatalog() y.ks.getCatalog()
y.something() # print(y.something())
# print(y._keystone) # print(y._keystone)
log.info("Starting")
print("Starting") tic = time.perf_counter()
allProjects=y.ks.getAllProjects()
toc = time.perf_counter()
timingText +=(f"Queried keystone in {toc - tic:0.4f} seconds\n")
def sendFailureNotice(e,timingText):
log.error("JOB FAILED\n\n" + str(e))
log.error(timingText)
exit()
def cleanUp():
log.info("Cleaning up")
log.info("Deleting project")
y.ks.deleteProject(testProject['id'])
#Delete VM
#Delete router
#Delete Network
#Delete project
pass
try:
#Does my test project ID already exist?
for _project in allProjects['projects']:
if _project['name']==testProjectName:
testProject=_project
testProjectExists=True
if testProjectExists:
log.error("Test project already exists with ID " + 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("Test project created with ID " + testProject['id'])
toc = time.perf_counter()
timingText +=(f"Queried projects in {toc - tic:0.4f} seconds\n")
except Exception as e:
log.error("Error managing project" + str(e))
cleanUp()
sendFailureNotice(e,timingText)
try:
#Does my test network exist?
allNetworks=y.neutron.getAllNetworks(testProject['id'])
log.info(allNetworks)
#Does my test network ID already exist?
for _network in allNetworks['networks']:
if _network['name']==testProjectName+"_network":
testNetwork=_network
if testNetwork != "":
log.info("Test network already exists with ID " + testNetwork['id'])
else:
# Create test network
log.info("{} network does not exist, creating".format(testProjectName))
testNetwork=y.neutron.createNetwork(testProjectName+"_network",testProject['id'],"Test network description")['network']
log.info("Test network created with ID " + testNetwork['id'])
#Create subnet
log.info("Creating new subnet")
testSubnet=y.neutron.createSubnet(testProjectName + "_subnet",testNetwork['id'])
log.debug(testSubnet)
#Create a test router
log.info("Creating new router")
testRouter=y.neutron.createRouter(testProjectName + "_router",os.getenv("EXTERNAL_NETWORK_ID"))
log.debug(testRouter)
toc = time.perf_counter()
timingText +=(f"Queried neutron in {toc - tic:0.4f} seconds")
except Exception as e:
log.error("Error managing network" + str(e))
toc = time.perf_counter()
timingText +=(f"Neutron failed after {toc - tic:0.4f} seconds\n")
cleanUp()
sendFailureNotice(e,timingText)
#Create
#Project
#Network
#Subnet
#Router
#bind router to network
#Volume from image
#Vm from volume
if cleanupResourcesOnCompletion:
cleanUp()
toc = time.perf_counter()
log.info(f"Total runtime {toc - tic:0.4f} seconds")

View File

@ -10,9 +10,13 @@ class OpenStackConnection_x:
someProp=0 someProp=0
ks=False ks=False
nova=False nova=False
neutron=False
cinder=False
catalogData="" catalogData=""
novaURL="" novaURL=""
interface=""
token=""
""" """
It's important not to initalise any of the submodules during the init cycle becuase thic causes cirtucalr import loops It's important not to initalise any of the submodules during the init cycle becuase thic causes cirtucalr import loops
@ -22,23 +26,34 @@ class OpenStackConnection_x:
pass pass
def initalise(self) -> None: def initalise(self) -> None:
log.info("Initalising connection")
from myOpenstackApp.keystone import myopenstack_keystone from myOpenstackApp.keystone import myopenstack_keystone
from myOpenstackApp.nova import myopenstack_nova from myOpenstackApp.nova import myopenstack_nova
from myOpenstackApp.neutron import myopenstack_neutron
from myOpenstackApp.cinder import myopenstack_cinder
self.ks=myopenstack_keystone(self) self.ks=myopenstack_keystone(self)
self.nova=myopenstack_nova(self) self.nova=myopenstack_nova(self)
self.neutron=myopenstack_neutron(self)
self.cinder=myopenstack_cinder(self)
self.interface=os.getenv("OS_INTERFACE")
pass pass
def something(_self): def something(_self):
print(1) print(1)
_self.ks.getCatalog() _self.ks.getCatalog()
_self.nova.showNovaURL() print(_self.nova.getAllServers(os.getenv("OS_PROJECT_ID"),True))
def make_request(_self, getPost, url, data, apiEndpoint, scopedProjectID=""): def make_request(_self, getPost, url, data, apiEndpoint, scopedProjectID=""):
log.debug("Making a request {} {} ".format(apiEndpoint,url)) 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) # Default the scope project to the value set in .env.example, allow the user to override if required(EG creating backups)
if scopedProjectID== "": if scopedProjectID== "":
if len(str(os.getenv("OS_PROJECT_ID")))<8:
raise Exception("No OS_PROJECT_ID provided")
scopedProjectID=os.getenv("OS_PROJECT_ID") scopedProjectID=os.getenv("OS_PROJECT_ID")
else: else:
scopedProjectID=scopedProjectID scopedProjectID=scopedProjectID
@ -56,9 +71,11 @@ class OpenStackConnection_x:
url = apiEndpoint + "/" + url url = apiEndpoint + "/" + url
if getPost=="GET": if getPost=="GET":
response = requests.get(url, headers=headers) response = requests.get(url, headers=headers,timeout=15)
elif getPost=="POST": elif getPost=="POST":
response = requests.post(url, data=data_json, headers=headers) response = requests.post(url, data=data_json, headers=headers,timeout=15)
elif getPost=="DELETE":
response = requests.delete(url, headers=headers,timeout=15)
else: else:
raise ValueError("Unknown request type") raise ValueError("Unknown request type")
@ -70,7 +87,7 @@ class OpenStackConnection_x:
def getToken(_self,username, password, authDomain, scopeDomain, scopeProject): def getToken(_self,username, password, authDomain, scopeDomain, scopeProject):
try: try:
return _self.lookupTokenFromRedis(username, authDomain, scopeDomain, scopeProject) return _self.lookupToken(username, authDomain, scopeDomain, scopeProject)
except exceptions.ItemNotFoundError: except exceptions.ItemNotFoundError:
url = os.getenv("OS_AUTH_URL") + '/auth/tokens' url = os.getenv("OS_AUTH_URL") + '/auth/tokens'
@ -101,25 +118,28 @@ class OpenStackConnection_x:
} }
} }
response = requests.post(url) # response = requests.post(url)
headers = {'Content-type': 'application/json'} headers = {'Content-type': 'application/json'}
response = requests.post(url, headers=headers, response = requests.post(url, headers=headers,
data=json.dumps(xdata), data=json.dumps(xdata),
verify=False, verify=False,
timeout=4) timeout=15)
if response.status_code == 201: if response.status_code == 201:
try: try:
_self.saveTokenToRedis( username, authDomain, scopeDomain, scopeProject, response.headers['X-Subject-Token']) _self.saveToken( username, authDomain, scopeDomain, scopeProject, response.headers['X-Subject-Token'])
except exceptions.ItemNotSavedError: except exceptions.ItemNotSavedError:
log.warn("Error saving token to redis..meh") log.warn("Error saving token to redis..meh")
return response.headers['X-Subject-Token'] return response.headers['X-Subject-Token']
else: else:
raise ValueError("Error in token response to token request:"+response.text) raise ValueError("Error in token response to token request:"+response.text)
def lookupTokenFromRedis(_self, username, authDomain, scopeDomain, scopeProject): def lookupToken(_self, username, authDomain, scopeDomain, scopeProject):
if _self.token!="":
return _self.token
raise exceptions.ItemNotFoundError("OpenstackToken not found in redis") raise exceptions.ItemNotFoundError("OpenstackToken not found in redis")
def saveTokenToRedis(_self, username, authDomain, scopeDomain, scopeProject,token): def saveToken(_self, username, authDomain, scopeDomain, scopeProject,token):
raise exceptions.ItemNotSavedError("OpenstackToken not saved in redis") _self.token=token
#raise exceptions.ItemNotSavedError("OpenstackToken not saved in redis")

29
myOpenstackApp/cinder.py Normal file
View File

@ -0,0 +1,29 @@
import imp
import json
import myOpenstackApp.OpenStackConnection
class myopenstack_cinder():
def __init__(self,conn: myOpenstackApp.OpenStackConnection.OpenStackConnection_x ) -> None:
self.conn=conn
def getAllVolumes(_self, projectID):
result_Data=_self.conn.make_request("GET", "v2.0/volumes?project_id="+projectID, "",
_self.conn.ks.getEndpointByNameAndInterface("cinder",_self.conn.interface)["url"]).json()
return result_Data
def createVolume(_self,name,network_id):
data={
"router": {
"name": name,
"external_gateway_info": {
"network_id": network_id,
"enable_snat": True,
},
"admin_state_up": True
}
}
result_Data=_self.conn.make_request("POST", "v2.0/routers", data,
_self.conn.ks.getEndpointByNameAndInterface("cinder",_self.conn.interface)["url"]).json()
return result_Data

View File

@ -7,11 +7,11 @@ import myOpenstackApp.OpenStackConnection
class myopenstack_keystone(): class myopenstack_keystone():
def __init__(self, connection): def __init__(self,conn: myOpenstackApp.OpenStackConnection.OpenStackConnection_x ) -> None:
self.serviceData={} self.serviceData={}
self.catalogData={} self.catalogData={}
self.projectData={} self.projectData={}
self.connection=connection self.connection=conn
@ -55,7 +55,7 @@ class myopenstack_keystone():
# print(_endpoint) # print(_endpoint)
return(_endpoint) return(_endpoint)
def getEndpointByNameIDAndInterface(_self,name,interface): def getEndpointByNameAndInterface(_self,name,interface):
id=_self.getServicebyName(name)['id'] id=_self.getServicebyName(name)['id']
for _endpoint in _self.catalogData['endpoints']: for _endpoint in _self.catalogData['endpoints']:
if str(_endpoint['service_id']).lower()==str(id).lower(): if str(_endpoint['service_id']).lower()==str(id).lower():
@ -73,6 +73,14 @@ class myopenstack_keystone():
"name": name "name": name
} }
} }
_self.newProjectData=_self.requestor.make_request("POST", "projects", data,
_self.newProjectData=_self.connection.make_request("POST", "projects", data,
os.getenv("OS_AUTH_URL")).json() os.getenv("OS_AUTH_URL")).json()
return _self.newProjectData 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

62
myOpenstackApp/neutron.py Normal file
View File

@ -0,0 +1,62 @@
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", "v2.0/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", "v2.0/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
}
}
result_Data=_self.conn.make_request("POST", "v2.0/networks", data,
_self.conn.ks.getEndpointByNameAndInterface("neutron",_self.conn.interface)["url"]).json()
return result_Data
def createSubnet(_self,name,network_id):
data={
"subnet": {
"name": name,
"network_id": network_id,
"ip_version": 4,
"cidr": "192.168.199.0/24"
}
}
result_Data=_self.conn.make_request("POST", "v2.0/subnets", data,
_self.conn.ks.getEndpointByNameAndInterface("neutron",_self.conn.interface)["url"]).json()
return result_Data
def createRouter(_self,name,network_id):
data={
"router": {
"name": name,
"external_gateway_info": {
"network_id": network_id,
"enable_snat": True,
},
"admin_state_up": True
}
}
result_Data=_self.conn.make_request("POST", "v2.0/routers", data,
_self.conn.ks.getEndpointByNameAndInterface("neutron",_self.conn.interface)["url"]).json()
return result_Data

View File

@ -13,5 +13,22 @@ class myopenstack_nova():
_self.myOpenstackObject.keystone.echo() _self.myOpenstackObject.keystone.echo()
def showNovaURL(_self): def showNovaURL(_self):
print(_self.conn.novaURL) return _self.conn.ks.getEndpointByNameAndInterface("nova",_self.conn.interface)["url"]
_self.conn
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

@ -1,16 +0,0 @@
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"

0
readme.md Normal file
View File

2
requirements.txt Normal file
View File

@ -0,0 +1,2 @@
python-dotenv==0.21.0
requests==2.28.1

16
test.py Normal file
View File

@ -0,0 +1,16 @@
import time
timingText=""
tic = time.perf_counter()
import requests
toc = time.perf_counter()
timingText +=(f"Queried projects in {toc - tic:0.4f} seconds\n")
x=requests.get("http://google.com")
toc = time.perf_counter()
time.sleep(1)
timingText +=(f"Queried projects in {toc - tic:0.4f} seconds\n")
toc = time.perf_counter()
timingText +=(f"Queried projects in {toc - tic:0.4f} seconds\n")
print(timingText)