Skip to content

Commit

Permalink
Merge pull request #20 from nicklan/set-certs
Browse files Browse the repository at this point in the history
Set cert location based on where they actually are in the filesystem
  • Loading branch information
samansmink authored Nov 20, 2024
2 parents 1c359eb + 1e7437f commit 8547541
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 1 deletion.
3 changes: 3 additions & 0 deletions src/include/uc_api.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ struct UCAPITableCredentials {

class UCAPI {
public:
//! WARNING: not thread-safe. To be called once on extension initialization
static void InitializeCurl();

static UCAPITableCredentials GetTableCredentials(const string &table_id, UCCredentials credentials);
static vector<string> GetCatalogs(const string &catalog, UCCredentials credentials);
static vector<UCAPITable> GetTables(const string &catalog, const string &schema, UCCredentials credentials);
Expand Down
44 changes: 44 additions & 0 deletions src/uc_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,53 @@
#include "storage/uc_catalog.hpp"
#include "yyjson.hpp"
#include <curl/curl.h>
#include <sys/stat.h>

namespace duckdb {

//! We use a global here to store the path that is selected on the UCAPI::InitializeCurl call
static string SELECTED_CURL_CERT_PATH = "";

static size_t GetRequestWriteCallback(void *contents, size_t size, size_t nmemb, void *userp) {
((std::string *)userp)->append((char *)contents, size * nmemb);
return size * nmemb;
}

// we statically compile in libcurl, which means the cert file location of the build machine is the
// place curl will look. But not every distro has this file in the same location, so we search a
// number of common locations and use the first one we find.
static string certFileLocations[] = {
// Arch, Debian-based, Gentoo
"/etc/ssl/certs/ca-certificates.crt",
// RedHat 7 based
"/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem",
// Redhat 6 based
"/etc/pki/tls/certs/ca-bundle.crt",
// OpenSUSE
"/etc/ssl/ca-bundle.pem",
// Alpine
"/etc/ssl/cert.pem"
};

// Look through the the above locations and if one of the files exists, set that as the location curl should use.
static bool SelectCurlCertPath() {
for (string& caFile : certFileLocations) {
struct stat buf;
if (stat(caFile.c_str(), &buf) == 0) {
SELECTED_CURL_CERT_PATH = caFile;
}
}
return false;
}

static bool SetCurlCAFileInfo(CURL* curl) {
if (!SELECTED_CURL_CERT_PATH.empty()) {
curl_easy_setopt(curl, CURLOPT_CAINFO, SELECTED_CURL_CERT_PATH.c_str());
return true;
}
return false;
}

static string GetRequest(const string &url, const string &token = "") {
CURL *curl;
CURLcode res;
Expand All @@ -24,6 +63,7 @@ static string GetRequest(const string &url, const string &token = "") {
curl_easy_setopt(curl, CURLOPT_XOAUTH2_BEARER, token.c_str());
curl_easy_setopt(curl, CURLOPT_HTTPAUTH, CURLAUTH_BEARER);
}
SetCurlCAFileInfo(curl); // todo: log something if this returns false
res = curl_easy_perform(curl);
curl_easy_cleanup(curl);

Expand Down Expand Up @@ -103,6 +143,10 @@ static string GetCredentialsRequest(const string &url, const string &table_id, c
throw InternalException("Failed to initialize curl");
}

void UCAPI::InitializeCurl() {
SelectCurlCertPath();
}

//# list catalogs
// echo "List of catalogs"
// curl --request GET "https://${DATABRICKS_HOST}/api/2.1/unity-catalog/catalogs" \
Expand Down
5 changes: 4 additions & 1 deletion src/uc_catalog_extension.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@
#include "duckdb/common/string_util.hpp"
#include "duckdb/function/scalar_function.hpp"
#include "duckdb/main/extension_util.hpp"
#include <duckdb/parser/parsed_data/create_scalar_function_info.hpp>
#include "duckdb/parser/parsed_data/create_scalar_function_info.hpp"
#include "duckdb/parser/parsed_data/attach_info.hpp"
#include "duckdb/storage/storage_extension.hpp"
#include "uc_api.hpp"

namespace duckdb {

Expand Down Expand Up @@ -129,6 +130,8 @@ class UCCatalogStorageExtension : public StorageExtension {
};

static void LoadInternal(DatabaseInstance &instance) {
UCAPI::InitializeCurl();

SecretType secret_type;
secret_type.name = "uc";
secret_type.deserializer = KeyValueSecret::Deserialize<KeyValueSecret>;
Expand Down

0 comments on commit 8547541

Please sign in to comment.