more generic approach for job types

This commit is contained in:
itsikkes 2016-05-29 14:32:06 +03:00
parent 82dc945a0c
commit b1d3bbcc0e
5 changed files with 104 additions and 32 deletions

View File

@ -160,18 +160,19 @@ function createNewJob() {
type: "object", type: "object",
title: "Job", title: "Job",
properties: { properties: {
vlan: { job: {
title: "Vlan", title: "Type",
type: "integer", $ref: "/jobcreate",
$ref: "/info?type=vlans" }
},
}, },
options: { options: {
"collapsed": true "collapsed": false
}, },
}, },
ajax: true, ajax: true,
disable_edit_json: false, disable_edit_json: false,
disable_collapse: true,
disable_properties: true,
}); });
} }

View File

@ -1,7 +1,7 @@
class NetControllerConnector(object): class NetControllerConnector(object):
def __init__(self): def __init__(self):
_properties = {} self._properties = {}
def _load_prop_dict(self, target, prop): def _load_prop_dict(self, target, prop):
for property in prop: for property in prop:
@ -36,3 +36,19 @@ class NetControllerConnector(object):
def disconnect(self): def disconnect(self):
return return
class NetControllerJob(object):
connector = NetControllerConnector
def __init__(self):
self._properties = {
# property: [value, enumerating_function]
}
def get_job_properties(self):
return self._properties
def set_job_properties(self, properties):
return {}
def run(self):
raise NotImplementedError()

View File

@ -1,4 +1,4 @@
from connectors import NetControllerConnector from connectors import NetControllerJob, NetControllerConnector
demo_state = { demo_state = {
501: ["Machine A", "Machine B"], 501: ["Machine A", "Machine B"],
@ -7,7 +7,6 @@ demo_state = {
514: ["Machine E", "Machine F"], 514: ["Machine E", "Machine F"],
} }
class DemoConnector(NetControllerConnector): class DemoConnector(NetControllerConnector):
def __init__(self): def __init__(self):
self._conn = None self._conn = None
@ -34,3 +33,11 @@ class DemoConnector(NetControllerConnector):
if (demo_state.has_key(vlanid)): if (demo_state.has_key(vlanid)):
return demo_state[vlanid] return demo_state[vlanid]
return [] return []
class DemoJob(NetControllerJob):
connector = DemoConnector
def __init__(self):
self._properties = {
"vlan": [0, "get_vlans_list"],
}

View File

@ -1,8 +1,7 @@
from connectors import NetControllerConnector from connectors import NetControllerJob, NetControllerConnector
from pyVmomi import vim from pyVmomi import vim
from pyVim.connect import SmartConnect, Disconnect from pyVim.connect import SmartConnect, Disconnect
class VCenterConnector(NetControllerConnector): class VCenterConnector(NetControllerConnector):
def __init__(self): def __init__(self):
self._service_instance = None self._service_instance = None
@ -21,6 +20,9 @@ class VCenterConnector(NetControllerConnector):
"resource_pool": "" "resource_pool": ""
} }
} }
self._job_properties = {
}
def connect(self): def connect(self):
self._service_instance = SmartConnect(host=self._properties["address"], self._service_instance = SmartConnect(host=self._properties["address"],
@ -124,3 +126,13 @@ class VCenterConnector(NetControllerConnector):
break break
return obj return obj
class VCenterJob(NetControllerJob):
connector = VCenterConnector
def __init__(self):
self._properties = {
"vlan": [0, "get_vlans_list"],
}

View File

@ -1,4 +1,5 @@
import os import os
import sys
from flask import Flask, request, abort, send_from_directory from flask import Flask, request, abort, send_from_directory
from flask.ext import restful from flask.ext import restful
from flask.ext.pymongo import PyMongo from flask.ext.pymongo import PyMongo
@ -7,8 +8,8 @@ import bson.json_util
import json import json
from datetime import datetime from datetime import datetime
import dateutil.parser import dateutil.parser
from connectors.vcenter import VCenterConnector from connectors.vcenter import VCenterJob, VCenterConnector
from connectors.demo import DemoConnector from connectors.demo import DemoJob, DemoConnector
MONGO_URL = os.environ.get('MONGO_URL') MONGO_URL = os.environ.get('MONGO_URL')
if not MONGO_URL: if not MONGO_URL:
@ -18,7 +19,7 @@ app = Flask(__name__)
app.config['MONGO_URI'] = MONGO_URL app.config['MONGO_URI'] = MONGO_URL
mongo = PyMongo(app) mongo = PyMongo(app)
available_connectors=[VCenterConnector, DemoConnector] available_jobs = [VCenterJob, DemoJob]
active_connectors = {} active_connectors = {}
@ -92,15 +93,49 @@ class Connector(restful.Resource):
{"$set": settings_json}, {"$set": settings_json},
upsert=True) upsert=True)
class Info(restful.Resource): class JobCreation(restful.Resource):
def get(self, **kw): def get(self, **kw):
type = request.args.get('type') jobtype = request.args.get('type')
if type == "vlans": if not jobtype:
res = []
update_connectors() update_connectors()
vlans = set() for con in available_jobs:
for con in active_connectors: if con.connector.__name__ in active_connectors:
vlans.update(active_connectors[con].get_vlans_list()) res.append({"title": con.__name__, "$ref": "/jobcreate?type=" + con.__name__})
return {"enum": list(vlans)} return {"oneOf": res}
job = None
for jobclass in available_jobs:
if jobclass.__name__ == jobtype:
job = jobclass()
if job and job.connector.__name__ in active_connectors.keys():
properties = dict()
job_prop = job.get_job_properties()
for prop in job_prop:
properties[prop] = dict({})
if type(job_prop[prop][0]) is int:
properties[prop]["type"] = "number"
elif type(job_prop[prop][0]) is bool:
properties[prop]["type"] = "boolean"
else:
properties[prop]["type"] = "string"
if job_prop[prop][1]:
properties[prop]["enum"] = list(active_connectors[job.connector.__name__].__getattribute__(job_prop[prop][1])())
res = dict({
"title": "%s Job" % jobtype,
"type": "object",
"options": {
"disable_collapse": True,
"disable_properties": True,
},
"properties": properties
})
return res
return {}
def normalize_obj(obj): def normalize_obj(obj):
@ -136,18 +171,19 @@ def refresh_connector_config(name):
def update_connectors(): def update_connectors():
for con in available_connectors: for con in available_jobs:
if con.__name__ not in active_connectors: connector_name = con.connector.__name__
active_connectors[con.__name__] = con() if connector_name not in active_connectors:
active_connectors[connector_name] = con.connector()
if not active_connectors[con.__name__ ].is_connected(): if not active_connectors[connector_name].is_connected():
refresh_connector_config(con.__name__) refresh_connector_config(connector_name)
try: try:
active_connectors[con.__name__].connect() active_connectors[connector_name].connect()
app.logger.info("Trying to activate connector: %s" % con.__name__) app.logger.info("Trying to activate connector: %s" % connector_name)
except Exception, e: except Exception, e:
active_connectors.pop(con.__name__) active_connectors.pop(connector_name)
app.logger.info("Error activating connector: %s, reason: %s" % (con.__name__, e)) app.logger.info("Error activating connector: %s, reason: %s" % (connector_name, e))
@ -162,7 +198,7 @@ api.representations = DEFAULT_REPRESENTATIONS
api.add_resource(Root, '/api') api.add_resource(Root, '/api')
api.add_resource(Job, '/job') api.add_resource(Job, '/job')
api.add_resource(Connector, '/connector') api.add_resource(Connector, '/connector')
api.add_resource(Info, '/info') api.add_resource(JobCreation, '/jobcreate')
if __name__ == '__main__': if __name__ == '__main__':
app.run(host='0.0.0.0', debug=True, ssl_context=('server.crt', 'server.key')) app.run(host='0.0.0.0', debug=True, ssl_context=('server.crt', 'server.key'))