Skip to content

Commit 968aa36

Browse files
committed
CCDB: add support for bearer token
Allows authenticating with the soon to be deployed security proxy of the CI. Also make the endpoint configurable in tests. Solves the issues with CCDB on SLC10.
1 parent bf435e7 commit 968aa36

4 files changed

Lines changed: 56 additions & 12 deletions

File tree

CCDB/src/CcdbApi.cxx

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,29 @@ using namespace std;
6060
std::mutex gIOMutex; // to protect TMemFile IO operations
6161
unique_ptr<TJAlienCredentials> CcdbApi::mJAlienCredentials = nullptr;
6262

63+
namespace
64+
{
65+
/// Append the gate token, if ALICEO2_CCDB_AUTH_TOKEN names one, to a header list.
66+
///
67+
/// Set when CCDB is reached through a broker that authenticates its callers.
68+
/// The CI does this so the credential CCDB wants for writes -- a grid
69+
/// certificate -- stays in the broker and never enters the build container,
70+
/// which runs pull-request code. The broker consumes this header and does not
71+
/// forward it, so CCDB itself never sees it.
72+
///
73+
/// Read once into a static: getenv races setenv, and these paths run from
74+
/// several threads. Returns the list unchanged when no token is configured, so
75+
/// callers can apply it unconditionally.
76+
curl_slist* appendGateToken(curl_slist* list)
77+
{
78+
static const std::string header = []() -> std::string {
79+
const char* token = getenv("ALICEO2_CCDB_AUTH_TOKEN");
80+
return (token && *token) ? std::string("Authorization: Bearer ") + token : std::string();
81+
}();
82+
return header.empty() ? list : curl_slist_append(list, header.c_str());
83+
}
84+
} // namespace
85+
6386
/**
6487
* Object, encapsulating a semaphore, regulating
6588
* concurrent (multi-process) access to CCDB snapshot files.
@@ -428,6 +451,8 @@ int CcdbApi::storeAsBinaryFile(const char* buffer, size_t size, const std::strin
428451
static const char buf[] = "Expect:";
429452
headerlist = curl_slist_append(headerlist, buf);
430453

454+
headerlist = appendGateToken(headerlist);
455+
431456
curlSetSSLOptions(curl);
432457

433458
curl_easy_setopt(curl, CURLOPT_MIMEPOST, mime);
@@ -722,6 +747,8 @@ void CcdbApi::initCurlHTTPHeaderOptionsForRetrieve(CURL* curlHandle, curl_slist*
722747
curl_easy_setopt(curlHandle, CURLOPT_HEADERDATA, headers);
723748
}
724749

750+
option_list = appendGateToken(option_list);
751+
725752
if (option_list) {
726753
curl_easy_setopt(curlHandle, CURLOPT_HTTPHEADER, option_list);
727754
}
@@ -795,7 +822,7 @@ bool CcdbApi::receiveObject(void* dataHolder, std::string const& path, std::map<
795822
TObject* CcdbApi::retrieve(std::string const& path, std::map<std::string, std::string> const& metadata,
796823
long timestamp) const
797824
{
798-
struct MemoryStruct chunk {
825+
struct MemoryStruct chunk{
799826
(char*)malloc(1) /*memory*/, 0 /*size*/
800827
};
801828

@@ -1237,6 +1264,7 @@ std::string CcdbApi::list(std::string const& path, bool latestOnly, std::string
12371264
if (createdNotBefore >= 0) {
12381265
headers = curl_slist_append(headers, ("If-Not-Before: " + std::to_string(createdNotBefore)).c_str());
12391266
}
1267+
headers = appendGateToken(headers);
12401268
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
12411269

12421270
curlSetSSLOptions(curl);
@@ -1453,6 +1481,7 @@ std::map<std::string, std::string> CcdbApi::retrieveHeaders(std::string const& p
14531481
if (curl != nullptr) {
14541482
struct curl_slist* list = nullptr;
14551483
list = curl_slist_append(list, ("If-None-Match: " + std::to_string(timestamp)).c_str());
1484+
list = appendGateToken(list);
14561485

14571486
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list);
14581487

@@ -1531,6 +1560,7 @@ bool CcdbApi::getCCDBEntryHeaders(std::string const& url, std::string const& eta
15311560

15321561
struct curl_slist* list = nullptr;
15331562
list = curl_slist_append(list, ("If-None-Match: " + etag).c_str());
1563+
list = appendGateToken(list);
15341564

15351565
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list);
15361566

CCDB/test/testBasicCCDBManager.cxx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "CCDB/BasicCCDBManager.h"
2424
#include "Framework/Logger.h"
2525
#include <boost/test/unit_test.hpp>
26+
#include <cstdlib>
2627

2728
using namespace o2::ccdb;
2829

@@ -37,6 +38,11 @@ struct Fixture {
3738
Fixture()
3839
{
3940
CcdbApi api;
41+
// These suites upload, so they need a WRITABLE instance -- ccdb-test by
42+
// default, not the official CCDB.
43+
if (const char* host = std::getenv("ALICEO2_CCDB_HOST")) {
44+
ccdbUrl = host;
45+
}
4046
api.init(ccdbUrl);
4147
std::cout << "ccdb url: " << ccdbUrl << std::endl;
4248
hostReachable = api.isHostReachable();
@@ -134,7 +140,7 @@ BOOST_AUTO_TEST_CASE(TestBasicCCDBManager)
134140
BOOST_CHECK(objB && (*objB) == ccdbObjO); // make sure correct object is loaded
135141

136142
// get object in TimeMachine mode in the past
137-
cdb.setCreatedNotAfter(1); // set upper object validity
143+
cdb.setCreatedNotAfter(1); // set upper object validity
138144
cdb.setFatalWhenNull(false);
139145
objA = cdb.get<std::string>(pathA); // should not be loaded
140146
BOOST_CHECK(!objA); // make sure correct object is not loaded

CCDB/test/testCcdbApi.cxx

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,15 @@
2020
#define BOOST_TEST_DYN_LINK
2121

2222
#include "CCDB/CcdbApi.h"
23-
#include "CCDB/IdPath.h" // just as test object
23+
#include "CCDB/IdPath.h" // just as test object
2424
#include "CommonUtils/RootChain.h" // just as test object
2525
#include "CCDB/CCDBTimeStampUtils.h"
2626
#include <boost/test/unit_test.hpp>
2727
#include <filesystem>
2828
#include <iostream>
2929
#include <TH1F.h>
3030
#include <chrono>
31+
#include <cstdlib>
3132
#include <CommonUtils/StringUtils.h>
3233
#include <TStreamerInfo.h>
3334
#include <TGraph.h>
@@ -45,7 +46,7 @@ using namespace o2::ccdb;
4546
namespace utf = boost::unit_test;
4647
namespace tt = boost::test_tools;
4748

48-
static std::string ccdbUrl;
49+
static std::string ccdbUrl = "http://ccdb-test.cern.ch:8080";
4950
static std::string basePath;
5051
bool hostReachable = false;
5152

@@ -56,7 +57,11 @@ struct Fixture {
5657
Fixture()
5758
{
5859
CcdbApi api;
59-
ccdbUrl = "http://ccdb-test.cern.ch:8080";
60+
// These suites upload, so they need a WRITABLE instance -- ccdb-test by
61+
// default, not the official CCDB.
62+
if (const char* host = std::getenv("ALICEO2_CCDB_HOST")) {
63+
ccdbUrl = host;
64+
}
6065
api.init(ccdbUrl);
6166
cout << "ccdb url: " << ccdbUrl << endl;
6267
hostReachable = api.isHostReachable();
@@ -65,7 +70,7 @@ struct Fixture {
6570
gethostname(hostname, _POSIX_HOST_NAME_MAX);
6671
basePath = std::string("Test/TestCcdbApi/") + hostname + "/pid" + getpid() + "/";
6772
// Replace dashes by underscores to avoid problems in the creation of local directories
68-
std::replace(basePath.begin(), basePath.end(), '-','_');
73+
std::replace(basePath.begin(), basePath.end(), '-', '_');
6974
cout << "Path we will use in this test suite : " + basePath << endl;
7075
}
7176
~Fixture()
@@ -446,13 +451,13 @@ BOOST_AUTO_TEST_CASE(TestFetchingHeaders, *utf::precondition(if_reachable()))
446451
std::vector<std::string> headers;
447452
std::vector<std::string> pfns;
448453
std::string path = objectPath + "/" + std::to_string(getCurrentTimestamp());
449-
auto updated = CcdbApi::getCCDBEntryHeaders("http://ccdb-test.cern.ch:8080/" + path, etag, headers);
454+
auto updated = CcdbApi::getCCDBEntryHeaders(ccdbUrl + "/" + path, etag, headers);
450455
BOOST_CHECK_EQUAL(updated, true);
451456
BOOST_REQUIRE(headers.size() != 0);
452457
CcdbApi::parseCCDBHeaders(headers, pfns, etag);
453458
BOOST_REQUIRE(etag != "");
454459
BOOST_REQUIRE(pfns.size());
455-
updated = CcdbApi::getCCDBEntryHeaders("http://ccdb-test.cern.ch:8080/" + path, etag, headers);
460+
updated = CcdbApi::getCCDBEntryHeaders(ccdbUrl + "/" + path, etag, headers);
456461
BOOST_CHECK_EQUAL(updated, false);
457462
}
458463

@@ -557,7 +562,7 @@ BOOST_AUTO_TEST_CASE(TestUpdateMetadata, *utf::precondition(if_reachable()))
557562
BOOST_AUTO_TEST_CASE(multi_host_test)
558563
{
559564
CcdbApi api;
560-
api.init("http://bogus-host.cern.ch,http://ccdb-test.cern.ch:8080");
565+
api.init("http://bogus-host.cern.ch," + ccdbUrl);
561566
std::map<std::string, std::string> metadata;
562567
std::map<std::string, std::string> headers;
563568
o2::pmr::vector<char> dst;
@@ -569,7 +574,7 @@ BOOST_AUTO_TEST_CASE(multi_host_test)
569574
BOOST_AUTO_TEST_CASE(vectored)
570575
{
571576
CcdbApi api;
572-
api.init("http://ccdb-test.cern.ch:8080");
577+
api.init(ccdbUrl);
573578

574579
int TEST_SAMPLE_SIZE = 5;
575580
std::vector<o2::pmr::vector<char>> dests(TEST_SAMPLE_SIZE);

CCDB/test/testCcdbApiHeaders.cxx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "CCDB/CCDBTimeStampUtils.h"
2424
#include "CCDB/CcdbApi.h"
2525
#include <boost/test/unit_test.hpp>
26+
#include <cstdlib>
2627

2728
static std::string basePath;
2829
// std::string ccdbUrl = "http://localhost:8080";
@@ -37,8 +38,10 @@ struct Fixture {
3738
Fixture()
3839
{
3940
auto& ccdbManager = o2::ccdb::BasicCCDBManager::instance();
40-
if (std::getenv("ALICEO2_CCDB_HOST")) {
41-
ccdbUrl = std::string(std::getenv("ALICEO2_CCDB_HOST"));
41+
// These suites upload, so they need a WRITABLE instance -- ccdb-test by
42+
// default, not the official CCDB.
43+
if (const char* host = std::getenv("ALICEO2_CCDB_HOST")) {
44+
ccdbUrl = host;
4245
}
4346
ccdbManager.setURL(ccdbUrl);
4447
hostReachable = ccdbManager.getCCDBAccessor().isHostReachable();

0 commit comments

Comments
 (0)