ADD: added central kubernetes api class

This commit is contained in:
Henry Winkel
2023-12-21 17:15:28 +01:00
parent d1024de907
commit 351cf9ec69
12 changed files with 514 additions and 128 deletions

View File

@@ -1,6 +1,9 @@
#include "curlpp/Options.hpp"
#include "kubecontrol/PodInfo.hpp"
#include "kubecontrol/Utils.hpp"
#include "nlohmann/json_fwd.hpp"
#include "yaml-cpp/binary.h"
#include <exception>
#include <fstream>
#include <iterator>
#include <kubecontrol/KubePod.hpp>
@@ -170,7 +173,7 @@ namespace kubecontrol
node["spec"]["containers"][0]["command"].push_back(PodCommand_);
}
node["spec"]["terminationGracePeriodSeconds"] = 3;
node["spec"]["terminationGracePeriodSeconds"] = 10;
node["spec"]["restartPolicy"] = "Never";
@@ -185,62 +188,43 @@ namespace kubecontrol
}
std::string KubePod::start(std::string apiAddress,std::string token)
std::string KubePod::start(KubernetesAPI APIInterface,bool WaitTillRunning)
{
std::string curlURL = apiAddress;
std::string AuthString = "Authorization: Bearer " + token;
std::list<std::string> headers;
headers.push_back(AuthString);
headers.push_back("Content-Type: application/yaml");
curlpp::Cleanup cleaner;
curlpp::Easy request;
std::stringstream result;
request.setOpt(cURLpp::Options::WriteStream(&result));
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::Post(true));
request.setOpt(new curlpp::options::CustomRequest("POST"));
// request.setOpt(new curlpp::options::Verbose("POST"));
std::string request = "/api/v1/namespaces/simulator/pods/";
this->createYAML();
LOG_S(INFO)<< this->PathToYaml_;
// LOG_S(INFO)<< this->PathToYaml_;
std::stringstream stream;
stream << YAMLNode_;
// request.setOpt(new curlpp::options::PostFields(buffer));
request.setOpt(new curlpp::options::PostFields(stream.str()));
std::string response = APIInterface.performRequest(request,"POST",stream.str());
request.perform();
request.reset();
std::string response = result.str();
InfoPod.update(response);
while (InfoPod.Status != "Running" && InfoPod.Status != "Succeeded") {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
response = this->getInfo(curlURL, token);
InfoPod.update(response);
}
if (WaitTillRunning == true) {
return response;
while (InfoPod.Status != "Running" && InfoPod.Status != "Succeeded") {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
response = this->getInfoForThisPod(APIInterface);
InfoPod.update(response);
}
}
return response;
}
std::string KubePod::stop(std::string apiAddress,std::string token)
{
std::string curlURL = apiAddress+ this->Uuid_;
LOG_S(INFO)<<curlURL;
std::string AuthString = "Authorization: Bearer " + token;
std::list<std::string> headers;
@@ -267,12 +251,20 @@ namespace kubecontrol
request.perform();
auto response = result.str();
LOG_S(INFO)<<InfoPod.getRelatedPods().size();
// std::this_thread::sleep_for(std::chrono::milliseconds(5000));
// InfoPod.update(this->getInfo(apiAddress, token));
LOG_S(INFO)<<"Related pods: " <<InfoPod.getRelatedPods().size();
if (InfoPod.getRelatedPods().size() > 0)
{
for(int i = 0; i<InfoPod.getRelatedPods().size(); i++)
{
StopChilds(apiAddress, token, InfoPod.getRelatedPods()[i]);
StopChilds(apiAddress, token, InfoPod.getRelatedPods()[i]);
}
}
@@ -281,6 +273,19 @@ namespace kubecontrol
return response;
}
std::string KubePod::stop(KubernetesAPI APIInterface)
{
std::string request = "/api/v1/namespaces/simulator/pods/"+Uuid_;
std::string result = APIInterface.performRequest(request,"DELETE");
this->getInfoForRelatedPods(APIInterface);
return result;
}
std::string KubePod::StopChilds(std::string apiAddress,std::string token,std::string uuid)
{
std::string curlURL = apiAddress+ uuid;
@@ -316,34 +321,88 @@ namespace kubecontrol
std::string KubePod::getInfo(std::string apiAddress,std::string token)
{
std::string curlURL = apiAddress+Uuid_+"/"+"status";
std::string AuthString = "Authorization: Bearer " + token;
std::list<std::string> headers;
headers.push_back(AuthString);
// std::string KubePod::getInfo(std::string apiAddress,std::string token)
// {
// std::string curlURL = apiAddress+Uuid_+"/"+"status";
// std::string AuthString = "Authorization: Bearer " + token;
// std::list<std::string> headers;
// headers.push_back(AuthString);
curlpp::Cleanup cleaner;
curlpp::Easy request;
// curlpp::Cleanup cleaner;
// curlpp::Easy request;
std::stringstream result;
request.setOpt(cURLpp::Options::WriteStream(&result));
// std::stringstream result;
// request.setOpt(cURLpp::Options::WriteStream(&result));
request.setOpt(new curlpp::options::HttpHeader(headers));
// request.setOpt(new curlpp::options::HttpHeader(headers));
request.setOpt(new curlpp::options::Url(curlURL));
// request.setOpt(new curlpp::options::Url(curlURL));
request.setOpt(new curlpp::options::SslVerifyPeer(false));
// request.setOpt(new curlpp::options::SslVerifyPeer(false));
request.perform();
return result.str();
// request.perform();
// return result.str();
// }
std::string KubePod::getInfoForThisPod(KubernetesAPI APIInterface)
{
std::string request = "/api/v1/namespaces/simulator/pods/"+Uuid_+"/status";
std::string result = APIInterface.performRequest(request,"GET");
return result;
}
std::string KubePod::getInfoForRelatedPods( KubernetesAPI APIInterface)
{
// std::string curlURL = apiAddress+"?labelSelector=app.kubernetes.io/part-of="+Uuid_;
std::string request = "/api/v1/namespaces/simulator/pods?labelSelector=app.kubernetes.io/part-of="+Uuid_;
std::string result = APIInterface.performRequest(request,"GET");
return result;
}
std::vector<std::string> KubePod::getUUIDForRelatedPods(KubernetesAPI APIInterface)
{
std::vector<std::string> uuids;
auto rawResponse = getInfoForRelatedPods(APIInterface);
if (rawResponse == "")
{
return uuids;
}
try {
nlohmann::json j = nlohmann::json::parse(rawResponse);
if (j.contains("items") && j["items"].is_array())
{
for (auto i : j["items"])
{
uuids.push_back(i["metadata"]["name"].get<std::string>());
}
}
} catch (const std::exception e) {
LOG_S(ERROR)<< "Exeption in getUUIDForRelatedPods() :" << e.what();
}
// LOG_S(INFO)<<rawResponse;
return uuids;
}
}

View File

@@ -0,0 +1,142 @@
#include <curlpp/Easy.hpp>
#include <curlpp/cURLpp.hpp>
#include <exception>
#include <kubecontrol/KubernetesAPI.hpp>
#include <list>
#include <curlpp/Options.hpp>
#include <sstream>
#include <loguru.hpp>
namespace kubecontrol {
KubernetesAPI::KubernetesAPI()
{
}
KubernetesAPI::KubernetesAPI(YAML::Node config)
{
addYaml(config);
}
KubernetesAPI::KubernetesAPI(std::string APIAddress, std::string Token)
:APIAddress_(APIAddress), Token_(Token)
{
}
void KubernetesAPI::addAddress(std::string address)
{
APIAddress_ = address;
}
void KubernetesAPI::addToken(std::string token)
{
Token_ = token;
}
void KubernetesAPI::addYaml(YAML::Node config)
{
try {
Token_ = config["users"][0]["user"]["token"].as<std::string>();
Namespace_ = config["contexts"][0]["context"]["namespace"].as<std::string>();
char * KUBERNETES_SERVICE_HOST = std::getenv("KUBERNETES_SERVICE_HOST");
char * KUBERNETES_SERVICE_PORT = std::getenv("KUBERNETES_SERVICE_PORT");
if (KUBERNETES_SERVICE_HOST != nullptr && KUBERNETES_SERVICE_PORT!= nullptr)
{
APIAddress_ = "https://" +std::string(KUBERNETES_SERVICE_HOST)+":"+std::string(KUBERNETES_SERVICE_PORT);
} else
{
LOG_S(INFO)<<"Taking Serveraddress out of the provided YAML file";
APIAddress_ = config["clusters"][0]["cluster"]["server"].as<std::string>();
}
} catch (std::exception& e) {
LOG_S(ERROR)<< e.what();
throw e.what();
}
}
std::string KubernetesAPI::performRequest(std::string request,std::string Methode )
{
std::stringstream result;
std::string curlURL = APIAddress_+request;
std::string AuthString = "Authorization: Bearer " + Token_;
std::list<std::string> headers;
headers.push_back(AuthString);
curlpp::Cleanup cleaner;
curlpp::Easy curlRequest;
curlRequest.setOpt(cURLpp::Options::WriteStream(&result));
curlRequest.setOpt(new curlpp::options::HttpHeader(headers));
curlRequest.setOpt(new curlpp::options::Url(curlURL));
curlRequest.setOpt(new curlpp::options::SslVerifyPeer(false));
curlRequest.setOpt(new curlpp::options::CustomRequest(Methode));
try {
curlRequest.perform();
} catch (const std::exception e) {
LOG_S(ERROR)<<e.what();
}
curlRequest.reset();
return result.str();
}
std::string KubernetesAPI::performRequest(std::string request,std::string Methode,std::string PostFields)
{
std::string curlURL = APIAddress_+request;;
std::string AuthString = "Authorization: Bearer " + Token_;
std::list<std::string> headers;
headers.push_back(AuthString);
headers.push_back("Content-Type: application/yaml");
curlpp::Cleanup cleaner;
curlpp::Easy curlRequest;
std::stringstream result;
curlRequest.setOpt(cURLpp::Options::WriteStream(&result));
curlRequest.setOpt(new curlpp::options::HttpHeader(headers));
curlRequest.setOpt(new curlpp::options::Url(curlURL));
curlRequest.setOpt(new curlpp::options::SslVerifyPeer(false));
curlRequest.setOpt(new curlpp::options::CustomRequest("POST"));
curlRequest.setOpt(new curlpp::options::PostFields(PostFields));
curlRequest.perform();
curlRequest.reset();
return result.str();
}
}

View File

@@ -1,5 +1,7 @@
#include "curlpp/Options.hpp"
#include "kubecontrol/KubePod.hpp"
#include "kubecontrol/KubernetesAPI.hpp"
#include "kubecontrol/PodInfo.hpp"
#include "nlohmann/json_fwd.hpp"
#include <cstddef>
@@ -8,13 +10,15 @@
#include <kubecontrol/PodController.hpp>
#include <math.h>
#include <memory>
#include <mutex>
#include <string>
#include <vector>
namespace kubecontrol
{
PodController::PodController(std::string pathToKubectlConfig)
PodController::PodController(std::string pathToKubectlConfig):
APIInterface_( YAML::LoadFile(pathToKubectlConfig))
{
LOG_S(INFO)<< "Path To Yaml: " <<pathToKubectlConfig;
@@ -37,10 +41,11 @@ namespace kubecontrol
ServerAddress_ = config["clusters"][0]["cluster"]["server"].as<std::string>();
}
ApiCall_ = "/api/v1/namespaces/"+Namespace_+"/pods/";
} catch (std::exception& e) {
LOG_S(ERROR)<< e.what();
throw e.what();
LOG_S(ERROR)<< e.what();
throw e.what();
}
}
@@ -51,22 +56,32 @@ namespace kubecontrol
void PodController::startPod(KubePod Pod)
void PodController::startPod(KubePod Pod,bool WaitTillRunning )
{
PodList_.emplace_back(Pod);
LOG_S(INFO)<< "starting pod: "<<Pod.getUUID();
auto response = Pod.start(ServerAddress_+ApiCall_, BearerToken_);
LOG_S(INFO)<< "starting pod: "<<Pod.getUUID();
// auto response = Pod.start(ServerAddress_+ApiCall_, BearerToken_,WaitTillRunning);
auto response = Pod.start(APIInterface_,WaitTillRunning);
std::lock_guard<std::mutex>lock(mx_);
PodList_.emplace_back(Pod);
// LOG_S(INFO)<<response;
}
void PodController::stopPod(std::string Label)
{
for (auto item : PodList_)
std::lock_guard<std::mutex>lock(mx_);
// PodList_
for (std::vector<KubePod>::iterator it = PodList_.begin(); it != PodList_.end();)
{
if (Label == item.getUUID())
if (Label == it->getUUID())
{
item.stop(ServerAddress_+ApiCall_, BearerToken_);
it->stop(APIInterface_);
it = PodList_.erase(it);
}
else
{
it++;
}
}
@@ -74,30 +89,34 @@ namespace kubecontrol
void PodController::stopAllPods()
{
std::lock_guard<std::mutex>lock(mx_);
checkPodsHierarchy();
for (auto item : PodList_)
{
LOG_S(INFO)<<item.InfoPod.Uuid;
item.InfoPod = *getPodInfo(item.getUUID()).get();
item.stop(ServerAddress_+ApiCall_, BearerToken_);
item.InfoPod = *getPodInfo(item.getUUID()).get();
item.stop(APIInterface_);
LOG_S(INFO)<< "stopping pod: "<<item.getUUID();
}
}
std::string PodController::getInfoForOwnPod()
{
std::string response = "";
for (auto item : PodList_)
{
// std::string PodController::getInfoForOwnPod()
// {
// std::string response = "";
// for (auto item : PodList_)
// {
response = item.getInfo(ServerAddress_+ApiCall_, BearerToken_);
}
// response = item.getInfoForThisPod(APIInterface_);
// }
return response;
}
// return response;
// }
std::string PodController::getPodsInfo()
std::string PodController::getInfoForAllPods()
{
std::string curlURL = ServerAddress_+ApiCall_;
@@ -155,11 +174,13 @@ namespace kubecontrol
if (uid == item.getUUID())
{
found = true;
checkPodsHierarchy();
// checkPodsHierarchy();
item.InfoPod = *getPodInfo(item.getUUID()).get();
// LOG_S(INFO)<<item.InfoPod.getRelatedPods().size();
item.getInfoForRelatedPods(APIInterface_);
return item.getInfo(ServerAddress_+ApiCall_, BearerToken_);
// return item.getInfo(ServerAddress_+ApiCall_, BearerToken_);
return item.getInfoForThisPod(APIInterface_);
}
}
@@ -175,7 +196,7 @@ namespace kubecontrol
void PodController::checkPodsHierarchy()
{
auto response = this->getPodsInfo();
auto response = this->getInfoForAllPods();
nlohmann::json j;
try

View File

@@ -84,6 +84,11 @@ namespace kubecontrol
j["Ip"] = Ip;
j["Status"] = Status;
j["Part-Of"] = PartOf;
j["Related-Pods"] ;
for (auto i : this->relatedPods ) {
j["Related-Pods"].push_back(i);
}
return j;
}