diff --git a/monkey_business/cc/admin/ui/index.html b/monkey_business/cc/admin/ui/index.html index 5705f9776..f85c8885f 100644 --- a/monkey_business/cc/admin/ui/index.html +++ b/monkey_business/cc/admin/ui/index.html @@ -129,26 +129,19 @@
- - -
-
- +
diff --git a/monkey_business/cc/admin/ui/js/monkeysb-admin.js b/monkey_business/cc/admin/ui/js/monkeysb-admin.js index 8c154298a..abe33ad34 100644 --- a/monkey_business/cc/admin/ui/js/monkeysb-admin.js +++ b/monkey_business/cc/admin/ui/js/monkeysb-admin.js @@ -12,8 +12,8 @@ const ICONS_EXT = ".png"; var jobsTable = undefined; var logsTable = undefined; -var vcenterCfg = undefined; var jobCfg = undefined; +var conCfg = undefined; var selectedJob = undefined; JSONEditor.defaults.theme = 'bootstrap3'; @@ -41,73 +41,8 @@ function initAdmin() { showLog(selectedJob); } ); - vcenterCfg = new JSONEditor(document.getElementById('vcenter-config'),{ - schema: { - type: "object", - title: "vcenter", - properties: { - address: { - title: "Address", - type: "string", - }, - port: { - title: "Port", - type: "integer", - }, - username: { - title: "Username", - type: "string", - }, - password: { - title: "Password", - type: "string", - }, - monkey_template_name: { - title: "Monkey Template Name", - type: "string", - }, - monkey_vm_info: { - title: "Monkey Creation VM", - type: "object", - properties: { - name: { - title: "Deployment Name", - type: "string", - }, - vm_folder: { - title: "VM Folder (opt.)", - type: "string", - }, - resource_pool: { - title: "Resource Pool (opt.)", - type: "string", - }, - datacenter_name: { - title: "Datacenter (opt.)", - type: "string", - }, - cluster_name: { - title: "Cluster (opt.)", - type: "string", - }, - datastore_name: { - title: "Datastore (opt.)", - type: "string", - }, - } - } - }, - options: { - "collapsed": true - }, - }, - disable_edit_json: false, - disable_properties: true, - }); - setInterval(updateJobs, 5000); setInterval(showLog, 5000); - loadVcenterConfig(); updateJobs(); } @@ -140,20 +75,39 @@ function updateJobs() { } jobsTable.draw(); - //enableJobsSelect(); }); } -function loadVcenterConfig() { - $.getJSON('/connector?type=VCenterConnector', function(json) { - vcenterCfg.setValue(json); +function loadConnectorsConfig() { + elem = document.getElementById('connectors-config'); + elem.innerHTML = "" + conCfg = new JSONEditor(elem,{ + schema: { + type: "object", + title: "Connector", + properties: { + connector: { + title: "Type", + $ref: "/connector", + } + }, + options: { + "collapsed": false + }, + }, + ajax: true, + disable_edit_json: false, + disable_collapse: true, + disable_properties: true, + no_additional_properties: true + }); + conCfg.on('ready',function() { + document.getElementById("btnSaveConnectorConfig").style.visibility = "visible"; }); } -function updateVcenterConfig() { - var vc_config = vcenterCfg.getValue() - vc_config["type"] = "VCenterConnector"; - +function updateConnectorConfig() { + var con_config = conCfg.getValue() $.ajax({ headers : { 'Accept' : 'application/json', @@ -161,9 +115,12 @@ function updateVcenterConfig() { }, url : '/connector', type : 'POST', - data : JSON.stringify(vc_config), + data : JSON.stringify(con_config.connector), success : function(response, textStatus, jqXhr) { console.log("New vcenter config successfully updated!"); + document.getElementById("btnSaveConnectorConfig").style.visibility = "hidden"; + elem = document.getElementById('connectors-config'); + elem.innerHTML = "" }, error : function(jqXHR, textStatus, errorThrown) { // log the error to the console diff --git a/monkey_business/cc/connectors/__init__.py b/monkey_business/cc/connectors/__init__.py index a6ae03932..b282d014a 100644 --- a/monkey_business/cc/connectors/__init__.py +++ b/monkey_business/cc/connectors/__init__.py @@ -65,6 +65,8 @@ class NetControllerJob(object): if self._logger: self._logger.log(text) + # external API + def get_job_properties(self): return self._properties @@ -80,4 +82,10 @@ class NetControllerJob(object): raise NotImplementedError() def get_results(self): - return [] \ No newline at end of file + return [] + + def get_state(self): + return None + + def stop(self): + raise NotImplementedError() \ No newline at end of file diff --git a/monkey_business/cc/connectors/vcenter.py b/monkey_business/cc/connectors/vcenter.py index bdd9c062b..4ddbf3c2d 100644 --- a/monkey_business/cc/connectors/vcenter.py +++ b/monkey_business/cc/connectors/vcenter.py @@ -12,7 +12,6 @@ class VCenterConnector(NetControllerConnector): "password": "", "monkey_template_name": "", "monkey_vm_info": { - "name": "Monkey Test", "datacenter_name": "", "vm_folder": "", "datastore_name": "", diff --git a/monkey_business/cc/main.py b/monkey_business/cc/main.py index afe03a646..a38549155 100644 --- a/monkey_business/cc/main.py +++ b/monkey_business/cc/main.py @@ -63,15 +63,39 @@ class Job(restful.Resource): class Connector(restful.Resource): + def _build_prop_dict(self, properties, job_obj=None): + res = dict() + for prop in properties: + res[prop] = dict({}) + res[prop]["default"] = properties[prop] + if type(properties[prop]) is int: + res[prop]["type"] = "number" + elif type(properties[prop]) is bool: + res[prop]["type"] = "boolean" + elif type(properties[prop]) is dict: + res[prop]["type"] = "object" + res[prop]["properties"] = self._build_prop_dict(properties[prop], job_obj) + else: + res[prop]["type"] = "string" + + if job_obj: + enum = job_obj.get_property_function(prop) + if enum: + properties[prop]["enum"] = list( + active_connectors[job_obj.connector_type.__name__].__getattribute__(enum)()) + return res + def get(self, **kw): contype = request.args.get('type') # if no type given - return list of types if not contype: conlist = [] + checked_con = [] # used for easy checking for reoccurring connectors for jobclass in available_jobs: - if jobclass.connector_type.__name__ not in conlist: - conlist.append(jobclass.connector_type.__name__) + if jobclass.connector_type.__name__ not in checked_con: + checked_con.append(jobclass.connector_type.__name__) + conlist.append({"title": jobclass.connector_type.__name__, "$ref": "/connector?type=" + jobclass.connector_type.__name__}) return {"oneOf": conlist} con = get_connector_by_name(contype) @@ -80,14 +104,34 @@ class Connector(restful.Resource): properties = mongo.db.connector.find_one({"type": con.__class__.__name__}) if properties: con.load_properties(properties) - ret = con.get_properties() - ret["password"] = "" # for better security, don't expose password - return ret + con_prop = con.get_properties() + con_prop["password"] = "" # for better security, don't expose password + + properties = self._build_prop_dict(con_prop) + properties["type"] = { + "type": "enum", + "enum": [contype], + "options": {"hidden": True} + } + + res = dict({ + "title": "%s Connector" % contype, + "type": "object", + "options": { + "disable_collapse": True, + "disable_properties": True, + }, + "properties": properties + }) + return res def post(self, **kw): settings_json = json.loads(request.data) contype = settings_json.get("type") + if not contype: + return {} + # preserve password if empty given properties = mongo.db.connector.find_one({"type": contype}) if properties and (not settings_json.has_key("password") or not settings_json["password"]): @@ -97,6 +141,7 @@ class Connector(restful.Resource): {"$set": settings_json}, upsert=True) + class JobCreation(restful.Resource): def get(self, **kw): jobtype = request.args.get('type')