#include #include "curlpp/Options.hpp" #include "kubecontrol/Container.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 namespace kubecontrol { KubePod::KubePod(const std::string &Owner, const std::string &Uuid, const std::string &ContainerImage, const std::string &Namespace) :Owner_(Utils::to_lower(Owner)), Uuid_(Utils::to_lower(Uuid)), ContainerRegistry_("kmaster.ti.unibw-hamburg.de:30808"), Namespace_(Namespace) { // EnvirmonentVars_ = std::map(); this->PathToYaml_ = "config/pods/" + this->Uuid_ + ".yaml"; if( !std::filesystem::directory_entry("config").exists()) { std::filesystem::create_directory("config"); } std::filesystem::directory_entry entry("config/pods"); if(!entry.exists()) { std::filesystem::create_directory("config/pods"); } auto map = std::map(); addContainer(Uuid, ContainerImage,map); } KubePod::KubePod(const std::string &Owner, const std::string &Uuid, const std::string &Component, const std::string &ContainerImage, const std::string &Namespace): Owner_(Utils::to_lower(Owner)), Uuid_(Utils::to_lower(Uuid)), Component_(Utils::to_lower(Component)), ContainerRegistry_("kmaster.ti.unibw-hamburg.de:30808"), Namespace_(Namespace) { // EnvirmonentVars_ = std::map(); this->PathToYaml_ = "config/pods/" + this->Uuid_ + ".yaml"; if( !std::filesystem::directory_entry("config").exists()) { std::filesystem::create_directory("config"); } std::filesystem::directory_entry entry("config/pods"); if(!entry.exists()) { std::filesystem::create_directory("config/pods"); } auto map = std::map(); addContainer(Uuid, ContainerImage,map); } void KubePod::addContainer(std::string name,std::string image, std::map &envs, PullPolicy pullPolicy ) { Container container(Owner_,name,image,pullPolicy); container.addEnv(envs); ContainerImages_.push_back(container); } void KubePod::addContainer(Container containter) { ContainerImages_.push_back(containter); } void KubePod::addEnvValuesToContainer(std::string containerUUID, std::map envs) { for (auto container: ContainerImages_) { if (container.getUUID() == containerUUID +"-container") { container.addEnv(envs); } } } 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]; } return ""; } void KubePod::setArgs(const std::string &args) { Args_.emplace_back(Utils::to_lower(args)); } std::vector KubePod::GetArgs() { return Args_; } void KubePod::setCommand(const std::string &command) { PodCommand_ = Utils::to_lower(command); } std::string KubePod::getCommand() { return PodCommand_; } void KubePod::setComponent(const 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].toYAML(); // 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 (const auto& item :EnvirmonentVars_) { node["spec"]["containers"][0]["env"][i]["name"] = item.first; node["spec"]["containers"][0]["env"][i]["value"] = item.second; i++; } if (!Args_.empty()) { node["spec"]["containers"][0]["args"].SetStyle(YAML::EmitterStyle::Flow); for (const 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 ) { 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.empty()) { return 1; } for(const auto& uuid: uuids) { std::string request = "/api/v1/namespaces/simulator/pods/"+uuid.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.empty()) { 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.empty()) { return {}; } extractInformationFromResopnse(result); return this->ChildPods; } int KubePod::extractInformationFromResopnse(std::string response) { if (response.empty()) { 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)<