ADD: added podinfo with building a tree hierarchy for a pod

This commit is contained in:
Henry Winkel
2023-08-16 14:42:00 +02:00
parent 6c2f8f1eb6
commit 89465f06a5
8 changed files with 474 additions and 48 deletions

View File

@@ -63,6 +63,9 @@ ENDIF()
include/kubecontrol/Utils.hpp include/kubecontrol/Utils.hpp
src/kubecontrol/Utils.cpp src/kubecontrol/Utils.cpp
include/kubecontrol/PodInfo.hpp
src/kubecontrol/PodInfo.cpp
) )

View File

@@ -1,5 +1,6 @@
#pragma once #pragma once
#include "kubecontrol/PodInfo.hpp"
#include "nlohmann/json_fwd.hpp" #include "nlohmann/json_fwd.hpp"
#include "yaml-cpp/node/node.h" #include "yaml-cpp/node/node.h"
#include <map> #include <map>
@@ -19,6 +20,7 @@
#include <vector> #include <vector>
namespace kubecontrol namespace kubecontrol
{ {
class KubePod class KubePod
@@ -49,6 +51,8 @@ namespace kubecontrol
std::string stop(std::string apiAddress,std::string token); std::string stop(std::string apiAddress,std::string token);
std::string getInfo(std::string apiAddress,std::string token); std::string getInfo(std::string apiAddress,std::string token);
PodInfo PodInfo;
private: private:
@@ -69,5 +73,7 @@ namespace kubecontrol
std::string StopChilds(std::string apiAddress,std::string token,std::string uuid);
}; };
} }

View File

@@ -1,5 +1,9 @@
#pragma once #pragma once
#include "kubecontrol/PodInfo.hpp"
#include <kubecontrol/KubePod.hpp> #include <kubecontrol/KubePod.hpp>
#include <memory>
#include <string>
#include <vector>
namespace kubecontrol namespace kubecontrol
{ {
@@ -15,14 +19,28 @@ namespace kubecontrol
void stopAllPods(); void stopAllPods();
std::string getPodsInfo(); std::string getPodsInfo();
std::string getInfoForOwnPod();
std::string getInfoForPod(std::string Label); std::string getInfoForPod(std::string Label);
void checkPodsHierarchy();
std::string getPodsInfoForAll();
private: private:
std::vector<KubePod> PodList_; std::vector<KubePod> PodList_;
std::string performRequest(std::string url);
void performForceStopRequest(std::string uuid);
std::string BearerToken_; std::string BearerToken_;
std::string ServerAddress_; std::string ServerAddress_;
std::string ApiCall_; std::string ApiCall_;
// void addPodInfoToInfoList(std::shared_ptr<PodInfo> podinfo);
std::shared_ptr<PodInfo> getPodInfo(std::string uuid);
std::vector<std::shared_ptr<PodInfo>> podsInfoList_;
}; };
} // namespace ku } // namespace ku

View File

@@ -0,0 +1,66 @@
#pragma once
#include "nlohmann/json_fwd.hpp"
#include <memory>
#include <string>
#include <vector>
#include <nlohmann/json.hpp>
#include <string>
#include <loguru.hpp>
namespace kubecontrol {
class PodInfo
{
public:
PodInfo();
PodInfo(std::string response);
void update(std::string response);
std::string ToString();
nlohmann::json ToJson();
std::vector<std::string> 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<std::string> relatedPods;
};
// struct PodInfo
// {
// std::string Uuid;
// std::string Image;
// std::string Ip;
// std::string Component;
// std::string Status;
// std::string PartOf;
// std::vector<std::pair<std::string,std::shared_ptr<KubePod>>> relatedPods;
// bool operator==(PodInfo const &rhs )
// {
// if (Uuid == rhs.Uuid) {
// return true;
// }
// return false;
// }
// };
}

View File

@@ -1,5 +1,6 @@
#pragma once #pragma once
#include <kubecontrol/KubePod.hpp>
#include <string> #include <string>
#include <algorithm> #include <algorithm>
@@ -12,4 +13,10 @@ namespace kubecontrol
static std::string to_lower(std::string); static std::string to_lower(std::string);
}; };
} }

View File

@@ -6,6 +6,7 @@
#include <kubecontrol/KubePod.hpp> #include <kubecontrol/KubePod.hpp>
#include <sstream> #include <sstream>
#include <string> #include <string>
#include <thread>
namespace kubecontrol namespace kubecontrol
@@ -166,7 +167,7 @@ namespace kubecontrol
node["spec"]["containers"][0]["command"].push_back(PodCommand_); node["spec"]["containers"][0]["command"].push_back(PodCommand_);
} }
node["spec"]["terminationGracePeriodSeconds"] = 3;
node["spec"]["restartPolicy"] = "Never"; node["spec"]["restartPolicy"] = "Never";
@@ -209,23 +210,10 @@ namespace kubecontrol
request.setOpt(new curlpp::options::CustomRequest("POST")); request.setOpt(new curlpp::options::CustomRequest("POST"));
// request.setOpt(new curlpp::options::Verbose("POST")); // request.setOpt(new curlpp::options::Verbose("POST"));
this->createYAML(); this->createYAML();
LOG_S(ERROR)<< this->PathToYaml_; 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; std::stringstream stream;
stream << YAMLNode_; stream << YAMLNode_;
// request.setOpt(new curlpp::options::PostFields(buffer)); // request.setOpt(new curlpp::options::PostFields(buffer));
@@ -236,7 +224,16 @@ namespace kubecontrol
request.reset(); request.reset();
auto response = mWriterChunk.getResponse(); 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) std::string KubePod::stop(std::string apiAddress,std::string token)
@@ -269,12 +266,61 @@ namespace kubecontrol
request.perform(); request.perform();
auto response = mWriterChunk.getResponse(); auto response = mWriterChunk.getResponse();
return nlohmann::json::parse(response).dump();
LOG_S(INFO)<<PodInfo.getRelatedPods().size();
if (PodInfo.getRelatedPods().size() > 0)
{
for(int i = 0; i<PodInfo.getRelatedPods().size(); i++)
{
StopChilds(apiAddress, token, PodInfo.getRelatedPods()[i]);
} }
}
return response;
}
std::string KubePod::StopChilds(std::string apiAddress,std::string token,std::string uuid)
{
std::string curlURL = apiAddress+ uuid;
std::string AuthString = "Authorization: Bearer " + token;
std::list<std::string> 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 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::string AuthString = "Authorization: Bearer " + token;
std::list<std::string> headers; std::list<std::string> headers;
@@ -300,7 +346,7 @@ namespace kubecontrol
request.perform(); request.perform();
auto response = mWriterChunk.getResponse(); auto response = mWriterChunk.getResponse();
return nlohmann::json::parse(response).dump(); return response;
} }

View File

@@ -1,8 +1,13 @@
#include "kubecontrol/PodInfo.hpp"
#include "nlohmann/json_fwd.hpp"
#include <cstddef> #include <cstddef>
#include <cstdlib> #include <cstdlib>
#include <exception>
#include <kubecontrol/PodController.hpp> #include <kubecontrol/PodController.hpp>
#include <memory>
#include <string> #include <string>
#include <vector>
namespace kubecontrol namespace kubecontrol
@@ -40,9 +45,9 @@ namespace kubecontrol
{ {
PodList_.emplace_back(Pod); PodList_.emplace_back(Pod);
LOG_S(INFO)<< "starting pod: "<<Pod.getUUID(); LOG_S(INFO)<< "starting pod: "<<Pod.getUUID();
auto response = Pod.start(ServerAddress_+ApiCall_, BearerToken_);
LOG_S(INFO)<<Pod.start(ServerAddress_+ApiCall_, BearerToken_); // LOG_S(INFO)<<response;
} }
void PodController::stopPod(std::string Label) void PodController::stopPod(std::string Label)
@@ -59,59 +64,223 @@ namespace kubecontrol
void PodController::stopAllPods() void PodController::stopAllPods()
{ {
checkPodsHierarchy();
for (auto item : PodList_) for (auto item : PodList_)
{ {
item.PodInfo = *getPodInfo(item.getUUID()).get();
item.stop(ServerAddress_+ApiCall_, BearerToken_); item.stop(ServerAddress_+ApiCall_, BearerToken_);
LOG_S(INFO)<< "stopping pod: "<<item.getUUID(); LOG_S(INFO)<< "stopping pod: "<<item.getUUID();
} }
} }
std::string PodController::getInfoForOwnPod()
{
std::string response = "";
for (auto item : PodList_)
{
response = item.getInfo(ServerAddress_+ApiCall_, BearerToken_);
}
return response;
}
std::string PodController::getPodsInfo( ) std::string PodController::getPodsInfo( )
{ {
std::string curlURL = ServerAddress_+ApiCall_; std::string curlURL = ServerAddress_+ApiCall_;
std::string AuthString = "Authorization: Bearer " + BearerToken_;
std::list<std::string> headers; auto response = this->performRequest(curlURL);
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)); std::vector<std::string> podsNames;
request.perform();
auto response = mWriterChunk.getResponse();
auto j = nlohmann::json::parse(response); auto j = nlohmann::json::parse(response);
if (j.contains("items"))
{
int i = j["items"].size();
for (int a = 0; a<i; a++)
{
if (!j["items"][a]["metadata"]["name"].empty())
{
podsNames.emplace_back(j["items"][a]["metadata"]["name"]);
}
}
}
j.clear();
for (auto item: podsNames)
{
std::string curlURL = ServerAddress_+ApiCall_+item+"/status";
auto response = this->performRequest(curlURL);
j["items"].emplace_back(nlohmann::json::parse(response));
}
return j.dump(); return j.dump();
} }
std::string PodController::getInfoForPod(std::string Label) std::string PodController::getInfoForPod(std::string Label)
{ {
bool found = false;
for (auto item : PodList_) for (auto item : PodList_)
{ {
if (Label == item.getUUID()) if (Label == item.getUUID())
{ {
found = true;
checkPodsHierarchy();
item.PodInfo = *getPodInfo(item.getUUID()).get();
LOG_S(INFO)<<item.PodInfo.getRelatedPods().size();
return item.getInfo(ServerAddress_+ApiCall_, BearerToken_); return item.getInfo(ServerAddress_+ApiCall_, BearerToken_);
}
}
if (found == false)
{
std::string curlURL = ServerAddress_+ApiCall_+Label;
auto response = this->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<i; a++)
{
auto item = std::make_shared<PodInfo>(j["items"][a].dump());
// item->Uuid = j["items"][a]["metadata"]["labels"]["app.kubernetes.io/name"].get<std::string>();
// item->Component = j["items"][a]["metadata"]["labels"]["app.kubernetes.io/component"].get<std::string>();
// item->Image = j["items"][a]["spec"]["containers"][0]["image"].get<std::string>();
// item->Ip = j["items"][a]["status"]["podIP"].get<std::string>();
// item->Status = j["items"][a]["status"]["phase"].get<std::string>();
// item->PartOf = j["items"][a]["metadata"]["labels"]["app.kubernetes.io/part-of"].get<std::string>();
// // LOG_S(INFO)<<j["items"][a]["status"]["podIP"];
// LOG_S(INFO)<<j["items"][a]["status"]["phase"];
this->podsInfoList_.push_back(std::move(item));
}
i = j["items"].size();
for (int a = 0; a<i; a++)
{
auto item = std::make_shared<PodInfo>();
std::string uuid = j["items"][a]["metadata"]["labels"]["app.kubernetes.io/name"].get<std::string>();
std::string parentName= j["items"][a]["metadata"]["labels"]["app.kubernetes.io/part-of"].get<std::string>();
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)<<e.what();
}
}
std::string PodController::getPodsInfoForAll()
{
checkPodsHierarchy();
std::string item = "";
nlohmann::json j;
for (int i = 0; i < podsInfoList_.size(); i++) {
if(podsInfoList_[i]->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> podinfo)
// {
// }
std::shared_ptr<PodInfo> PodController::getPodInfo(std::string uuid)
{
for (int i = 0; i < podsInfoList_.size(); i++) {
if (podsInfoList_[i]->Uuid == uuid)
{
return podsInfoList_[i];
} }
} }
return nullptr; return nullptr;
} }
std::string PodController::performRequest(std::string curlURL)
{
std::string AuthString = "Authorization: Bearer " + BearerToken_;
std::list<std::string> headers;
headers.push_back(AuthString);
auto request = std::make_unique<curlpp::Easy>();
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)
{
}
} }

111
src/kubecontrol/PodInfo.cpp Normal file
View File

@@ -0,0 +1,111 @@
#include "nlohmann/json_fwd.hpp"
#include <kubecontrol/PodInfo.hpp>
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<std::string>();
Component = j["items"][0]["metadata"]["labels"]["app.kubernetes.io/component"].get<std::string>();
Image = j["items"][0]["spec"]["containers"][0]["image"].get<std::string>();
Ip = j["items"][0]["status"]["podIP"].get<std::string>();
Status = j["items"][0]["status"]["phase"].get<std::string>();
PartOf = j["items"][0]["metadata"]["labels"]["app.kubernetes.io/part-of"].get<std::string>();
}
}else
{
Uuid = j["metadata"]["labels"]["app.kubernetes.io/name"].get<std::string>();
Component = j["metadata"]["labels"]["app.kubernetes.io/component"].get<std::string>();
PartOf = j["metadata"]["labels"]["app.kubernetes.io/part-of"].get<std::string>();
Image = j["spec"]["containers"][0]["image"].get<std::string>();
if (j["status"].contains("podIP")) Ip = j["status"]["podIP"].get<std::string>();
Status = j["status"]["phase"].get<std::string>();
}
} catch (std::exception& e)
{
LOG_S(ERROR)<<e.what();
}
}
std::vector<std::string> 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();
}
}