Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Newmaster #43

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file removed bin/__init__.py
Empty file.
59 changes: 4 additions & 55 deletions bin/quads.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,10 @@
import argparse
import os
import sys
import requests # EC528 addition
import json # EC528 addition
import importlib #EC528 addition
import logging
from subprocess import call
from subprocess import check_call

sys.path.append(os.path.dirname(__file__) + "/../")
from lib.hardware_services.hardware_service import set_hardware_service


logger = logging.getLogger('quads')
ch = logging.StreamHandler(sys.stdout)
ch.setLevel(logging.INFO)
Expand All @@ -44,7 +37,6 @@ def main(argv):
quads_config_file = os.path.dirname(__file__) + "/../conf/quads.yml"
quads_config = quads_load_config(quads_config_file)


if "data_dir" not in quads_config:
print "quads: Missing \"data_dir\" in " + quads_config_file
exit(1)
Expand All @@ -53,28 +45,14 @@ def main(argv):
print "quads: Missing \"install_dir\" in " + quads_config_file
exit(1)


if "hardware_service" not in quads_config:
print "quads: Missing \"hardware_service\" in " + quads_config_file
exit(1)

sys.path.append(quads_config["install_dir"] + "/lib")
sys.path.append(os.path.dirname(__file__) + "/../lib")
sys.path.append(os.path.dirname(__file__) + "/../lib/hardware_services/hardware_drivers/")
import libquads

defaultconfig = quads_config["data_dir"] + "/schedule.yaml"
defaultstatedir = quads_config["data_dir"] + "/state"
defaultmovecommand = "/bin/echo"

# EC528 addition - sets hardware service
defaulthardwareservice = quads_config["hardware_service"]



# added for EC528 HIL-QUADS integration project - not a good place for this variable - should be moved eventually
hil_url = 'http://127.0.0.1:5000'

parser = argparse.ArgumentParser(description='Query current cloud for a given host')
parser.add_argument('--host', dest='host', type=str, default=None, help='Specify the host to query')
parser.add_argument('--cloud-only', dest='cloudonly', type=str, default=None, help='Limit full report to hosts only in this cloud')
Expand Down Expand Up @@ -116,12 +94,6 @@ def main(argv):
parser.add_argument('--dry-run', dest='dryrun', action='store_true', default=None, help='Dont update state when used with --move-hosts')
parser.add_argument('--log-path', dest='logpath',type=str,default=None, help='Path to quads log file')

parser.add_argument('--hil-api-action', dest='hilapiaction', type=str, default=None, help='HIL API Action');
parser.add_argument('--hil-api-call', dest='hilapicall', type=str, default=None, help='HIL API Call');

parser.add_argument('--set-hardware-service', dest='hardwareservice', type=str, default=defaulthardwareservice, help='Set Hardware Serve');


args = parser.parse_args()

if args.logpath :
Expand Down Expand Up @@ -187,7 +159,7 @@ def main(argv):
# a cloud environment.

quads = libquads.Quads(args.config, args.statedir, args.movecommand, args.datearg,
args.syncstate, args.initialize, args.force, args.hardwareservice)
args.syncstate, args.initialize, args.force)

# should these be mutually exclusive?
if args.lshosts:
Expand All @@ -196,7 +168,6 @@ def main(argv):

if args.lsclouds:
quads.quads_list_clouds()
#quads.quads_rest_call('GET', hil_url, '/projects')
exit(0)

if args.lsowner:
Expand All @@ -220,18 +191,10 @@ def main(argv):
exit(1)

if args.rmhost:
# print "Detaching HIL node " + args.rmhost + " from project " + args.hostcloud
# quads.quads_rest_call('POST', hil_url, '/project/' + args.hostcloud + '/detach_node', json.dumps({'node': args.rmhost})) #EC528 addition)
# print "removing QUADS host " + args.rmhost + " from " + args.hostcloud + " in QUADS data"
quads.quads_remove_host(args.rmhost)
exit(0)

if args.rmcloud:
# print "Deleting network in HIL named " + args.rmcloud
# quads.quads_rest_call('DELETE', hil_url, '/network/' + args.rmcloud) #EC528 addition
#print "Deleting project in HIL named " + args.rmcloud
# quads.quads_rest_call('DELETE', hil_url, '/project/' + args.rmcloud) #EC528 addition
#print "Deleting " + args.rmcloud + " from QUADS data"
quads.quads_remove_cloud(args.rmcloud)
exit(0)

Expand All @@ -240,18 +203,10 @@ def main(argv):
exit(1)

if args.hostresource:
# print "attaching HIL node " + args.hostresource + " to project " + args.hostcloud
# quads.quads_rest_call('POST', hil_url, '/project/' + args.hostcloud + '/connect_node', json.dumps({'node': args.hostresource})) #EC528 addition
# print "defining QUADS host " + args.hostresource + " and adding it to " + args.hostcloud + " in QUADS data"
quads.quads_update_host(args.hostresource, args.hostcloud, args.force)
exit(0)

if args.cloudresource:
# print "creating project in HIL named " + args.cloudresource
# quads.quads_rest_call('PUT', hil_url, '/project/' + args.cloudresource) #EC528 addition
#print "adding network to HIL and attaching it to " + args.cloudresource
#quads.quads_rest_call('PUT', hil_url, '/network/' + args.cloudresource, json.dumps({"owner": args.cloudresource, "access": args.cloudresource, "net_id": ""})) #EC528 addition
print "adding " + args.cloudresource + " to quads data"
quads.quads_update_cloud(args.cloudresource, args.description, args.force, args.cloudowner, args.ccusers, args.cloudticket, args.qinq)
exit(0)

Expand Down Expand Up @@ -293,18 +248,12 @@ def main(argv):
exit(0)

if args.movehosts:
if args.datearg is not None and not args.dryrun:
print "--move-hosts and --date are mutually exclusive unless using --dry-run."
exit(1)
# if args.datearg is not None and not args.dryrun:
# print "--move-hosts and --date are mutually exclusive unless using --dry-run."
# exit(1)
quads.quads_move_hosts(args.movecommand, args.dryrun, args.statedir, args.datearg)
exit(0)

#added for EC528 HIL-QUADS Demo
#hardcoded to work on localhost port 5000, but can be reconfigured to work on another server
if args.hilapiaction is not None and args.hilapicall is not None:
quads.quads_rest_call(args.hilapiaction, hil_url, args.hilapicall)
exit(0)

# finally, this part is just reporting ...
quads.quads_print_result(args.host, args.cloudonly, args.datearg, args.summary, args.fullsummary, args.lsschedule)

Expand Down
7 changes: 0 additions & 7 deletions conf/quads.yml
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,6 @@ data_dir: /opt/quads/data
domain: example.com
log: /opt/quads/log/quads.log


# EC528 addition - demo 3
# set hardware service - currently 3 options: MockDriver, HilDriver, and JuniperDriver
hardware_service: MockDriver



# used for reporting
report_cc: [email protected], [email protected], [email protected], [email protected]

Expand Down
Empty file removed lib/__init__.py
Empty file.
File renamed without changes.
Empty file removed lib/hardware_services/__init__.py
Empty file.
Empty file.
File renamed without changes.
128 changes: 90 additions & 38 deletions lib/libquads.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
from datetime import datetime
import calendar
import time
import yaml
import argparse
import os
import requests
import logging
import sys
import importlib
import logging
from subprocess import call
from subprocess import check_call

from hardware_services.hardware_service import get_hardware_service, set_hardware_service
sys.path.append(os.path.dirname(__file__) + "/hardware_services.hardware_drivers/")


class Hosts(object):
def __init__(self, data):
"""
Expand Down Expand Up @@ -74,8 +75,7 @@ def __init__(self, data):


class Quads(object):

def __init__(self, config, statedir, movecommand, datearg, syncstate, initialize, force, hardwareservice):
def __init__(self, config, statedir, movecommand, datearg, syncstate, initialize, force):
"""
Initialize a quads object.
"""
Expand All @@ -86,7 +86,6 @@ def __init__(self, config, statedir, movecommand, datearg, syncstate, initialize
self.logger = logging.getLogger("quads.Quads")
self.logger.setLevel(logging.DEBUG)

#EC528 addition - dynamically import driver module and set hardware service
importlib.import_module(hardwareservice)
set_hardware_service(getattr(sys.modules[hardwareservice], hardwareservice)())
self.hardware_service = get_hardware_service()
Expand Down Expand Up @@ -211,12 +210,12 @@ def quads_sync_state(self):
# list the hosts
def quads_list_hosts(self):
# list just the hostnames
self.hardware_service.list_hosts(self)
self.quads.hosts.host_list()

# list the hosts
def quads_list_clouds(self):
# list just the hostnames
self.hardware_service.list_clouds(self)
self.quads.clouds.cloud_list()

# list the owners
def quads_list_owners(self, cloudonly):
Expand Down Expand Up @@ -285,41 +284,83 @@ def quads_list_qinq(self, cloudonly):
# remove a host
def quads_remove_host(self, rmhost):
# remove a specific host

kwargs = {'rmhost': rmhost}

self.hardware_service.remove_host(self, **kwargs)
if rmhost not in self.quads.hosts.data:
print rmhost + " not found"
return
del(self.quads.hosts.data[rmhost])
self.quads_write_data()

return

# remove a cloud
def quads_remove_cloud(self, rmcloud):
# remove a cloud (only if no hosts use it)

kwargs = {'rmcloud': rmcloud}

self.hardware_service.remove_cloud(self, **kwargs)
if rmcloud not in self.quads.clouds.data:
print rmcloud + " not found"
return
for h in self.quads.hosts.data:
if self.quads.hosts.data[h]["cloud"] == rmcloud:
print rmcloud + " is default for " + h
print "Change the default before deleting this cloud"
return
for s in self.quads.hosts.data[h]["schedule"]:
if self.quads.hosts.data[h]["schedule"][s]["cloud"] == rmcloud:
print rmcloud + " is used in a schedule for " + h
print "Delete schedule before deleting this cloud"
return
del(self.quads.clouds.data[rmcloud])
self.quads_write_data()

return

# update a host resource
def quads_update_host(self, hostresource, hostcloud, forceupdate):
# define or update a host resouce
if hostcloud is None:
self.logger.error("--default-cloud is required when using --define-host")
exit(1)
else:
if hostcloud not in self.quads.clouds.data:
print "Unknown cloud : %s" % hostcloud
print "Define it first using: --define-cloud"
exit(1)
if hostresource in self.quads.hosts.data and not forceupdate:
self.logger.error("Host \"%s\" already defined. Use --force to replace" % hostresource)
exit(1)

kwargs = {'hostresource': hostresource, 'hostcloud': hostcloud, 'forceupdate': forceupdate}

self.hardware_service.update_host(self, **kwargs)
if hostresource in self.quads.hosts.data:
self.quads.hosts.data[hostresource] = { "cloud": hostcloud, "interfaces": self.quads.hosts.data[hostresource]["interfaces"], "schedule": self.quads.hosts.data[hostresource]["schedule"] }
self.quads.history.data[hostresource][int(time.time())] = hostcloud
else:
self.quads.hosts.data[hostresource] = { "cloud": hostcloud, "interfaces": {}, "schedule": {}}
self.quads.history.data[hostresource] = {}
self.quads.history.data[hostresource][0] = hostcloud
self.quads_write_data()

return

# update a cloud resource
def quads_update_cloud(self, cloudresource, description, forceupdate, cloudowner, ccusers, cloudticket, qinq):
# define or update a cloud resource

kwargs = {'cloudresource': cloudresource, 'description': description, 'forceupdate': forceupdate,
'cloudowner': cloudowner, 'ccusers': ccusers, 'cloudticket': cloudticket, 'qinq': qinq}

self.hardware_service.update_cloud(self, **kwargs)
if description is None:
self.logger.error("--description is required when using --define-cloud")
exit(1)
else:
if cloudresource in self.quads.clouds.data and not forceupdate:
self.logger.error("Cloud \"%s\" already defined. Use --force to replace" % cloudresource)
exit(1)
if not cloudowner:
cloudowner = "nobody"
if not cloudticket:
cloudticket = "00000"
if not qinq:
qinq = "0"
if not ccusers:
ccusers = []
else:
ccusers = ccusers.split()
self.quads.clouds.data[cloudresource] = { "description": description, "networks": {}, "owner": cloudowner, "ccusers": ccusers, "ticket": cloudticket, "qinq": qinq}
self.quads_write_data()

return

Expand Down Expand Up @@ -499,12 +540,30 @@ def quads_mod_host_schedule(self, modschedule, schedstart, schedend, schedcloud,
# as needed move host(s) based on defined schedules
def quads_move_hosts(self, movecommand, dryrun, statedir, datearg):
# move a host

kwargs = {'movecommand': movecommand, 'dryrun': dryrun, 'statedir': statedir,
'datearg': datearg}

self.hardware_service.move_hosts(self, **kwargs)

for h in sorted(self.quads.hosts.data.iterkeys()):
default_cloud, current_cloud, current_override = self._quads_find_current(h, datearg)
if not os.path.isfile(statedir + "/" + h):
try:
stream = open(statedir + "/" + h, 'w')
stream.write(current_cloud + '\n')
stream.close()
except Exception, ex:
self.logger.error("There was a problem with your file %s" % ex)
else:
stream = open(statedir + "/" + h, 'r')
current_state = stream.readline().rstrip()
stream.close()
if current_state != current_cloud:
self.logger.info("Moving " + h + " from " + current_state + " to " + current_cloud)
if not dryrun:
try:
check_call([movecommand, h, current_state, current_cloud])
except Exception, ex:
self.logger.error("Move command failed: %s" % ex)
exit(1)
stream = open(statedir + "/" + h, 'w')
stream.write(current_cloud + '\n')
stream.close()
exit(0)

# generally the last thing that happens is reporting results
Expand Down Expand Up @@ -558,10 +617,3 @@ def quads_print_result(self, host, cloudonly, datearg, summaryreport, fullsummar
else:
print current_cloud

# add for EC528 HIL-QUADS integration project
def quads_rest_call(self, method, url, request, json_data=None):
r = requests.request(method, url + request, data=json_data)
if method == 'GET':
print r.text


File renamed without changes.