#include "curlpp/Options.hpp" #include "kubecontrol/PodController.hpp" #include "kubecontrol/Utils.hpp" #include "nlohmann/json_fwd.hpp" #include "yaml-cpp/binary.h" #include #include #include #include #include #include #include #include #include #include #include #include "loguru.hpp" #include "yaml-cpp/node/node.h" namespace kubecontrol { KubePod::KubePod(std::string Owner, std::string Uuid, std::string ContainerImage,std::string Namespace) :Owner_(Utils::to_lower(Owner)), Uuid_(Utils::to_lower(Uuid)), Namespace_(Namespace), EnvirmonentVars_() { ContainerRegistry_ = "kmaster.ti.unibw-hamburg.de:30808"; EnvirmonentVars_ = std::map(); this->PathToYaml_ = "config/pods/" + this->Uuid_ + ".yaml"; if( std::filesystem::directory_entry("config").exists() != true) { std::filesystem::create_directory("config"); } std::filesystem::directory_entry entry("config/pods"); if(entry.exists() != true) { std::filesystem::create_directory("config/pods"); } addContainer(Uuid, ContainerImage); } KubePod::KubePod(std::string Owner, std::string Uuid, std::string Component, std::string ContainerImage,std::string Namespace): Owner_(Utils::to_lower(Owner)), Uuid_(Utils::to_lower(Uuid)), Component_(Utils::to_lower(Component)), Namespace_(Namespace), EnvirmonentVars_() { ContainerRegistry_ = "kmaster.ti.unibw-hamburg.de:30808"; EnvirmonentVars_ = std::map(); this->PathToYaml_ = "config/pods/" + this->Uuid_ + ".yaml"; if( std::filesystem::directory_entry("config").exists() != true) { std::filesystem::create_directory("config"); } std::filesystem::directory_entry entry("config/pods"); if(entry.exists() != true) { std::filesystem::create_directory("config/pods"); } addContainer(Uuid, ContainerImage); } void KubePod::addContainer(std::string name,std::string image, std::shared_ptr> envs, PullPolicy pullPolicy ) { YAML::Node container; transform(image.begin(), image.end(), image.begin(), ::tolower); transform(name.begin(), name.end(), name.begin(), ::tolower); container["name"] = name+"-container"; container["image"] = this->ContainerRegistry_ + "/" + image; container["imagePullPolicy"] = toString(pullPolicy); if (envs != nullptr) { int i = 0; for(auto [key,value] : *envs) { container["env"][i]["name"] = key; container["env"][i]["value"] = value; i++; } } ContainerImages_.push_back(container); } std::string KubePod::getUUID() { return this->Uuid_; } std::string KubePod::getOwner() { return this->Owner_; } std::string KubePod::getIp() { return this->Ip_; } std::string KubePod::getStatus() { return this->Status_; } void KubePod::setEnvironmentVar(std::string key, std::string val) { EnvirmonentVars_.emplace(key,val); } std::map KubePod::GetEnvironmentVars() { return EnvirmonentVars_; } std::string KubePod::GetEnvironmentVar(std::string key) { if(EnvirmonentVars_.contains(key)) { return EnvirmonentVars_[key]; } else { return nullptr; } } void KubePod::setArgs(std::string args) { Args_.emplace_back(Utils::to_lower(args)); } std::vector KubePod::GetArgs() { return Args_; } void KubePod::setCommand(std::string command) { PodCommand_ = Utils::to_lower(command); } std::string KubePod::getCommand() { return PodCommand_; } void KubePod::setComponent(std::string component) { this->Component_ = Utils::to_lower(component); } std::string KubePod::getComponent() { return this->Component_; } void KubePod::setName(std::string name) { this->Name_ = name; } std::string KubePod::getName() { return this->Name_; } std::string KubePod::createYAML() { YAML::Node node; node["apiVersion"] = "v1"; node["kind"] = "Pod"; node["metadata"]["name"] = this->Uuid_; node["metadata"]["namespace"] = this->Namespace_; node["metadata"]["labels"]["app.kubernetes.io/name"] = this->Uuid_; node["metadata"]["labels"]["app.kubernetes.io/part-of"] = this->Owner_; // if (!std::empty(this->Component_)) node["metadata"]["labels"]["app.kubernetes.io/component"] = this->Component_; node["metadata"]["labels"]["app.kubernetes.io/component"] = this->Component_; for (int i = 0; i< this->ContainerImages_.size(); i++) { node["spec"]["containers"][i] = this->ContainerImages_[i]; // node["spec"]["containers"][i]["name"] = this->Uuid_+"-container"; // node["spec"]["containers"][i]["image"] = this->ContainerRegistry_ + "/" + this->ContainerImages_[i]; // node["spec"]["containers"][i]["imagePullPolicy"] = imagePullPolicy; // node["spec"]["containers"][i]["ports"][0]["containerPort"] = 10000; // node["spec"]["containers"][i]["ports"][0]["protocol"] = "UDP"; } int i = 0; for (auto item :EnvirmonentVars_) { node["spec"]["containers"][0]["env"][i]["name"] = item.first; node["spec"]["containers"][0]["env"][i]["value"] = item.second; i++; } if (Args_.size() > 0) { node["spec"]["containers"][0]["args"].SetStyle(YAML::EmitterStyle::Flow); for (auto item : Args_) { node["spec"]["containers"][0]["args"].push_back(item); } } if (!PodCommand_.empty()) { node["spec"]["containers"][0]["command"].SetStyle(YAML::EmitterStyle::Flow); node["spec"]["containers"][0]["command"].push_back(PodCommand_); } node["spec"]["terminationGracePeriodSeconds"] = 5; node["spec"]["restartPolicy"] = "Never"; YAMLNode_ = node; std::ofstream fout(this->PathToYaml_); fout << node; fout.close(); return this->PathToYaml_; } int KubePod::start(KubernetesAPI APIInterface,bool WaitTillRunning) { std::string request = "/api/v1/namespaces/simulator/pods/"; this->createYAML(); std::stringstream stream; stream << YAMLNode_; std::string response = APIInterface.performRequest(request,"POST",stream.str()); extractInformationFromResopnse(response); auto timeoutTime = std::chrono::system_clock::now() + std::chrono::seconds(10); if (WaitTillRunning == true ) { while ((this->Status_ != "Running" && this->Status_ != "Succeeded") || std::chrono::system_clock::now() >= timeoutTime) { // LOG_S(INFO)<<"wainting till running " << this->Status_; std::this_thread::sleep_for(std::chrono::milliseconds(100)); this->updateInfoForThisPod(APIInterface); } } else { std::this_thread::sleep_for(std::chrono::milliseconds(200)); } return 0; } int KubePod::stop(KubernetesAPI APIInterface) { std::string request = "/api/v1/namespaces/simulator/pods/"+Uuid_; std::string result = APIInterface.performRequest(request,"DELETE"); LOG_S(INFO)<<"stopping: " <getPodsChilds(APIInterface); if (uuids.size() == 0) { return 1; } for(auto i: uuids) { std::string request = "/api/v1/namespaces/simulator/pods/"+i.UUID; std::string result = APIInterface.performRequest(request,"DELETE"); } return 0; } int KubePod::updateInfoForThisPod(KubernetesAPI APIInterface) { std::string request = "/api/v1/namespaces/simulator/pods/"+Uuid_+"/status"; std::string result = APIInterface.performRequest(request,"GET"); if (result == "") { return 1; } if (extractInformationFromResopnse(result)!= 0) { return 1; } return 0; } std::vector KubePod::getPodsChilds( KubernetesAPI APIInterface) { std::string request = "/api/v1/namespaces/simulator/pods?labelSelector=app.kubernetes.io/part-of="+Uuid_; std::string result = APIInterface.performRequest(request,"GET"); if (result == "") { return std::vector(); } extractInformationFromResopnse(result); return this->ChildPods; } int KubePod::extractInformationFromResopnse(std::string response) { if (response == "") { return 1 ; } // LOG_S(INFO)<< response; nlohmann::json j; try { j = nlohmann::json::parse(response); if(j.contains("kind") && j["kind"] == "Pod") { if( j["status"].contains("podIP")) this->Ip_ = j["status"]["podIP"].get(); this->Status_ = j["status"]["phase"].get(); this->PartOf_ = j["metadata"]["labels"]["app.kubernetes.io/part-of"]; }else if(j.contains("items") && j["items"].is_array()) { for (auto i : j["items"]) { // LOG_S(INFO)<(); child.IP = i["status"]["podIP"].get(); child.Status = i["status"]["phase"].get(); child.Component = i["metadata"]["labels"]["app.kubernetes.io/component"].get(); this->ChildPods.push_back(child); } }else{ return 1; } } catch (const std::exception e) { LOG_S(ERROR)<< "Exeption in extractInformationFromResopnse() :" << e.what(); std::exception_ptr p = std::current_exception(); LOG_S(ERROR)<< "Exeption :" << p.__cxa_exception_type()->name(); LOG_S(INFO)<