Skip to content

Commit

Permalink
feat: Add create and delete service methods with enhanced debug logging
Browse files Browse the repository at this point in the history
- Implemented `create_service` method to send a POST request to the API for creating services.
- Implemented `delete_service` method to send a DELETE request to the API for deleting services.
- Added detailed debug logging for both service creation and deletion processes.
  - Logs request payload (formatted JSON) before sending the request.
  - Logs API response (formatted JSON) with HTTP status code for success and failure cases.
- Incorporated error handling for JSON parsing and CURL request failures.
- Improved overall debugging visibility with formatted logs using nlohmann::json for clarity.
  • Loading branch information
irfanghat committed Nov 18, 2024
1 parent 57d7782 commit 8b3cb9a
Show file tree
Hide file tree
Showing 8 changed files with 3,246 additions and 33 deletions.
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -84,4 +84,7 @@ quick-build:

# deps:
# sudo apt -y install nlohmann-json3-dev
# sudo apt -y install libjsoncpp-dev
# sudo apt-get install doxygen

# Quick build command: g++ -I./librender_cdk/extern/dotenv-cpp/include -I./librender_cdk/extern/nlohmann-json/include src/main.cpp src/environment_manager.cpp src/authorization.cpp src/service_manager.cpp -o librender_cdk_DEBUG -lcurl -ljsoncpp
2,863 changes: 2,863 additions & 0 deletions librender_cdk/Doxyfile

Large diffs are not rendered by default.

11 changes: 5 additions & 6 deletions librender_cdk/src/authorization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
#include <nlohmann/json.hpp>
#include <sstream>

// Define an anonymous namespace for the WriteCallback function.
namespace {
// Callback function for handling the data received from `libcurl`.
size_t WriteCallback(void *contents, size_t size, size_t nmemb,
Expand Down Expand Up @@ -57,10 +56,10 @@ AuthorizationManager::list_authorized_users(const std::string &email,
// Format <debug> logs.
try {
nlohmann::json prettyJson = nlohmann::json::parse(response);
std::cout << "<response>::<Authorized Users> -> \n"
std::cout << "\n<response>::<Authorized Users> -> \n"
<< prettyJson.dump(4) << std::endl;
} catch (const nlohmann::json::parse_error &e) {
std::cerr << "Failed to parse JSON with nlohmann::json: "
std::cerr << "\nFailed to parse JSON with nlohmann::json: "
<< e.what() << std::endl;
}

Expand All @@ -79,14 +78,14 @@ AuthorizationManager::list_authorized_users(const std::string &email,
}
}
} else {
std::cerr << "Error parsing JSON response: " << errs << std::endl;
std::cerr << "\nError parsing JSON response: " << errs << std::endl;
}
} else {
std::cerr << "Request failed with HTTP status code: " << http_code
std::cerr << "\nRequest failed with HTTP status code: " << http_code
<< std::endl;
}
} else {
std::cerr << "curl_easy_perform() failed: " << curl_easy_strerror(res)
std::cerr << "\ncurl_easy_perform() failed: " << curl_easy_strerror(res)
<< std::endl;
}

Expand Down
42 changes: 40 additions & 2 deletions librender_cdk/src/environment_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,60 @@
#include <iostream>
#include <string>

/**
* @brief Structure that holds configuration data.
*
* The `Config` struct contains two fields: `api_key` and `owner_credentials`,
* which are loaded from environment variables. This structure is used to
* store configuration values required for connecting to the Render Cloud API.
*/
struct Config {
std::string api_key;
std::string owner_credentials;
};

/**
* @brief Loads configuration data from environment variables.
*
* This function initializes the dotenv library to load variables from a `.env`
* file into the environment. It then retrieves the `API_KEY` and
* `OWNER_CREDENTIALS` from the environment and stores them in a `Config`
* struct, which is returned.
*
* @return A `Config` struct containing the loaded API key and owner
* credentials. If the environment variables are not set, the corresponding
* fields in the `Config` struct will be empty strings.
*
* @note The dotenv library must be properly configured, and the `.env` file
* must exist in the current working directory with the necessary environment
* variables. If the environment variables are not found, the fields in the
* returned `Config` object will remain empty.
*
* @example
* ```
* Config config = load_config();
* std::cout << "API Key: " << config.api_key << std::endl;
* std::cout << "Owner Credentials: " << config.owner_credentials << std::endl;
* ```
*/
Config load_config() {
dotenv::init(".env");

const char *api_key = std::getenv("API_KEY");
const char *owner_credentials = std::getenv("OWNER_CREDENTIALS");

Config config;
if (api_key)
if (api_key) {
config.api_key = api_key;
if (owner_credentials)
} else {
std::cout << "[API_KEY] must be set." << std::endl;
}

if (owner_credentials) {
config.owner_credentials = owner_credentials;
} else {
std::cout << "[OWNER_CREDENTIALS] must be set." << std::endl;
}

return config;
}
94 changes: 87 additions & 7 deletions librender_cdk/src/main.cpp
Original file line number Diff line number Diff line change
@@ -1,15 +1,92 @@
#include "authorization.h"
#include "environment_manager.h"
#include "service_manager.h"
#include <curl/curl.h>
#include <iostream>
#include <jsoncpp/json/json.h>
#include <map>
#include <nlohmann/json.hpp>

int test_delete_service() {
// Load <environment> configuration.
Config config = load_config();
if (config.api_key.empty()) {
std::cerr << "\nAPI key is missing in the configuration." << std::endl;
return -1;
}

ServiceManager service_manager = ServiceManager(config.api_key);
std::string service_id = "srv-csth5l5ds78s73cita7g";
service_manager.delete_service(service_id);

return 0;
}

int test_create_service() {
// Load <environment> configuration.
Config config = load_config();
if (config.api_key.empty()) {
std::cerr << "\nAPI key is missing in the configuration." << std::endl;
return -1;
}

// Initialize the AuthorizationManager with the loaded <environment>
// variables.
AuthorizationManager auth_manager(config.api_key);

// Set the owner email and limit (as request parameters).
std::string email = config.owner_credentials;
std::string limit = "10";

// Get a list of authorized users.
auto authorized_users = auth_manager.list_authorized_users(email, limit);

// Find the owner with the matching email, <owner credentials>.
std::string owner_id;

for (const auto &owner_response : authorized_users) {
const auto &owner = owner_response.owner;
if (owner.email == config.owner_credentials) {
owner_id = owner.id;
break;
}
}

if (owner_id.empty()) {
std::cerr << "\nNo authorized user found..." << std::endl;
return -1;
}

// Sample <service data>.
Json::Value service_data;
service_data["type"] = "static_site";
service_data["autoDeploy"] = "yes";
service_data["serviceDetails"]["pullRequestPreviewsEnabled"] = "no";
service_data["serviceDetails"]["previews"]["generation"] = "off";
service_data["name"] = "cpp_site";
service_data["ownerId"] = owner_id;
service_data["repo"] =
"https://github.com/lexara-prime-ai/SAMPLE_STATIC_SITE";
service_data["branch"] = "main";
service_data["rootDir"] = "./";

// Sample <environment> variables.
Json::Value envVar;
envVar["key"] = "SAMPLE_KEY";
envVar["value"] = "SAMPLE_VALUE";
service_data["envVars"].append(envVar);

ServiceManager service_manager(config.api_key);
service_manager.create_service(service_data);

return 0;
}

int test_list_services() {
// Load environment configuration.
// Load <environment> configuration.
Config config = load_config();
if (config.api_key.empty()) {
std::cerr << "API key is missing in the configuration." << std::endl;
std::cerr << "\nAPI key is missing in the configuration." << std::endl;
return -1;
}

Expand Down Expand Up @@ -58,14 +135,15 @@ int test_list_services() {
}

int test_list_authorized_users() {
// Load environment configuration.
// Load <environment> configuration.
Config config = load_config();
if (config.api_key.empty()) {
std::cerr << "API key is missing in the configuration." << std::endl;
std::cerr << "\nAPI key is missing in the configuration." << std::endl;
return -1;
}

// Initialize the AuthorizationManager with the loaded environment variables.
// Initialize the AuthorizationManager with the loaded <environment>
// variables.
AuthorizationManager auth_manager(config.api_key);

// Set the owner email and limit (as request parameters).
Expand Down Expand Up @@ -93,6 +171,8 @@ int test_list_authorized_users() {
}

int main() {
test_list_authorized_users();
test_list_services();
// test_create_service();
// test_list_authorized_users();
// test_list_services();
test_delete_service();
}
Loading

0 comments on commit 8b3cb9a

Please sign in to comment.