def get(self, beehive_id): bee_db = BeekeeperDB() obj = bee_db.get_beehive(beehive_id) if not obj: raise Exception(f"Beehive {beehive_id} not found" ) bee_db.close() return jsonify(obj)
def post(self, beehive_id): expected_forms = ["tls-key", "tls-cert", "ssh-key", "ssh-pub", "ssh-cert"] count_updated = 0 data={} try: bee_db = BeekeeperDB() obj = bee_db.get_beehive(beehive_id) if not obj: raise Exception(f"Beehive {beehive_id} not found" ) for formname in request.files: if not formname in expected_forms: raise Exception(f"Formname {formname} not supported" ) # we could remove this check... for formname in expected_forms: if not formname in request.files: raise Exception(f"Formname {formname} missing" ) for formname in request.files: formdata = request.files.get(formname).read().decode("utf-8") if not formdata: raise Exception(f"Field {formname} empty" ) data[formname] = formdata #logger.debug(f"data: {formname} {data[formname]}") #filename = secure_filename(file.filename) #logger.debug(f"filename: {filename}") for formname in data: col_name = formname.replace("-", "_ca_") count_updated += bee_db.update_object_field("beehives", col_name, data[formname], "id", beehive_id) bee_db.close() except Exception as e: raise ErrorResponse(f"something failed: {str(e)}" , status_code=HTTPStatus.INTERNAL_SERVER_ERROR) return jsonify({"modified": count_updated})
def deploy_wes(node_id, this_debug, force=False): logger.debug("(deploy_wes) determine correct beehive") assign_beehive = "" bee_db = None try: bee_db = BeekeeperDB() node_state = bee_db.get_node_state(node_id) except Exception as e: raise Exception(f"finding beehive for node failed: {str(e)}") if not node_state: raise Exception(f"node {node_id} not found") if not "beehive" in node_state: raise Exception(f"Node is not assigned to any beehive") assign_beehive=node_state["beehive"] if assign_beehive == "": raise Exception(f"Node is not assigned to any beehive") try: beehive_obj = bee_db.get_beehive(assign_beehive) except Exception as e: raise Exception(f"finding beehive for node failed: {str(e)}") if not beehive_obj: raise Exception(f"Beehive {assign_beehive} unknown" ) if not isinstance(beehive_obj, dict): raise Exception(f"beehive_obj is not a dict") beehive_id = beehive_obj.get("id", "") if not beehive_id: raise Exception(f"beehive_id is missing") logger.debug(f"(deploy_wes) using beehive {beehive_id}") # first check if kubectl work on the node try: result_stdout_str ,result_stderr_str, exit_code = node_ssh(node_id, "kubectl get nodes") except Exception as e: raise Exception(f"node_ssh failed: {str(e)}") if exit_code != 0: raise Exception(f"ssh failed or kubectl is not yet ready ({result_stderr_str})") logger.debug("calling create_ssh_upload_cert") try: create_ssh_upload_cert(bee_db, node_id, beehive_obj, force=force ) except Exception as e: raise Exception(f"create_ssh_upload_cert failed: {type(e).__name__} {str(e)}") logger.debug("calling create_tls_cert_for_node") try: create_tls_cert_for_node(bee_db, node_id, beehive_obj, force=force) except Exception as e: raise Exception(f"create_tls_cert_for_node failed: {type(e).__name__} {str(e)}") node_keypair = bee_db.get_node_keypair(node_id) if not "ssh_key_private" in node_keypair: raise Exception(f"ssh_key_private field missing in node_keypair") if not "ssh_key_public" in node_keypair: raise Exception(f"ssh_key_public field missing in node_keypair") ssh_key_private = node_keypair["ssh_key_private"] ssh_key_public = node_keypair["ssh_key_public"] logger.debug("calling get_node_credentials_all") try: node_creds = bee_db.get_node_credentials_all(node_id, beehive_id) except Exception as e: raise Exception(f"get_node_credentials_all failed: {type(e).__name__} {str(e)}") bee_db.close() if not "tls_cert" in node_creds: raise Exception(f"tls_cert field missing in node_creds") if not "tls_key" in node_creds: raise Exception(f"tls_key field missing in node_creds") if not "ssh_upload_cert" in node_creds: raise Exception(f"ssh_upload_cert field missing in node_creds") ssh_upload_cert = node_creds["ssh_upload_cert"] # create and push secret for upload-ssh-key upload_secret = kube_secret("wes-beehive-upload-ssh-key", { "ssh-key": ssh_key_private, "ssh-key.pub": ssh_key_public, "ssh-key-cert.pub": ssh_upload_cert, }) kubectl_apply_with_logging(node_id, upload_secret) # create and upload tls secret tls_secret = kube_secret("wes-beehive-rabbitmq-tls", { "cert.pem": node_creds["tls_cert"], "key.pem": node_creds["tls_key"], }) kubectl_apply_with_logging(node_id, tls_secret) #return {"result": "A"} #################### # waggle id / host / port config map for key in ["rmq_host", "rmq_port", "upload_host", "upload_port"]: if not key in beehive_obj: raise Exception(f"Beekeeper field {key} missing") rmq_host = beehive_obj["rmq_host"] rmq_port = beehive_obj["rmq_port"] upload_host = beehive_obj["upload_host"] upload_port = beehive_obj["upload_port"] waggle_ConfigMap = kube_configmap("waggle-config", { "WAGGLE_NODE_ID": node_id.lower(), "WAGGLE_BEEHIVE_RABBITMQ_HOST": rmq_host, "WAGGLE_BEEHIVE_RABBITMQ_PORT": str(rmq_port), "WAGGLE_BEEHIVE_UPLOAD_HOST": upload_host, "WAGGLE_BEEHIVE_UPLOAD_PORT": str(upload_port), }) kubectl_apply_with_logging(node_id, waggle_ConfigMap) ########################### # beehive-ssh-ca configmap for key in ["ssh-pub", "ssh-cert", "tls-cert"]: if not key in beehive_obj: available_str = ",".join(list(beehive_obj)) raise Exception(f"Beekeeper field {key} missing (got: {available_str})") ca_ssh_pub = beehive_obj["ssh-pub"] ca_ssh_cert = beehive_obj["ssh-cert"] ca_tls_cert = beehive_obj["tls-cert"] #return {"result": "B"} beehive_ssh_ca_ConfigMap = kube_configmap("beehive-ssh-ca", { "ca.pub": ca_ssh_pub, "ca-cert.pub": ca_ssh_cert, }) kubectl_apply_with_logging(node_id, beehive_ssh_ca_ConfigMap) ########################### # beehive-tls-ca configmap beehive_tls_ca_ConfigMap = kube_configmap("beehive-ca-certificate", { "cacert.pem": ca_tls_cert, }) kubectl_apply_with_logging(node_id, beehive_tls_ca_ConfigMap) node_private_git_repo_key = "/config/node-private-git-repo-key/node-private-git-repo-key" if os.path.exists(node_private_git_repo_key): result_stdout , result_stderr, exit_code = scp(node_private_git_repo_key, node_id, "/root/.ssh/") if exit_code != 0 : raise Exception(f"scp failed {result_stderr} and {result_stdout}") else: logger.info("/config/node-private-git-repo-key/node-private-git-repo-key not found, skipping") final_command = "./update-stack.sh" if FAKE_DEPLOYMENT: final_command = "echo \"This fake deployment was successful\"" deploy_script= \ """\ #!/bin/sh ### This script was generated by beekeeper ### set -e set -x # check if k3s runs kubectl get nodes if [ ! -e "/opt/waggle-edge-stack" ] ; then cd /opt git clone https://github.com/waggle-sensor/waggle-edge-stack.git fi cd /opt/waggle-edge-stack git pull origin main #git checkout tags/v.1.0 cd /opt/waggle-edge-stack/kubernetes """ + final_command #return {"result": "C"} try: node_ssh_with_logging(node_id, "cat > /tmp/deploy.sh", input_str=deploy_script) node_ssh_with_logging(node_id, "sh /tmp/deploy.sh") except Exception as e: raise Exception(f"node_ssh_with_logging failed: {str(e)}") try: register_wes_deployment_event(node_id, lock_tables=True, lock_requested_by="wes_deployment") except Exception as e: raise Exception(f"register_wes_deployment_event failed: {str(e)}") if this_debug: return { "waggle_ConfigMap": waggle_ConfigMap, "tls_secret":tls_secret, "upload_secret": upload_secret, } #node_creds["tls_result_stdout"] = result_stdout #node_creds["tls_result_stderr"] = result_stderr return {"success":True}
def get(self): """API to create keys, certificate and user for end-point. Arguments: id (str): unique ID for this end-point Returns: dict: end-point id, private key, public key and certificate """ node_id = request.args.get("id", type=str) if not node_id: logger.debug("Registration failed: id missing") return f"Error: id missing\n", 500 logger.debug("Register user [{}]".format(node_id)) if DEFAULT_BEEHIVE: # first check the default beehive exists try: bee_db = BeekeeperDB() beehive_obj = bee_db.get_beehive(DEFAULT_BEEHIVE) bee_db.close() except Exception as e: raise Exception(f"error: get_beehive returned: {str(e)}") if not beehive_obj: raise Exception(f"error: Beehive {DEFAULT_BEEHIVE} is not known yet" ) try: # create keypair and certificates for node (idempotent function) registration_result = _register(node_id) except Exception as e: logger.debug(f"_register failed: {str(e)}") traceback.print_exc() logger.debug(f"Error: unable to register id [{node_id} , {str(e)}]") return f"Error: unable to register id [{node_id} , {str(e)}]\n", 500 # update beekeeper db (create registartion event) try: register_node(node_id, lock_requested_by="register-resource") except Exception as e: logger.debug(f"Error: Creating registration event failed: {str(e)}") return f"Error: Creating registration event failed: {str(e)}", 500 if DEFAULT_BEEHIVE: time.sleep(2) # see if that helps with the locks logger.debug("Adding user [{}] to default beehive".format(node_id)) try: set_node_beehive(node_id, DEFAULT_BEEHIVE) except Exception as e: logger.debug(f"Error: Adding node to beehive {DEFAULT_BEEHIVE} failed: {str(e)}") # Do not let registration fail because of this return f"Error: Adding node to beehive {DEFAULT_BEEHIVE} failed: {str(e)}", 500 else: logger.debug("No default beehive defined") logger.debug(f"success: responding with registration results") #return json.dumps(registration_result) return registration_result