initial commit
This commit is contained in:
commit
811f80c92c
17 changed files with 549 additions and 0 deletions
41
source/gns3/GnsNode.cpp
Normal file
41
source/gns3/GnsNode.cpp
Normal file
|
@ -0,0 +1,41 @@
|
|||
#include "GnsNode.hpp"
|
||||
#include "GnsPort.hpp"
|
||||
#include "GnsProject.hpp"
|
||||
|
||||
#include <cpr/cpr.h>
|
||||
#include <vector>
|
||||
|
||||
|
||||
namespace gns {
|
||||
|
||||
|
||||
GnsNode::GnsNode(const GnsProject *project, std::string uuid, const std::vector<GnsPort>& ports) {
|
||||
this->project = project;
|
||||
this->uuid = std::move(uuid);
|
||||
this->ports = ports;
|
||||
}
|
||||
|
||||
std::string GnsNode::getApiBase() const {
|
||||
return this->project->getApiBase() + "nodes/" + this->uuid;
|
||||
}
|
||||
|
||||
std::string GnsNode::getUuid() const {
|
||||
return this->uuid;
|
||||
}
|
||||
|
||||
std::vector<GnsPort> GnsNode::getPorts() const {
|
||||
return this->ports;
|
||||
}
|
||||
|
||||
void GnsNode::start() const {
|
||||
// request the API endpoint
|
||||
cpr::Url endpoint = this->getApiBase() + "start";
|
||||
cpr::Response response = Post(endpoint);
|
||||
|
||||
// check for a valid response
|
||||
if (response.error.code != cpr::ErrorCode::OK)
|
||||
throw std::runtime_error(response.error.message);
|
||||
}
|
||||
|
||||
|
||||
}
|
53
source/gns3/GnsNode.hpp
Normal file
53
source/gns3/GnsNode.hpp
Normal file
|
@ -0,0 +1,53 @@
|
|||
#pragma once
|
||||
|
||||
#include "GnsPort.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
||||
|
||||
namespace gns {
|
||||
|
||||
|
||||
class GnsProject;
|
||||
|
||||
|
||||
/**
|
||||
* Represent a GNS3 node
|
||||
*/
|
||||
class GnsNode {
|
||||
public:
|
||||
GnsNode(const GnsProject* project, std::string uuid, const std::vector<GnsPort>& ports);
|
||||
|
||||
/**
|
||||
* Get the base URL for the node API
|
||||
* @return the base URL for the node API
|
||||
*/
|
||||
[[nodiscard]] std::string getApiBase() const;
|
||||
|
||||
/**
|
||||
* Get the uuid of the node
|
||||
* @return the uuid of the node
|
||||
*/
|
||||
[[nodiscard]] std::string getUuid() const;
|
||||
|
||||
/**
|
||||
* Get the ports of the node
|
||||
* @return the ports of the node
|
||||
*/
|
||||
[[nodiscard]] std::vector<GnsPort> getPorts() const;
|
||||
|
||||
/**
|
||||
* Start the node
|
||||
*/
|
||||
void start() const;
|
||||
|
||||
private:
|
||||
const GnsProject* project;
|
||||
std::string uuid;
|
||||
std::vector<GnsPort> ports;
|
||||
};
|
||||
|
||||
|
||||
}
|
12
source/gns3/GnsPort.cpp
Normal file
12
source/gns3/GnsPort.cpp
Normal file
|
@ -0,0 +1,12 @@
|
|||
#include "GnsPort.hpp"
|
||||
|
||||
|
||||
namespace gns {
|
||||
|
||||
|
||||
GnsPort::GnsPort(const std::optional<std::string>& mac_address) {
|
||||
this->mac_address = mac_address;
|
||||
}
|
||||
|
||||
|
||||
}
|
20
source/gns3/GnsPort.hpp
Normal file
20
source/gns3/GnsPort.hpp
Normal file
|
@ -0,0 +1,20 @@
|
|||
#pragma once
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
|
||||
namespace gns {
|
||||
|
||||
|
||||
/**
|
||||
* Represent a port of a GNS3 node
|
||||
*/
|
||||
class GnsPort {
|
||||
public:
|
||||
explicit GnsPort(const std::optional<std::string>& mac_address);
|
||||
|
||||
std::optional<std::string> mac_address;
|
||||
};
|
||||
|
||||
|
||||
}
|
74
source/gns3/GnsProject.cpp
Normal file
74
source/gns3/GnsProject.cpp
Normal file
|
@ -0,0 +1,74 @@
|
|||
#include "GnsProject.hpp"
|
||||
#include "GnsServer.hpp"
|
||||
#include "GnsPort.hpp"
|
||||
|
||||
#include <cpr/cpr.h>
|
||||
#include <nlohmann/json.hpp>
|
||||
using json = nlohmann::json;
|
||||
|
||||
|
||||
namespace gns {
|
||||
|
||||
|
||||
GnsProject::GnsProject(const GnsServer* server, std::string uuid) {
|
||||
this->server = server;
|
||||
this->uuid = std::move(uuid);
|
||||
}
|
||||
|
||||
std::string GnsProject::getApiBase() const {
|
||||
return this->server->getApiBase() + "projects/" + this->uuid + "/";
|
||||
}
|
||||
|
||||
std::string GnsProject::getUuid() const {
|
||||
return this->uuid;
|
||||
}
|
||||
|
||||
std::vector<GnsNode> GnsProject::getNodes() const {
|
||||
std::vector<GnsNode> nodes;
|
||||
|
||||
// request the API endpoint
|
||||
cpr::Url endpoint = this->getApiBase() + "nodes";
|
||||
cpr::Response response = Get(endpoint);
|
||||
|
||||
// check for a valid response
|
||||
if (response.error.code != cpr::ErrorCode::OK)
|
||||
throw std::runtime_error(response.error.message);
|
||||
|
||||
// check for valid content
|
||||
if (response.header["Content-Type"] != "application/json")
|
||||
throw std::runtime_error("Data must be JSON formatted.");
|
||||
|
||||
// parse the data
|
||||
json data = json::parse(response.text);
|
||||
|
||||
// deserialize the projects
|
||||
nodes.reserve(data.size());
|
||||
for (const auto& node_data : data) {
|
||||
// parse the ports of the node
|
||||
std::vector<json> ports_data = node_data.value("ports", std::vector<json>{});
|
||||
std::vector<GnsPort> ports;
|
||||
ports.reserve(ports_data.size());
|
||||
for (const auto& port_data : ports_data) {
|
||||
// get the mac of the port
|
||||
std::optional<std::string> mac_address;
|
||||
if (port_data.contains("mac_address"))
|
||||
mac_address.emplace(port_data["mac_address"]);
|
||||
|
||||
// save the port data
|
||||
ports.emplace_back(mac_address);
|
||||
}
|
||||
|
||||
// save the node
|
||||
nodes.emplace_back(
|
||||
this,
|
||||
node_data["node_id"],
|
||||
ports
|
||||
);
|
||||
}
|
||||
|
||||
return nodes;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
45
source/gns3/GnsProject.hpp
Normal file
45
source/gns3/GnsProject.hpp
Normal file
|
@ -0,0 +1,45 @@
|
|||
#pragma once
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "GnsNode.hpp"
|
||||
|
||||
|
||||
namespace gns {
|
||||
|
||||
|
||||
class GnsServer;
|
||||
|
||||
|
||||
/**
|
||||
* Represent a GNS3 project.
|
||||
*/
|
||||
class GnsProject {
|
||||
public:
|
||||
GnsProject(const GnsServer* server, std::string uuid);
|
||||
|
||||
/**
|
||||
* Get the base prefix for an API request
|
||||
* @return the base prefix for an API request
|
||||
*/
|
||||
[[nodiscard]] std::string getApiBase() const;
|
||||
|
||||
/**
|
||||
* Get the uuid of the project
|
||||
* @return the uuid of the project
|
||||
*/
|
||||
[[nodiscard]] std::string getUuid() const;
|
||||
|
||||
/**
|
||||
* Get all the nodes of the project
|
||||
* @return all the nodes of the project
|
||||
*/
|
||||
[[nodiscard]] std::vector<GnsNode> getNodes() const;
|
||||
|
||||
private:
|
||||
const GnsServer* server;
|
||||
std::string uuid;
|
||||
};
|
||||
|
||||
|
||||
}
|
62
source/gns3/GnsServer.cpp
Normal file
62
source/gns3/GnsServer.cpp
Normal file
|
@ -0,0 +1,62 @@
|
|||
#include "GnsServer.hpp"
|
||||
|
||||
#include <cpr/cpr.h>
|
||||
#include <nlohmann/json.hpp>
|
||||
using json = nlohmann::json;
|
||||
|
||||
|
||||
namespace gns {
|
||||
|
||||
|
||||
GnsServer::GnsServer(const std::string &host, const std::uint16_t port) {
|
||||
this->host = host;
|
||||
this->port = port;
|
||||
}
|
||||
|
||||
std::string GnsServer::getApiBase() const {
|
||||
return "http://" + this->host + ":" + std::to_string(this->port) + "/v2/";
|
||||
}
|
||||
|
||||
std::vector<GnsProject> GnsServer::getProjects() const {
|
||||
std::vector<GnsProject> projects;
|
||||
|
||||
// request the API endpoint
|
||||
cpr::Url endpoint = this->getApiBase() + "projects";
|
||||
cpr::Response response = Get(endpoint);
|
||||
|
||||
// check for a valid response
|
||||
if (response.error.code != cpr::ErrorCode::OK)
|
||||
throw std::runtime_error(response.error.message);
|
||||
|
||||
// check for valid content
|
||||
if (response.header["Content-Type"] != "application/json")
|
||||
throw std::runtime_error("Data must be JSON formatted.");
|
||||
|
||||
// parse the data
|
||||
json data = json::parse(response.text);
|
||||
|
||||
// deserialize the projects
|
||||
projects.reserve(data.size());
|
||||
for (const auto& project_data : data)
|
||||
projects.emplace_back(
|
||||
this,
|
||||
project_data["project_id"]
|
||||
);
|
||||
|
||||
return projects;
|
||||
}
|
||||
|
||||
std::vector<GnsNode> GnsServer::getNodes() const {
|
||||
std::vector<GnsNode> nodes;
|
||||
|
||||
// get all the nodes from all the projects
|
||||
for (const GnsProject& project : this->getProjects()) {
|
||||
std::vector<GnsNode> project_nodes = project.getNodes();
|
||||
nodes.insert(nodes.end(), project_nodes.begin(), project_nodes.end());
|
||||
}
|
||||
|
||||
return nodes;
|
||||
}
|
||||
|
||||
|
||||
}
|
44
source/gns3/GnsServer.hpp
Normal file
44
source/gns3/GnsServer.hpp
Normal file
|
@ -0,0 +1,44 @@
|
|||
#pragma once
|
||||
#include <string>
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
#include "GnsProject.hpp"
|
||||
|
||||
|
||||
namespace gns {
|
||||
|
||||
|
||||
/**
|
||||
* Represent a GNS3 server
|
||||
* Wrapper around the GNS3 API (https://gns3-server.readthedocs.io/en/latest/endpoints.html)
|
||||
*/
|
||||
class GnsServer {
|
||||
public:
|
||||
GnsServer(const std::string& host, std::uint16_t port);
|
||||
|
||||
/**
|
||||
* Get the base prefix for an API request
|
||||
* @return the base prefix for an API request
|
||||
*/
|
||||
[[nodiscard]] std::string getApiBase() const;
|
||||
|
||||
/**
|
||||
* Get all the projects in the server
|
||||
* @return all the projects in the server
|
||||
*/
|
||||
[[nodiscard]] std::vector<GnsProject> getProjects() const;
|
||||
|
||||
/**
|
||||
* Get all the nodes in the server
|
||||
* @return all the nodes in the server
|
||||
*/
|
||||
[[nodiscard]] std::vector<GnsNode> getNodes() const;
|
||||
|
||||
private:
|
||||
std::string host;
|
||||
std::uint16_t port;
|
||||
};
|
||||
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue