From 89465f06a5fa421fc4c424426704fc65680c4afa Mon Sep 17 00:00:00 2001 From: Henry Winkel Date: Wed, 16 Aug 2023 14:42:00 +0200 Subject: [PATCH] ADD: added podinfo with building a tree hierarchy for a pod --- CMakeLists.txt | 3 + include/kubecontrol/KubePod.hpp | 6 + include/kubecontrol/PodController.hpp | 18 ++ include/kubecontrol/PodInfo.hpp | 66 ++++++++ include/kubecontrol/Utils.hpp | 7 + src/kubecontrol/KubePod.cpp | 84 +++++++--- src/kubecontrol/PodController.cpp | 227 ++++++++++++++++++++++---- src/kubecontrol/PodInfo.cpp | 111 +++++++++++++ 8 files changed, 474 insertions(+), 48 deletions(-) create mode 100644 include/kubecontrol/PodInfo.hpp create mode 100644 src/kubecontrol/PodInfo.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index e0223e9..d69c803 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -63,6 +63,9 @@ ENDIF() include/kubecontrol/Utils.hpp src/kubecontrol/Utils.cpp + + include/kubecontrol/PodInfo.hpp + src/kubecontrol/PodInfo.cpp ) diff --git a/include/kubecontrol/KubePod.hpp b/include/kubecontrol/KubePod.hpp index 6301b81..7848cc4 100644 --- a/include/kubecontrol/KubePod.hpp +++ b/include/kubecontrol/KubePod.hpp @@ -1,5 +1,6 @@ #pragma once +#include "kubecontrol/PodInfo.hpp" #include "nlohmann/json_fwd.hpp" #include "yaml-cpp/node/node.h" #include @@ -19,6 +20,7 @@ #include + namespace kubecontrol { class KubePod @@ -49,8 +51,10 @@ namespace kubecontrol std::string stop(std::string apiAddress,std::string token); std::string getInfo(std::string apiAddress,std::string token); + PodInfo PodInfo; + private: std::string Owner_; std::string Uuid_; @@ -69,5 +73,7 @@ namespace kubecontrol + std::string StopChilds(std::string apiAddress,std::string token,std::string uuid); + }; } \ No newline at end of file diff --git a/include/kubecontrol/PodController.hpp b/include/kubecontrol/PodController.hpp index 660916f..ba467ad 100644 --- a/include/kubecontrol/PodController.hpp +++ b/include/kubecontrol/PodController.hpp @@ -1,5 +1,9 @@ #pragma once +#include "kubecontrol/PodInfo.hpp" #include +#include +#include +#include namespace kubecontrol { @@ -15,14 +19,28 @@ namespace kubecontrol void stopAllPods(); std::string getPodsInfo(); + std::string getInfoForOwnPod(); std::string getInfoForPod(std::string Label); + void checkPodsHierarchy(); + + std::string getPodsInfoForAll(); private: std::vector PodList_; + std::string performRequest(std::string url); + + void performForceStopRequest(std::string uuid); + + std::string BearerToken_; std::string ServerAddress_; std::string ApiCall_; + + // void addPodInfoToInfoList(std::shared_ptr podinfo); + std::shared_ptr getPodInfo(std::string uuid); + + std::vector> podsInfoList_; }; } // namespace ku diff --git a/include/kubecontrol/PodInfo.hpp b/include/kubecontrol/PodInfo.hpp new file mode 100644 index 0000000..8ee9831 --- /dev/null +++ b/include/kubecontrol/PodInfo.hpp @@ -0,0 +1,66 @@ +#pragma once +#include "nlohmann/json_fwd.hpp" +#include +#include +#include +#include +#include +#include + +namespace kubecontrol { + + class PodInfo + { + public: + + PodInfo(); + + PodInfo(std::string response); + + void update(std::string response); + + std::string ToString(); + nlohmann::json ToJson(); + + std::vector getRelatedPods(); + + std::string Uuid; + std::string Image; + std::string Ip; + std::string Component; + std::string Status; + std::string PartOf; + + void addRelatedPods(std::string uuid); + size_t relatedPodsSize(); + private: + std::vector relatedPods; + + + + + + + }; + + + +// struct PodInfo +// { +// std::string Uuid; +// std::string Image; +// std::string Ip; +// std::string Component; +// std::string Status; +// std::string PartOf; +// std::vector>> relatedPods; + +// bool operator==(PodInfo const &rhs ) +// { +// if (Uuid == rhs.Uuid) { +// return true; +// } +// return false; +// } +// }; +} \ No newline at end of file diff --git a/include/kubecontrol/Utils.hpp b/include/kubecontrol/Utils.hpp index 04920d2..1103ba8 100644 --- a/include/kubecontrol/Utils.hpp +++ b/include/kubecontrol/Utils.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include @@ -12,4 +13,10 @@ namespace kubecontrol static std::string to_lower(std::string); }; + + + + + + } \ No newline at end of file diff --git a/src/kubecontrol/KubePod.cpp b/src/kubecontrol/KubePod.cpp index 17d0f50..3b2f073 100644 --- a/src/kubecontrol/KubePod.cpp +++ b/src/kubecontrol/KubePod.cpp @@ -6,6 +6,7 @@ #include #include #include +#include namespace kubecontrol @@ -166,7 +167,7 @@ namespace kubecontrol node["spec"]["containers"][0]["command"].push_back(PodCommand_); } - + node["spec"]["terminationGracePeriodSeconds"] = 3; node["spec"]["restartPolicy"] = "Never"; @@ -209,23 +210,10 @@ namespace kubecontrol request.setOpt(new curlpp::options::CustomRequest("POST")); // request.setOpt(new curlpp::options::Verbose("POST")); - - this->createYAML(); LOG_S(ERROR)<< this->PathToYaml_; - std::ifstream is; - is.open (this->PathToYaml_, std::ios::binary | std::ios::ate); - is.seekg (0, std::ios::end); - long length = is.tellg(); - is.seekg (0, std::ios::beg); - - - char *buffer = new char [length]; - is.read(buffer,length); - is.close(); - std::stringstream stream; stream << YAMLNode_; // request.setOpt(new curlpp::options::PostFields(buffer)); @@ -236,7 +224,16 @@ namespace kubecontrol request.reset(); auto response = mWriterChunk.getResponse(); - return nlohmann::json::parse(response).dump(); + PodInfo.update(response); + + while (PodInfo.Status != "Running") { + std::this_thread::sleep_for(std::chrono::milliseconds(200)); + response = this->getInfo(curlURL, token); + PodInfo.update(response); + + } + + return response; } std::string KubePod::stop(std::string apiAddress,std::string token) @@ -269,12 +266,61 @@ namespace kubecontrol request.perform(); auto response = mWriterChunk.getResponse(); - return nlohmann::json::parse(response).dump(); + + LOG_S(INFO)< 0) + { + for(int i = 0; i headers; + headers.push_back(AuthString); + + + curlpp::Cleanup cleaner; + curlpp::Easy request; + + WriterMemoryClass mWriterChunk; + curlpp::types::WriteFunctionFunctor functor = std::bind(&WriterMemoryClass::WriteMemoryCallback, &mWriterChunk, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3); + curlpp::options::WriteFunction *writefunction = new curlpp::options::WriteFunction(functor); + request.setOpt(writefunction); + + request.setOpt(new curlpp::options::HttpHeader(headers)); + request.setOpt(new curlpp::options::Url(curlURL)); + + + request.setOpt(new curlpp::options::SslVerifyPeer(false)); + + + request.setOpt(new curlpp::options::CustomRequest("DELETE")); + // request.setOpt(new curlpp::options::Verbose(true)); + + + request.perform(); + auto response = mWriterChunk.getResponse(); + + + return response; + } + + + std::string KubePod::getInfo(std::string apiAddress,std::string token) { - std::string curlURL = apiAddress+"/"+Uuid_; + std::string curlURL = apiAddress+Uuid_+"/"+"status"; std::string AuthString = "Authorization: Bearer " + token; std::list headers; @@ -296,11 +342,11 @@ namespace kubecontrol request.setOpt(new curlpp::options::Url(curlURL)); request.setOpt(new curlpp::options::SslVerifyPeer(false)); - + request.perform(); auto response = mWriterChunk.getResponse(); - return nlohmann::json::parse(response).dump(); + return response; } diff --git a/src/kubecontrol/PodController.cpp b/src/kubecontrol/PodController.cpp index 9970470..36eecdb 100644 --- a/src/kubecontrol/PodController.cpp +++ b/src/kubecontrol/PodController.cpp @@ -1,8 +1,13 @@ +#include "kubecontrol/PodInfo.hpp" +#include "nlohmann/json_fwd.hpp" #include #include +#include #include +#include #include +#include namespace kubecontrol @@ -40,9 +45,9 @@ namespace kubecontrol { PodList_.emplace_back(Pod); LOG_S(INFO)<< "starting pod: "<performRequest(curlURL); - std::list headers; - headers.push_back(AuthString); - - curlpp::Easy request; - - WriterMemoryClass mWriterChunk; - curlpp::types::WriteFunctionFunctor functor = std::bind(&WriterMemoryClass::WriteMemoryCallback, &mWriterChunk, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3); - curlpp::options::WriteFunction *test = new curlpp::options::WriteFunction(functor); - request.setOpt(test); - request.setOpt(new curlpp::options::HttpHeader(headers)); - - request.setOpt(new curlpp::options::Url(curlURL)); - // request.setOpt(new curlpp::options::SslEngineDefault()); - // request.setOpt(new curlpp::options::CaPath("config/ca.crt")); - request.setOpt(new curlpp::options::SslVerifyPeer(false)); - - - // request.setOpt(new curlpp::options::Verbose(true)); - - - request.perform(); - auto response = mWriterChunk.getResponse(); + std::vector podsNames; auto j = nlohmann::json::parse(response); - return j.dump(); + + if (j.contains("items")) + { + int i = j["items"].size(); + for (int a = 0; aperformRequest(curlURL); + + j["items"].emplace_back(nlohmann::json::parse(response)); + } + + + return j.dump(); } std::string PodController::getInfoForPod(std::string Label) { + bool found = false; for (auto item : PodList_) { if (Label == item.getUUID()) { + found = true; + checkPodsHierarchy(); + item.PodInfo = *getPodInfo(item.getUUID()).get(); + LOG_S(INFO)<performRequest(curlURL); + return response; + } return nullptr; } + void PodController::checkPodsHierarchy() + { + auto response = this->getPodsInfo(); + + nlohmann::json j; + try + { + j = nlohmann::json::parse(response); + if (j.contains("items")) + { + int i = j["items"].size(); + for (int a = 0; a(j["items"][a].dump()); + // item->Uuid = j["items"][a]["metadata"]["labels"]["app.kubernetes.io/name"].get(); + // item->Component = j["items"][a]["metadata"]["labels"]["app.kubernetes.io/component"].get(); + // item->Image = j["items"][a]["spec"]["containers"][0]["image"].get(); + // item->Ip = j["items"][a]["status"]["podIP"].get(); + // item->Status = j["items"][a]["status"]["phase"].get(); + // item->PartOf = j["items"][a]["metadata"]["labels"]["app.kubernetes.io/part-of"].get(); + // // LOG_S(INFO)<podsInfoList_.push_back(std::move(item)); + } + + + i = j["items"].size(); + for (int a = 0; a(); + std::string uuid = j["items"][a]["metadata"]["labels"]["app.kubernetes.io/name"].get(); + std::string parentName= j["items"][a]["metadata"]["labels"]["app.kubernetes.io/part-of"].get(); + + auto self = this->getPodInfo(uuid); + auto parent = this->getPodInfo(parentName); + if (parent != nullptr && self != nullptr) { + parent->addRelatedPods(self->Uuid); + }else if (parent== nullptr) + { + self->PartOf = parentName; + } + + } + } + + + } catch (std::exception& e) + { + LOG_S(ERROR)<relatedPodsSize() != 0 ) + { + item = podsInfoList_[i]->ToJson().dump() +" Childs: "; + nlohmann::json tmp = podsInfoList_[i]->ToJson(); + auto vec = podsInfoList_[i]->getRelatedPods(); + for(int a = 0; a < vec.size();a++) + { + tmp["Childs"].push_back(getPodInfo(vec[a])->ToJson()); + item += getPodInfo(vec[a])->ToString() +" // "; + } + j.push_back(tmp); + } + } + + return j.dump(); + + } + + // void PodController::addPodInfoToInfoList(std::unique_ptr podinfo) + // { + + // } + std::shared_ptr PodController::getPodInfo(std::string uuid) + { + + for (int i = 0; i < podsInfoList_.size(); i++) { + if (podsInfoList_[i]->Uuid == uuid) + { + return podsInfoList_[i]; + } + } + return nullptr; + } + + + + std::string PodController::performRequest(std::string curlURL) + { + + std::string AuthString = "Authorization: Bearer " + BearerToken_; + + std::list headers; + headers.push_back(AuthString); + + auto request = std::make_unique(); + + WriterMemoryClass mWriterChunk; + curlpp::types::WriteFunctionFunctor functor = std::bind(&WriterMemoryClass::WriteMemoryCallback, &mWriterChunk, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3); + curlpp::options::WriteFunction *test = new curlpp::options::WriteFunction(functor); + request->setOpt(test); + + request->setOpt(new curlpp::options::HttpHeader(headers)); + + request->setOpt(new curlpp::options::Url(curlURL)); + // request.setOpt(new curlpp::options::SslEngineDefault()); + // request.setOpt(new curlpp::options::CaPath("config/ca.crt")); + request->setOpt(new curlpp::options::SslVerifyPeer(false)); + // request->setOpt(new curlpp::options::Verbose(true)); + + + request->perform(); + std::string response = mWriterChunk.getResponse(); + + return response; + } + + void PodController::performForceStopRequest(std::string uuid) + { + + } + + + } \ No newline at end of file diff --git a/src/kubecontrol/PodInfo.cpp b/src/kubecontrol/PodInfo.cpp new file mode 100644 index 0000000..efd1fcd --- /dev/null +++ b/src/kubecontrol/PodInfo.cpp @@ -0,0 +1,111 @@ + + +#include "nlohmann/json_fwd.hpp" +#include + + +namespace kubecontrol +{ + PodInfo::PodInfo() + { + Uuid = ""; + Component = ""; + Image = ""; + Ip = ""; + Status = ""; + PartOf = ""; + } + + PodInfo::PodInfo(std::string response) + { + update(response); + } + + + void PodInfo::update(std::string response) + { + + + nlohmann::json j; + try + { + j = nlohmann::json::parse(response); + + if (j.contains("items")) + { + + if (j["items"].size() == 1) { + Uuid = j["items"][0]["metadata"]["labels"]["app.kubernetes.io/name"].get(); + Component = j["items"][0]["metadata"]["labels"]["app.kubernetes.io/component"].get(); + Image = j["items"][0]["spec"]["containers"][0]["image"].get(); + Ip = j["items"][0]["status"]["podIP"].get(); + Status = j["items"][0]["status"]["phase"].get(); + PartOf = j["items"][0]["metadata"]["labels"]["app.kubernetes.io/part-of"].get(); + } + + }else + { + Uuid = j["metadata"]["labels"]["app.kubernetes.io/name"].get(); + Component = j["metadata"]["labels"]["app.kubernetes.io/component"].get(); + PartOf = j["metadata"]["labels"]["app.kubernetes.io/part-of"].get(); + Image = j["spec"]["containers"][0]["image"].get(); + + if (j["status"].contains("podIP")) Ip = j["status"]["podIP"].get(); + + Status = j["status"]["phase"].get(); + } + + + + + } catch (std::exception& e) + { + LOG_S(ERROR)< PodInfo::getRelatedPods() + { + return relatedPods; + } + + + std::string PodInfo::ToString() + { + + return "UUID: "+Uuid + " Compoment: " + Component + " Image: "+ Image+ " IP: " + Ip + " Status: "+Status + " Part Of: " +PartOf; + } + + nlohmann::json PodInfo::ToJson() + { + nlohmann::json j; + j["UUID"] = Uuid; + j["Compoment"] = Component; + j["Image"] = Image; + j["Ip"] = Ip; + j["Status"] = Status; + j["Part-Of"] = PartOf; + return j; + } + + + void PodInfo::addRelatedPods(std::string uuid) + { + if ( std::find(relatedPods.begin(), relatedPods.end(), uuid) == relatedPods.end() ) + { + relatedPods.emplace_back(uuid); + } + + } + + size_t PodInfo::relatedPodsSize() + { + return relatedPods.size(); + } + + + + + +} \ No newline at end of file