420 lines
11 KiB
C++
420 lines
11 KiB
C++
|
|
#include <kubecontrol/KubePod.hpp>
|
|
#include "curlpp/Options.hpp"
|
|
#include "kubecontrol/Container.hpp"
|
|
#include "kubecontrol/Utils.hpp"
|
|
#include "nlohmann/json_fwd.hpp"
|
|
#include "yaml-cpp/binary.h"
|
|
#include <cctype>
|
|
#include <exception>
|
|
#include <fstream>
|
|
#include <future>
|
|
#include <iterator>
|
|
#include <map>
|
|
#include <memory>
|
|
#include <sstream>
|
|
#include <string>
|
|
#include <thread>
|
|
|
|
|
|
|
|
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<std::string, std::string>();
|
|
|
|
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<std::string, std::string>();
|
|
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<std::string, std::string>();
|
|
|
|
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<std::string, std::string>();
|
|
|
|
addContainer(Uuid, ContainerImage,map);
|
|
|
|
}
|
|
|
|
|
|
|
|
void KubePod::addContainer(std::string name,std::string image, std::map<std::string, std::string> &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<std::string, std::string> 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<std::string, std::string> 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<std::string> 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: " <<Uuid_;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
int KubePod::stopChilds(KubernetesAPI APIInterface)
|
|
{
|
|
auto uuids = this->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<PodChild> 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<std::string>();
|
|
this->Status_ = j["status"]["phase"].get<std::string>();
|
|
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)<<i;
|
|
PodChild child;
|
|
child.UUID =i["metadata"]["name"].get<std::string>();
|
|
child.IP = i["status"]["podIP"].get<std::string>();
|
|
child.Status = i["status"]["phase"].get<std::string>();
|
|
child.Component = i["metadata"]["labels"]["app.kubernetes.io/component"].get<std::string>();
|
|
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)<<j;
|
|
return 1;
|
|
|
|
}
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|