def run_testConnection(): if request.method == 'POST': jsonData = request.get_json() ccp = CCP("https://" + jsonData['ipAddress'],jsonData['username'],jsonData['password']) # vip pools UUID still requires the v2 API so you need to login for both the v2 and v3 API until the vip pools has been moved to v3 loginV2 = ccp.loginV2() loginV3 = ccp.loginV3() if not loginV2 and not loginV3: socketio.emit('consoleLog', {'loggingType': 'ERROR','loggingMessage': config.ERROR_CCP_LOGIN }) return json.dumps({'success':False}), 401, {'ContentType':'application/json'} else: session['ccpURL'] = "https://" + jsonData['ipAddress'] session['ccpToken'] = loginV2.cookies.get_dict() session['sessionUUID'] = uuid.UUID(bytes=secrets.token_bytes(16)) session['x-auth-token'] = loginV3 socketio.emit('consoleLog', {'loggingType': 'INFO','loggingMessage': config.INFO_CCP_LOGIN }) return jsonify(dict(redirectURL='/ccpClusterCreation')) return render_template('ccpLogin.html')
def run_vsphereProviders(): if request.method == 'GET': if "ccpToken" in session and "x-auth-token" in session: ccp = CCP(session['ccpURL'],"","",session['ccpToken'],session['x-auth-token']) response = ccp.getProviderClientConfigs() if response: socketio.emit('consoleLog', {'loggingType': 'INFO','loggingMessage': config.INFO_VSPHERE_PROVIDERS }) return jsonify(response) else: return config.ERROR_VSPHERE_PROVIDERS, 400
def run_vipPools(): if request.method == 'GET': if "ccpToken" in session and "x-auth-token" in session: ccp = CCP(session['ccpURL'],"","",session['ccpToken'],session['x-auth-token']) jsonData = request.args.to_dict() response = ccp.getVIPPools() if response: socketio.emit('consoleLog', {'loggingType': 'INFO','loggingMessage': config.INFO_VIP_POOLS }) return jsonify(response) else: return jsonify("[]")
def checkClusterAlreadyExists(): if request.method == 'GET': if "ccpToken" in session and "x-auth-token" in session: ccp = CCP(session['ccpURL'],"","",session['ccpToken'],session['x-auth-token']) jsonData = request.args.to_dict() clusterName = jsonData["clusterName"] if not ccp.checkClusterAlreadyExists(clusterName): return json.dumps({'success':True}), 200, {'ContentType':'application/json'} else: return json.dumps({'success':False}), 400, {'ContentType':'application/json'}
def run_vsphereVMs(): if request.method == 'GET': if "ccpToken" in session and "x-auth-token" in session: ccp = CCP(session['ccpURL'],"","",session['ccpToken'],session['x-auth-token']) jsonData = request.args.to_dict() response = ccp.getProviderVsphereVMs(jsonData["vsphereProviderUUID"],jsonData["vsphereProviderDatacenter"]) if response: socketio.emit('consoleLog', {'loggingType': 'INFO','loggingMessage': config.INFO_VSPHERE_VMS }) return jsonify(response) else: return jsonify("[]")
def run_ccpLogin(): if request.method == 'POST': ccp = CCP("https://" + request.form['IP Address'],request.form['Username'],request.form['Password']) loginV2 = ccp.loginV2() loginV3 = ccp.loginV3() if not loginV2 and not loginV3: print ("There was an issue with login: "******"https://" + request.form['IP Address'] session['ccpToken'] = loginV2.cookies.get_dict() session['x-auth-token'] = loginV3 return render_template('ccpClusterCreation.html') return render_template('ccpLogin.html')
class FTMQ: FTMQ_SEPARATOR = b'\x00' FTMQ_MAX_MSG = 49 def __init__(self): self.ccp = CCP() self.ccp.register_callback(CCP.CCP_FTMQ_QUEUE, self.message_received) self.callbacks = [] #This function is called each time a packet is received #it checks the topic and call the subscribed functions def message_received(self, msg): #print("received: ", msg) (topic, sep, payload) = msg.partition(self.FTMQ_SEPARATOR) try: topic_str = topic.decode() if (self.check_topic(topic_str) and len(payload) > 0): for callback in self.callbacks: if topic_str == callback['topic']: callback['callback'](topic_str, payload) except UnicodeError: # bad message pass def publish(self, commid, topic, payload): msg = topic.encode() + self.FTMQ_SEPARATOR + payload #print(msg, len(msg)) self.ccp.send_data(commid, CCP.CCP_FTMQ_QUEUE, msg) def subscribe(self, commid, r_topic, r_callback): self.callbacks.append(dict(topic=r_topic, callback=r_callback)) # in python host handles topic filtering # send subscribe to all to ftclick (empty msg) #self.ccp.send_data(commid, CCP.CCP_FTMQ_QUEUE, bytes()) def check_topic(self, topic): # check if topic contains illegal chars return True
def run_clusterConfigTemplate(): if request.method == 'GET': if "ccpToken" in session and "x-auth-token" in session: ccp = CCP(session['ccpURL'],"","",session['ccpToken'],session['x-auth-token']) try: if API_VERSION == 2: with open("ccpRequestV2.json") as json_data: clusterData = json.load(json_data) return jsonify(clusterData) else: with open("ccpRequestV3.json") as json_data: clusterData = json.load(json_data) return jsonify(clusterData) except IOError as e: return "I/O error({0}): {1}".format(e.errno, e.strerror)
def __init__(self): self.ccp = CCP() self.ccp.register_callback(CCP.CCP_FTMQ_QUEUE, self.message_received) self.callbacks = []
def run_ccpClusterCreation(): if request.method == 'POST': uuid = "" if "ccpToken" not in session or "x-auth-token" not in session: return render_template('ccpLogin.html') ccp = CCP(session['ccpURL'],"","",session['ccpToken'],session['x-auth-token']) formData = request.get_json() try: if API_VERSION == 2: with open("ccpRequestV2.json") as json_data: clusterData = json.load(json_data) else: with open("ccpRequestV3.json") as json_data: clusterData = json.load(json_data) except IOError as e: socketio.emit('consoleLog', {'loggingType': 'ERROR','loggingMessage': config.ERROR_DEPLOY_CLUSTER_FAILED}) return json.dumps({'success':False,"errorCode":"ERROR_DEPLOY_CLUSTER_FAILED","errorMessage":config.ERROR_DEPLOY_CLUSTER_FAILED,"errorMessageExtended":e}), 400, {'ContentType':'application/json'} # if a proxy is required then we need to insert this once the worker nodes have been deployed # we will generate new SSH keys which will be provided to CCP as the initial keys # once the proxy has been updated we will insert the if "proxyInput" in formData: socketio.emit('consoleLog', {'loggingType': 'INFO','loggingMessage': config.INFO_SETTING_PROXY }) proxyInput = formData["proxyInput"] regex = re.compile( r'^((?:http)s?://)?' # http:// or https:// r'(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+(?:[A-Z]{2,6}\.?|[A-Z0-9-]{2,}\.?)|' #domain... r'localhost|' #localhost... r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})' # ...or ip r'(?::\d+)?' # optional port r'(?:/?|[/?]\S+)$', re.IGNORECASE) if re.match(regex, proxyInput) is None: return json.dumps({'success':False,"errorCode":"ERROR_INVALID_PROXY","errorMessage":config.ERROR_INVALID_PROXY}), 400, {'ContentType':'application/json'} # create a directory to add temporary keys - will be deleted once the proxy has been configured if not os.path.exists("./tmp-keys/"): try: socketio.emit('consoleLog', {'loggingType': 'INFO','loggingMessage': config.INFO_PROXY_CREATING_TEMP_DIR }) os.makedirs("./tmp-keys/") except OSError as e: if e.errno != errno.EEXIST: socketio.emit('consoleLog', {'loggingType': 'ERROR','loggingMessage': config.ERROR_CONFIGURING_PROXY }) return json.dumps({'success':False,"errorCode":"ERROR_CONFIGURING_PROXY","errorMessage":config.ERROR_CONFIGURING_PROXY,"errorMessageExtended":e}), 400, {'ContentType':'application/json'} socketio.emit('consoleLog', {'loggingType': 'INFO','loggingMessage': config.INFO_PROXY_GENERATING_KEYS }) keyName = "{}-{}".format(session["sessionUUID"],formData["clusterName"]) proxy.generateTemporaryKeys(keyName,"./tmp-keys") with open("./tmp-keys/{}.pub".format(keyName)) as f: publicKey = f.read().splitlines() sshKey = str(publicKey[0]) clusterData["ssh_key"] = sshKey socketio.emit('consoleLog', {'loggingType': 'INFO','loggingMessage': config.INFO_PROXY_GENERATING_KEYS_COMPLETE }) else: clusterData["ssh_key"] = formData["sshKey"] if "vsphereResourcePools" not in formData: formData["vsphereResourcePools"] = "" # The CCP API v2 and v3 are different and use a different JSON structure. By default you will be using v3 # This gets all the data the user provided in the form and then inserts it into the template found in ccpRequestV3.json if API_VERSION == 2: clusterData["name"] = formData["clusterName"] clusterData["datacenter"] = formData["vsphereDatacenters"] clusterData["cluster"] = formData["vsphereClusters"] clusterData["resource_pool"] = formData["vsphereClusters"] + "/" + formData["vsphereResourcePools"] clusterData["datastore"] = formData["vsphereDatastores"] clusterData["ingress_vip_pool_id"] = formData["vipPools"] clusterData["master_node_pool"]["template"] = formData["tenantImageTemplate"] clusterData["worker_node_pool"]["template"] = formData["tenantImageTemplate"] clusterData["node_ip_pool_uuid"] = formData["vipPools"] clusterData["networks"] = [formData["vsphereNetworks"] ] clusterData["provider_client_config_uuid"] = formData["vsphereProviders"] clusterData["deployer"]["provider"]["vsphere_client_config_uuid"] = formData["vsphereProviders"] clusterData["deployer"]["provider"]["vsphere_datacenter"] = formData["vsphereDatacenters"] clusterData["deployer"]["provider"]["vsphere_datastore"] = formData["vsphereDatastores"] clusterData["deployer"]["provider"]["vsphere_working_dir"] = "/" + formData["vsphereDatacenters"] + "/vm" else: clusterData["name"] = formData["clusterName"] clusterData["subnet_id"] = formData["vipPools"] clusterData["master_group"]["template"] = formData["tenantImageTemplate"] clusterData["node_groups"][0]["template"] = formData["tenantImageTemplate"] clusterData["provider"] = formData["vsphereProviders"] clusterData["vsphere_infra"]["datacenter"] = formData["vsphereDatacenters"] clusterData["vsphere_infra"]["datastore"] = formData["vsphereDatastores"] clusterData["vsphere_infra"]["networks"] = [ formData["vsphereNetworks"] ] clusterData["vsphere_infra"]["cluster"] = formData["vsphereClusters"] clusterData["vsphere_infra"]["resource_pool"] = formData["vsphereResourcePools"] clusterData["node_groups"][0]["ssh_key"] = clusterData["ssh_key"] clusterData["master_group"]["ssh_key"] = clusterData["ssh_key"] clusterData.pop('ssh_key', None) if "gpus" in formData and formData["gpus"] != "No GPU Selected": gpus = [{"type":formData["gpus"],"count":1}] clusterData["node_groups"][0]["gpus"] = gpus socketio.emit('consoleLog', {'loggingType': 'INFO','loggingMessage': config.INFO_DEPLOY_CLUSTER }) response = ccp.deployCluster(clusterData) if API_VERSION == 2 : if (response.status_code == 200) or (response.status_code == 201) : socketio.emit('consoleLog', {'loggingType': 'INFO','loggingMessage': config.INFO_DEPLOY_CLUSTER_COMPLETE }) if "uuid" not in response.json(): socketio.emit('consoleLog', {'loggingType': 'ERROR','loggingMessage': config.ERROR_DEPLOY_CLUSTER_FAILED }) return json.dumps({'success':False,"errorCode":"ERROR_DEPLOY_CLUSTER_FAILED","errorMessage":config.ERROR_DEPLOY_CLUSTER_FAILED,"errorMessageExtended":response.text}), 400, {'ContentType':'application/json'} uuid = response.json()["uuid"] else: if "id" not in response.json(): socketio.emit('consoleLog', {'loggingType': 'ERROR','loggingMessage': config.ERROR_DEPLOY_CLUSTER_FAILED }) return json.dumps({'success':False,"errorCode":"ERROR_DEPLOY_CLUSTER_FAILED","errorMessage":config.ERROR_DEPLOY_CLUSTER_FAILED,"errorMessageExtended":response.text}), 400, {'ContentType':'application/json'} uuid = response.json()["id"] kubeConfig = ccp.getConfig(uuid) if API_VERSION == 2 : if "apiVersion" in kubeConfig.text: socketio.emit('consoleLog', {'loggingType': 'INFO','loggingMessage': config.INFO_CREATING_KUBE_CONFIG }) kubeConfigDir = os.path.expanduser(config.KUBE_CONFIG_DIR) if not os.path.exists(kubeConfigDir): try: os.makedirs(kubeConfigDir) except OSError as e: if e.errno != errno.EEXIST: raise with open("{}/{}".format(kubeConfigDir,'k8s_' + str(session["sessionUUID"])), "w") as f: f.write(kubeConfig.text) else: socketio.emit('consoleLog', {'loggingType': 'ERROR','loggingMessage': config.ERROR_KUBECONFIG_MISSING}) return json.dumps({'success':False,"errorCode":"ERROR_KUBECONFIG_MISSING","errorMessage":config.ERROR_KUBECONFIG_MISSING}), 400, {'ContentType':'application/json'} else: # it looks like the CCP V3 API has made the cluster creation async so we get back a response straight away however # theres a status field which shows "CREATING". Will need to wait until this is "READY" if "status" in kubeConfig.text: while kubeConfig.json()["status"] == "CREATING": kubeConfig = ccp.getConfig(uuid) socketio.emit('consoleLog', {'loggingType': 'INFO','loggingMessage': config.INFO_DEPLOY_CLUSTER }) time.sleep(30) if kubeConfig.json()["status"] != "READY": socketio.emit('consoleLog', {'loggingType': 'ERROR','loggingMessage': config.ERROR_DEPLOY_CLUSTER_FAILED }) return json.dumps({'success':False,"errorCode":"ERROR_DEPLOY_CLUSTER_FAILED","errorMessage":config.ERROR_DEPLOY_CLUSTER_FAILED,"errorMessageExtended":response.text}), 400, {'ContentType':'application/json'} socketio.emit('consoleLog', {'loggingType': 'INFO','loggingMessage': config.INFO_DEPLOY_CLUSTER_COMPLETE }) if "kubeconfig" in kubeConfig.text: kubeConfig = kubeConfig.json()["kubeconfig"] socketio.emit('consoleLog', {'loggingType': 'INFO','loggingMessage': config.INFO_CREATING_KUBE_CONFIG }) kubeConfigDir = os.path.expanduser(config.KUBE_CONFIG_DIR) if not os.path.exists(kubeConfigDir): try: os.makedirs(kubeConfigDir) except OSError as e: if e.errno != errno.EEXIST: raise with open("{}/{}".format(kubeConfigDir,session["sessionUUID"]), "w") as f: f.write(kubeConfig) else: socketio.emit('consoleLog', {'loggingType': 'ERROR','loggingMessage': config.ERROR_KUBECONFIG_MISSING}) return json.dumps({'success':False,"errorCode":"ERROR_KUBECONFIG_MISSING","errorMessage":config.ERROR_KUBECONFIG_MISSING}), 400, {'ContentType':'application/json'} # if a proxy is required then we need to insert his once the worker nodes have been deployed if "proxyInput" in formData: cluster = ccp.getCluster(clusterData["name"]) if "uuid" in cluster.text: cluster = cluster.json() nodes = cluster["nodes"] privateKey = "{}-{}".format(session["sessionUUID"],clusterData["name"]) publicKey = "{}-{}.pub".format(session["sessionUUID"],clusterData["name"]) if os.path.isfile('./tmp-keys/{}'.format(privateKey)) and os.path.isfile('./tmp-keys/{}'.format(publicKey)) : for node in nodes: socketio.emit('consoleLog', {'loggingType': 'INFO','loggingMessage': config.INFO_DEPLOYING_PROXY + " " + node["public_ip"] }) proxy.sendCommand(node["public_ip"],'ccpuser','./tmp-keys/{}'.format(privateKey),formData["sshKey"],'configure_proxy.sh',proxyInput ) else: socketio.emit('consoleLog', {'loggingType': 'ERROR','loggingMessage': config.ERROR_PROXY_CONFIGURATION}) socketio.emit('consoleLog', {'loggingType': 'INFO','loggingMessage': config.INFO_PROXY_SSH_CLEANUP}) proxy.deleteTemporaryKeys(privateKey,publicKey,"./tmp-keys") else: socketio.emit('consoleLog', {'loggingType': 'ERROR','loggingMessage': config.ERROR_DEPLOY_CLUSTER_FAILED}) return json.dumps({'success':False,"errorCode":"ERROR_DEPLOY_CLUSTER_FAILED","errorMessage":config.ERROR_DEPLOY_CLUSTER_FAILED,"errorMessageExtended":cluster.text}), 400, {'ContentType':'application/json'} socketio.emit('consoleLog', {'loggingType': 'INFO','loggingMessage': config.INFO_DEPLOY_CLUSTER_COMPLETE}) return jsonify(dict(redirectURL='/deployKubeflow')) elif request.method == 'GET': if "ccpToken" in session: return render_template('ccpClusterCreation.html') else: return render_template('ccpLogin.html')
import sys import os from ccp import CCP from cluster import cluster from node import node import logging ccp = CCP(os.environ['CCPIP'], os.environ['CCPUSER'], os.environ['CCPPASS']) cluster1 = cluster(os.environ['CLUSTERNAME'], ccp) ips = cluster1.getworkerips() totalLoad = 0 for ip in ips: workernode = node(ip) totalLoad = totalLoad + workernode.getAvgLoad() loadAvgOverAllNodes = totalLoad / len(ips) print("Average load over all nodes is " + str(loadAvgOverAllNodes)) if (loadAvgOverAllNodes > 0.8): # Load higher than 80% --> scale up print("Scaling up...") cluster1.scaleupworkernodes() elif (loadAvgOverAllNodes < 0.5): if (cluster1.getnumberofworkernodes() > 1): # Load lower than 50% --> scale down print("Scaling down...") cluster1.scaledownworkernodes()
def func1(payload): '''Receives the payload of the received ccp packet''' print("function1") print("Payload:", end= " ") print(payload) def func2(payload): print("function2") for b in bytes(payload): print(int(b), end=" ") if __name__ == "__main__": #Reads the serial port from the scripts arguments comm = SerialComm(sys.argv[1]) #Creates a new CCP object ccp = CCP() #Send the comm(serial, at least by now) to ccp and return and id to this comm commid = ccp.register_comm(comm) #Register the function that will be called when a new ccp packet arrives #The first argument is the queue ccp.register_callback(4,func1) ccp.register_callback(1,func2) print("Starting") while(True): #Do tasks like checking if there is any new incomming ccp packet ccp.poll_1msec() #Generates random data data = bytes(range(random.randrange(2,100))) #Sends the random data to the port especified at the start, to the queue number 1 ccp.send_data(commid,1,data) #waits 1 second
if (value): command_data = self.DEBUG_QUEUES[key] data = bytes([command_id, command_data]) self.ccp.send_data(commid, self.COMMAND_QUEUE, data) def command_cb(self, payload): print("command: {} ".format(str(payload[0]))) for b in bytes(payload): print(int(b), end=" ") if __name__ == "__main__": args = docopt(__doc__) #print(args) comm = SerialComm(args['<port>']) ccp = CCP() commid = ccp.register_comm(comm) ccp_command_q = CCP_Command(ccp, commid) command_parsed_args = docopt(subcommands[args['<command>']], argv=args['<args>']) #print(command_parsed_args) ccp_command_q.send_command(args['<command>'], **command_parsed_args) # wait for a response start_time = time.time() while ((time.time() - start_time) < CCP_Command.COMMAND_RES_TIMEOUT): ccp.poll_1msec() time.sleep(0.001)