Commit 949da595 by Fukász Rómeó Ervin

Initial commit: first iteration of the occi client lib.

parents
CPP=g++
CC=gcc
CFLAGS=-fPIC -Ofast
CPPFLAGS=-fPIC --std=c++11 -Ofast
LDFLAGS=--shared
LIBS=-lrestclient-cpp
SONAME=_occi.so
SOURCES=occilib.cpp
SWIG=swig
SWIG_INTERFACES=occilib.i
WRAPPER_SOURCES=occilib_wrap.cxx
WRAPPER_INCLUDES=`pkg-config python --cflags`
default: test
compile:
$(CPP) $(CPPFLAGS) -c $(SOURCES)
test: compile
$(CPP) $(CPPFLAGS) -o test test.cpp *.o $(LIBS)
python:
$(SWIG) -python -c++ $(SWIG_INTERFACES)
$(CPP) $(CPPFLAGS) -c $(WRAPPER_SOURCES) $(WRAPPER_INCLUDES)
$(CPP) $(LDFLAGS) -o $(SONAME) occilib_wrap.o $(LIBS)
clean:
rm -f *.o
rm -f $(WRAPPER_SOURCES)
mrproper: clean
rm -f occi.py occi.pyc
rm -f _occi.so
// Copyright 2017 Budapest University of Technology and Economics (BME IK)
//
// This file is part of CIRCLE Cloud.
//
// CIRCLE is free software: you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// CIRCLE is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
// details.
//
// You should have received a copy of the GNU General Public License along
// with CIRCLE. If not, see <http://www.gnu.org/licenses/>.
#ifndef OCCILIB_COMPUTE_H_
#define OCCILIB_COMPUTE_H_
#include <string>
#include "json.hpp"
#include "resource.h"
#include "template.h"
#include <iostream>
namespace OcciClient {
using std::string;
class Compute : public Resource {
private:
string state;
string stateMessage;
double memory;
int cpuShare;
int cores;
string hostname;
string architecture;
string credentialProtocol;
int credentialPort;
string credentialHost;
string credentialPassword;
string credentialUsername;
string credentialCommand;
void parseJsonInstance(nlohmann::json instance) {
Resource::parseJsonInstance(instance);
this->state = getAttributeFromRendering<string>(instance, "occi.compute.state");
this->stateMessage = getAttributeFromRendering<string>(instance, "occi.compute.state.message");
this->memory = getAttributeFromRendering<double>(instance, "occi.compute.memory");
this->cpuShare = getAttributeFromRendering<int>(instance, "occi.compute.share");
this->cores = getAttributeFromRendering<int>(instance, "occi.compute.cores");
this->hostname = getAttributeFromRendering<string>(instance, "occi.compute.hostname");
this->architecture = getAttributeFromRendering<string>(instance, "occi.compute.architecture");
this->credentialProtocol = getAttributeFromRendering<string>(instance, "org.circlecloud.occi.credentials.protocol");
this->credentialPort = getAttributeFromRendering<int>(instance, "org.circlecloud.occi.credentials.port");
this->credentialHost = getAttributeFromRendering<string>(instance, "org.circlecloud.occi.credentials.host");
this->credentialUsername = getAttributeFromRendering<string>(instance, "org.circlecloud.occi.credentials.username");
this->credentialPassword = getAttributeFromRendering<string>(instance, "org.circlecloud.occi.credentials.password");
this->credentialCommand = getAttributeFromRendering<string>(instance, "org.circlecloud.occi.credentials.command");
this->rendering = instance;
}
Compute(OcciSession* session, nlohmann::json instance)
: Resource(session, "compute", instance) {
parseJsonInstance(instance);
}
public:
static std::shared_ptr<Compute> getComputeInstance(OcciSession* session, string id) {
auto uri = "compute/" + id + "/";
auto instance = session->get(uri);
return std::make_shared<Compute>(Compute(session, instance));
}
static std::shared_ptr<Compute> createComputeInstance(OcciSession* session, Template t) {
auto uri = "compute/1/";
nlohmann::json data = nlohmann::json::parse("{\"mixins\": [\"" + t + "\"]}");
auto instance = session->put(uri, data);
return std::make_shared<Compute>(Compute(session, instance));
}
string getState(){
return this->state;
}
string getStateMessage(){
return this->stateMessage;
}
double getMemory(){
return this->memory;
}
int getCpuShare(){
return this->cpuShare;
}
int getCores(){
return this->cores;
}
string getHostname(){
return this->hostname;
}
string getArchitecture(){
return this->architecture;
}
string getCredentialProtocol(){
return this->credentialProtocol;
}
int getCredentialPort(){
return this->credentialPort;
}
string getCredentialHost(){
return this->credentialHost;
}
string getCredentialPassword(){
return this->credentialPassword;
}
string getCredentialUsername(){
return this->credentialUsername;
}
string getCredentialCommand(){
return this->credentialCommand;
}
void invokeAction(nlohmann::json actionData) {
auto inst = Resource::invokeAction(actionData);
parseJsonInstance(inst);
}
void start() {
nlohmann::json actionData = {
{"action", "http://schemas.ogf.org/occi/infrastructure/compute/action#start"}
};
invokeAction(actionData);
}
void wakeup() {
start();
}
void sleep() {
nlohmann::json actionData = {
{"action", "http://schemas.ogf.org/occi/infrastructure/compute/action#suspend"},
{"attributes", {
{"method", "suspend"}
}}
};
invokeAction(actionData);
}
void reboot() {
nlohmann::json actionData = {
{"action", "http://schemas.ogf.org/occi/infrastructure/compute/action#restart"},
{"attributes", {
{"method", "warm"}
}}
};
invokeAction(actionData);
}
void reset() {
nlohmann::json actionData = {
{"action", "http://schemas.ogf.org/occi/infrastructure/compute/action#restart"},
{"attributes", {
{"method", "cold"}
}}
};
invokeAction(actionData);
}
void shutdown() {
nlohmann::json actionData = {
{"action", "http://schemas.ogf.org/occi/infrastructure/compute/action#stop"},
{"attributes", {
{"method", "acpioff"}
}}
};
invokeAction(actionData);
}
void shutoff() {
nlohmann::json actionData = {
{"action", "http://schemas.ogf.org/occi/infrastructure/compute/action#stop"},
{"attributes", {
{"method", "poweroff"}
}}
};
invokeAction(actionData);
}
};
}
#endif // OCCILIB_COMPUTE_H
This source diff could not be displayed because it is too large. You can view the blob instead.
#include "occilib.h"
// Copyright 2017 Budapest University of Technology and Economics (BME IK)
//
// This file is part of CIRCLE Cloud.
//
// CIRCLE is free software: you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// CIRCLE is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
// details.
//
// You should have received a copy of the GNU General Public License along
// with CIRCLE. If not, see <http://www.gnu.org/licenses/>.
#ifndef OCCILIB_H_
#define OCCILIB_H_
#include "occisession.h"
#include "resource.h"
#include "compute.h"
#include "template.h"
namespace OcciClient {
class OcciSession;
class Resource;
class Compute;
}
#endif // OCCILIB_H_
%module occi
%{
/* Includes the header in the wrapper code */
#include "occisession.h"
#include "resource.h"
#include "compute.h"
#include "template.h"
%}
/* Parse the header file to generate wrappers */
%include "std_string.i"
%include "std_vector.i"
%include "std_shared_ptr.i"
// a del python kulcsszo ezert warningot kapunk a generalaskor
// az OcciSession::del() metodusa amugy sem tartozik a
// publikus interfeszhez
%ignore OcciClient::OcciSession::del;
%shared_ptr(OcciClient::Resource)
%shared_ptr(OcciClient::Compute)
%newobject nlohmann::json;
%include "occisession.h"
%include "resource.h"
%include "compute.h"
%include "template.h"
namespace std {
%template(TemplateVector) vector<Template>;
}
// Copyright 2017 Budapest University of Technology and Economics (BME IK)
//
// This file is part of CIRCLE Cloud.
//
// CIRCLE is free software: you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// CIRCLE is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
// details.
//
// You should have received a copy of the GNU General Public License along
// with CIRCLE. If not, see <http://www.gnu.org/licenses/>.
#ifndef OCCILIB_SESSION_H_
#define OCCILIB_SESSION_H_
#include <string>
#include <exception>
#include <stdexcept>
#include "restclient-cpp/connection.h"
#include "restclient-cpp/restclient.h"
#include "json.hpp"
namespace OcciClient {
// using nlohmann::json;
using std::string;
enum class RequestType{Get, Post, Delete, Put};
class OcciSession {
private:
RestClient::Connection* connection = nullptr;
bool csrftokenRequired = false;
string csrfuri;
void setCsrfTokenHeader(){
auto resp = this->connection->getLastResponse();
string csrftoken;
try {
csrftoken = resp.cookies.at("csrftoken");
}
catch (const std::out_of_range& e) {
return;
}
this->connection->AppendHeader("X-CSRFToken", csrftoken);
}
public:
OcciSession(const char* url, bool insecure = false, bool csrf = false){
RestClient::init();
this->connection = new RestClient::Connection(url);
if (insecure) {
this->connection->SetHostVerify(false);
this->connection->SetPeerVerify(false);
}
this->csrftokenRequired = csrf;
RestClient::HeaderFields headers;
headers["Accept"] = "application/json";
headers["Content-type"] = "application/json";
headers["Referer"] = url;
this->connection->SetHeaders(headers);
}
~OcciSession(){
RestClient::disable();
}
nlohmann::json doRequest(string uri, RequestType type, nlohmann::json body = nullptr){
RestClient::Response r;
if (this->csrftokenRequired)
this->setCsrfTokenHeader();
if (type == RequestType::Post)
r = connection->post(uri, body.dump());
else if (type == RequestType::Put)
r = connection->put(uri, body.dump());
else if (type == RequestType::Delete)
r = connection->del(uri);
else
r = connection->get(uri);
nlohmann::json result;
try {
result = nlohmann::json::parse(r.body);
}
catch (std::invalid_argument& e) {
result = "{}"_json;
throw std::domain_error("Didn't get a nlohmann::json response from the OCCI server.");
}
try {
throw std::logic_error(result["error"].get<string>());
}
catch (std::domain_error e) {
return result;
}
return result;
}
nlohmann::json get(string uri) {
return doRequest(uri, RequestType::Get);
}
nlohmann::json post(string uri, nlohmann::json body = nullptr) {
return doRequest(uri, RequestType::Post, body);
}
nlohmann::json put(string uri, nlohmann::json body = nullptr) {
return doRequest(uri, RequestType::Put, body);
}
nlohmann::json del(string uri) {
return doRequest(uri, RequestType::Delete);
}
nlohmann::json circleOcciLogin(string username, string password){
get("login/");
string body = "{\"username\": \"" + username + "\", \"password\": \"" + password + "\"}";
return post("login/", nlohmann::json::parse(body));
}
nlohmann::json queryInterface(){
return get("-/");
}
};
}
#endif // OCCILIB_SESSION_H_
// Copyright 2017 Budapest University of Technology and Economics (BME IK)
//
// This file is part of CIRCLE Cloud.
//
// CIRCLE is free software: you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// CIRCLE is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
// details.
//
// You should have received a copy of the GNU General Public License along
// with CIRCLE. If not, see <http://www.gnu.org/licenses/>.
#ifndef OCCILIB_RESOURCE_H_
#define OCCILIB_RESOURCE_H_
#include <string>
#include "json.hpp"
#include "occisession.h"
namespace OcciClient{
// using nlohmann::json;
using std::string;
class Resource{
protected:
OcciSession* session;
string id;
string title;
nlohmann::json rendering;
string kind;
void parseJsonInstance(nlohmann::json instance) {
this->id = getID(instance);
this->title = instance["title"].get<string>();
this->rendering = instance;
}
Resource(OcciSession* session, string kind, nlohmann::json instance) {
this->session = session;
this->kind = kind;
parseJsonInstance(instance);
}
string getID(nlohmann::json& rendering) {
try {
return rendering["id"];
}
catch (std::domain_error) {
return "";
}
}
template <typename T> T getAttributeFromRendering(nlohmann::json& rendering, const string which, const T defaultValue = T()) {
try {
return rendering["attributes"][which].get<T>();
}
catch (std::exception e){
return defaultValue;
}
}
public:
string getId(){
return this->id;
}
string getTitle(){
return this->title;
}
static nlohmann::json invokeAction(OcciSession* session, string kind, string id, nlohmann::json actionData) {
auto uri = kind + "/" + id + "/";
return session->post(uri, actionData);
}
nlohmann::json invokeAction(nlohmann::json actionData){
return invokeAction(this->session, this->kind, this->id, actionData);
}
nlohmann::json getRendering(){
return this->rendering;
}
void destroyInstance() {
auto uri = this->kind + "/" + this->id + "/";
session->del(uri);
}
};
}
#endif // OCCILIB_RESOURCE_H_
// Copyright 2017 Budapest University of Technology and Economics (BME IK)
//
// This file is part of CIRCLE Cloud.
//
// CIRCLE is free software: you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// CIRCLE is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
// details.
//
// You should have received a copy of the GNU General Public License along
// with CIRCLE. If not, see <http://www.gnu.org/licenses/>.
#ifndef OCCILIB_TEMPLATE_H_
#define OCCILIB_TEMPLATE_H_
#include <string>
#include <vector>
#include <iostream>
#include "occisession.h"
#include "json.hpp"
typedef std::string Template;
namespace OcciClient{
std::vector<Template> getTemplates(OcciSession* session){
nlohmann::json mixins = session->queryInterface()["mixins"];
auto result = std::vector<Template>();
for (auto& mixin : mixins) {
if (mixin["depends"] == "http://schemas.ogf.org/occi/infrastructure#os_tpl") {
result.push_back(mixin["scheme"].get<string>() + mixin["term"].get<string>());
}
}
return result;
}
}
#endif // OCCILIB_TEMPLATE_H
#include <iostream>
#include "occilib.h"
using OcciClient::OcciSession;
using OcciClient::Compute;
using std::endl;
using std::cout;
using std::shared_ptr;
int main() {
shared_ptr<OcciSession> session(new OcciSession("https://vm.ik.bme.hu:15766/occi/", true, true));
session->circleOcciLogin("admin", "retekretek");
cout << "Templates: ";
auto ts = OcciClient::getTemplates(session.get());
for (auto& t : ts){
cout << t << ", ";
}
cout << endl;
auto comp = Compute::getComputeInstance(session.get(), "96");
comp->wakeup();
cout << comp->getStateMessage() << endl;
comp->sleep();
cout << comp->getStateMessage() << endl;
cout << "To connect to this compute instance use the \"" << comp->getCredentialCommand() << "\" command." << endl;
auto comp2 = Compute::createComputeInstance(session.get(), ts.back());
cout << "id: " << comp2->getId() << ", title: " << comp2->getTitle() << endl;
comp2->destroyInstance();
auto comp3 = Compute::getComputeInstance(session.get(), "96");
// not exists :'(
}
from occi import OcciSession, getTemplates, Compute
session = OcciSession("https://vm.ik.bme.hu:15766/occi/", True, True)
session.circleOcciLogin("admin", "retekretek")
ts = getTemplates(session)
for i in ts:
print(i)
comp = Compute.getComputeInstance(session, "96")
print("title: %s" % comp.getTitle())
comp.wakeup()
print(comp.getStateMessage())
comp.sleep()
print(comp.getStateMessage())
print("To connect to this compute instance use the "
"'%s' command." % comp.getCredentialCommand())
comp2 = Compute.createComputeInstance(session, ts.back())
print("id: %s, title: %s" % (comp2.getId(), comp2.getTitle()))
comp2.destroyInstance()
comp3 = Compute.getComputeInstance(session, "2000")
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment