Skip to content
This repository has been archived by the owner on Aug 19, 2019. It is now read-only.

Commit

Permalink
Add a User-Agent header to metadata API requests; allow overriding v…
Browse files Browse the repository at this point in the history
…ia config; add --version argument. (#84)
  • Loading branch information
igorpeshansky authored Mar 20, 2018
1 parent 621e16a commit f58374b
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 22 deletions.
13 changes: 8 additions & 5 deletions src/Makefile
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
PKG_VERSION=0.0.17
PKG_RELEASE=1
DOCKER_VERSION=0.2

LIBDIR=../lib
CPP_NETLIB_DIR=$(LIBDIR)/cpp-netlib
CPP_NETLIB_LIBDIR=$(CPP_NETLIB_DIR)/libs/network/src
Expand All @@ -12,10 +16,12 @@ GIT_VERSION=$(shell $(GIT) --version | grep -oh '[0-9]\+\.[0-9]\+\.[0-9]\+')

SED_I=/usr/bin/env sed -i
CMAKE=cmake
CXXFLAGS=\
-std=c++11 -g -Wno-write-strings -Wno-deprecated \
CPPFLAGS=\
-DAGENT_VERSION='$(PKG_VERSION)-$(PKG_RELEASE)' \
-DENABLE_DOCKER_METADATA -DENABLE_KUBERNETES_METADATA \
-I$(CPP_NETLIB_DIR) -I$(NETWORK_URI_DIR)/include -I$(YAML_CPP_DIR)/include
CXXFLAGS=\
-std=c++11 -g -Wno-write-strings -Wno-deprecated
LDFLAGS=-L$(CPP_NETLIB_LIBDIR) -L$(NETWORK_URI_LIBDIR) -L$(YAML_CPP_LIBDIR)
LDLIBS=\
-lcppnetlib-client-connections -lcppnetlib-server-parsers -lnetwork-uri \
Expand Down Expand Up @@ -80,11 +86,8 @@ install: metadatad

export DISTRO
PKG_NAME=stackdriver-metadata
PKG_VERSION=0.0.17
PKG_RELEASE=1
PKG_MAINTAINER=Stackdriver Agents <[email protected]>

DOCKER_VERSION=0.2
DOCKER_IMAGE=us.gcr.io/container-monitoring-storage/stackdriver-metadata-agent
DOCKER_TAG=$(DOCKER_VERSION)-$(PKG_VERSION)-$(PKG_RELEASE)

Expand Down
8 changes: 6 additions & 2 deletions src/api_server.cc
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ namespace {
void SendMetadataRequest(std::vector<json::value>&& entries,
const std::string& endpoint,
const std::string& auth_header,
const std::string& user_agent,
bool verbose_logging)
throw (boost::system::system_error) {
json::value update_metadata_request = json::object({
Expand All @@ -200,12 +201,14 @@ void SendMetadataRequest(std::vector<json::value>&& entries,

if (verbose_logging) {
LOG(INFO) << "About to send request: POST " << endpoint
<< " User-Agent: " << user_agent
<< " " << *update_metadata_request;
}

http::client client;
http::client::request request(endpoint);
std::string request_body = update_metadata_request->ToString();
request << boost::network::header("User-Agent", user_agent);
request << boost::network::header("Content-Length",
std::to_string(request_body.size()));
request << boost::network::header("Content-Type", "application/json");
Expand Down Expand Up @@ -247,6 +250,7 @@ void MetadataReporter::SendMetadata(
format::Substitute(agent_->config_.MetadataIngestionEndpointFormat(),
{{"project_id", project_id}});
const std::string auth_header = auth_.GetAuthHeaderValue();
const std::string user_agent = agent_->config_.MetadataReporterUserAgent();

const json::value empty_request = json::object({
{"entries", json::array({})},
Expand Down Expand Up @@ -282,7 +286,7 @@ void MetadataReporter::SendMetadata(
continue;
}
if (total_size + size > limit_bytes) {
SendMetadataRequest(std::move(entries), endpoint, auth_header,
SendMetadataRequest(std::move(entries), endpoint, auth_header, user_agent,
agent_->config_.VerboseLogging());
entries.clear();
total_size = empty_size;
Expand All @@ -291,7 +295,7 @@ void MetadataReporter::SendMetadata(
total_size += size;
}
if (!entries.empty()) {
SendMetadataRequest(std::move(entries), endpoint, auth_header,
SendMetadataRequest(std::move(entries), endpoint, auth_header, user_agent,
agent_->config_.VerboseLogging());
}
}
Expand Down
49 changes: 39 additions & 10 deletions src/configuration.cc
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,14 @@

#include <yaml-cpp/yaml.h>

#ifndef AGENT_VERSION
#define AGENT_VERSION 0.0
#endif

// https://gcc.gnu.org/onlinedocs/gcc-7.3.0/cpp/Stringizing.html
#define STRINGIFY_H(x) #x
#define STRINGIFY(x) STRINGIFY_H(x)

namespace google {

namespace {
Expand All @@ -35,6 +43,8 @@ constexpr const int kMetadataApiDefaultPort = 8000;
constexpr const char kMetadataApiDefaultResourceTypeSeparator[] = ".";
constexpr const int kMetadataReporterDefaultIntervalSeconds = 60;
constexpr const int kMetadataReporterDefaultPurgeDeleted = false;
constexpr const char kMetadataReporterDefaultUserAgent[] =
"metadata-agent/" STRINGIFY(AGENT_VERSION);
constexpr const char kMetadataIngestionDefaultEndpointFormat[] =
"https://stackdriver.googleapis.com/v1beta2/projects/{{project_id}}"
"/resourceMetadata:batchUpdate";
Expand All @@ -60,7 +70,6 @@ constexpr const bool kKubernetesDefaultUseWatch = true;
constexpr const bool kKubernetesDefaultClusterLevelMetadata = false;
constexpr const char kDefaultInstanceId[] = "";
constexpr const char kDefaultInstanceZone[] = "";

}

MetadataAgentConfiguration::MetadataAgentConfiguration()
Expand All @@ -75,6 +84,8 @@ MetadataAgentConfiguration::MetadataAgentConfiguration()
kMetadataReporterDefaultIntervalSeconds),
metadata_reporter_purge_deleted_(
kMetadataReporterDefaultPurgeDeleted),
metadata_reporter_user_agent_(
kMetadataReporterDefaultUserAgent),
metadata_ingestion_endpoint_format_(
kMetadataIngestionDefaultEndpointFormat),
metadata_ingestion_request_size_limit_bytes_(
Expand Down Expand Up @@ -106,6 +117,7 @@ int MetadataAgentConfiguration::ParseArguments(int ac, char** av) {
boost::program_options::options_description flags_desc;
flags_desc.add_options()
("help,h", "Print help message")
("version,V", "Print the agent version")
("verbose,v", boost::program_options::bool_switch(&verbose_logging_),
"Enable verbose logging")
;
Expand All @@ -121,18 +133,29 @@ int MetadataAgentConfiguration::ParseArguments(int ac, char** av) {
boost::program_options::positional_options_description positional_desc;
positional_desc.add(kConfigFileFlag, 1);
boost::program_options::variables_map flags;
boost::program_options::store(
boost::program_options::command_line_parser(ac, av)
.options(all_desc).positional(positional_desc).run(), flags);
boost::program_options::notify(flags);
try {
boost::program_options::store(
boost::program_options::command_line_parser(ac, av)
.options(all_desc).positional(positional_desc).run(), flags);
boost::program_options::notify(flags);

if (flags.count("help")) {
std::cout << flags_desc << std::endl;
if (flags.count("help")) {
std::cout << flags_desc << std::endl;
return -1;
}
if (flags.count("version")) {
std::cout << "Stackdriver Metadata Agent v" << STRINGIFY(AGENT_VERSION)
<< std::endl;
return -1;
}

ParseConfigFile(config_file);
return 0;
} catch (const boost::program_options::error& arg_error) {
std::cerr << arg_error.what() << std::endl;
std::cerr << flags_desc << std::endl;
return 1;
}

ParseConfigFile(config_file);
return 0;
}

void MetadataAgentConfiguration::ParseConfigFile(const std::string& filename) {
Expand Down Expand Up @@ -162,6 +185,9 @@ void MetadataAgentConfiguration::ParseConfiguration(std::istream& input) {
metadata_reporter_purge_deleted_ =
config["MetadataReporterPurgeDeleted"].as<bool>(
kMetadataReporterDefaultPurgeDeleted);
metadata_reporter_user_agent_ =
config["MetadataReporterUserAgent"].as<std::string>(
kMetadataReporterDefaultUserAgent);
metadata_ingestion_endpoint_format_ =
config["MetadataIngestionEndpointFormat"].as<std::string>(
kMetadataIngestionDefaultEndpointFormat);
Expand Down Expand Up @@ -217,3 +243,6 @@ void MetadataAgentConfiguration::ParseConfiguration(std::istream& input) {
}

} // google

#undef STRINGIFY
#undef STRINGIFY_H
10 changes: 10 additions & 0 deletions src/configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ namespace google {
class MetadataAgentConfiguration {
public:
MetadataAgentConfiguration();
// Parse the command line.
// A zero return value means that parsing succeeded and the program should
// proceed. A positive return value means that parsing failed. A negative
// value means that parsing succeeded, but all of the arguments were handled
// within the function and the program should exit with a success exit code.
int ParseArguments(int ac, char** av);

// Shared configuration.
Expand Down Expand Up @@ -61,6 +66,10 @@ class MetadataAgentConfiguration {
std::lock_guard<std::mutex> lock(mutex_);
return metadata_reporter_purge_deleted_;
}
const std::string& MetadataReporterUserAgent() const {
std::lock_guard<std::mutex> lock(mutex_);
return metadata_reporter_user_agent_;
}
const std::string& MetadataIngestionEndpointFormat() const {
std::lock_guard<std::mutex> lock(mutex_);
return metadata_ingestion_endpoint_format_;
Expand Down Expand Up @@ -157,6 +166,7 @@ class MetadataAgentConfiguration {
std::string metadata_api_resource_type_separator_;
int metadata_reporter_interval_seconds_;
bool metadata_reporter_purge_deleted_;
std::string metadata_reporter_user_agent_;
std::string metadata_ingestion_endpoint_format_;
int metadata_ingestion_request_size_limit_bytes_;
std::string metadata_ingestion_raw_content_version_;
Expand Down
2 changes: 1 addition & 1 deletion src/metadatad.cc
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ int main(int ac, char** av) {
google::MetadataAgentConfiguration config;
int parse_result = config.ParseArguments(ac, av);
if (parse_result) {
return parse_result;
return parse_result < 0 ? 0 : parse_result;
}

google::MetadataAgent server(config);
Expand Down
5 changes: 4 additions & 1 deletion test/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ GTEST_SOURCEDIR=$(GTEST_DIR)/src
GTEST_HEADERS=$(GTEST_DIR)/include/gtest/*.h \
$(GTEST_DIR)/include/gtest/internal/*.h
GTEST_SRCS_=$(GTEST_SOURCEDIR)/*.cc $(GTEST_SOURCEDIR)/*.h $(GTEST_HEADERS)
GMOCK_DIR=$(LIBDIR)/googletest/googlemock

# TODO: Factor out the common variables.
CPP_NETLIB_DIR=$(LIBDIR)/cpp-netlib
Expand All @@ -13,7 +14,9 @@ YAML_CPP_LIBDIR=$(YAML_CPP_DIR)

YAML_CPP_LIBS=$(YAML_CPP_LIBDIR)/libyaml-cpp.a

CPPFLAGS+=-isystem $(GTEST_DIR)/include -I$(YAML_CPP_DIR)/include
CPPFLAGS+= \
-isystem $(GTEST_DIR)/include -I$(GMOCK_DIR)/include \
-I$(YAML_CPP_DIR)/include
CXXFLAGS=-std=c++11 -g -pthread
LDLIBS=-lpthread -lboost_program_options -lyaml-cpp
LDFLAGS=-L$(YAML_CPP_LIBDIR)
Expand Down
11 changes: 8 additions & 3 deletions test/configuration_unittest.cc
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "../src/configuration.h"
#include "gtest/gtest.h"
#include "gmock/gmock.h"

namespace google {

Expand All @@ -18,6 +19,8 @@ class MetadataAgentConfigurationTest : public ::testing::Test {
EXPECT_EQ(".", config.MetadataApiResourceTypeSeparator());
EXPECT_EQ(60, config.MetadataReporterIntervalSeconds());
EXPECT_EQ(false, config.MetadataReporterPurgeDeleted());
EXPECT_THAT(config.MetadataReporterUserAgent(),
::testing::StartsWith("metadata-agent/"));
EXPECT_EQ("https://stackdriver.googleapis.com/"
"v1beta2/projects/{{project_id}}/resourceMetadata:batchUpdate",
config.MetadataIngestionEndpointFormat());
Expand Down Expand Up @@ -58,18 +61,20 @@ TEST_F(MetadataAgentConfigurationTest, PopulatedConfig) {
ParseConfiguration(
"ProjectId: TestProjectId\n"
"MetadataApiNumThreads: 13\n"
"MetadataReporterPurgeDeleted: true"
"MetadataReporterPurgeDeleted: true\n"
"MetadataReporterUserAgent: \"foobar/foobaz\"\n"
);
EXPECT_EQ("TestProjectId", config.ProjectId());
EXPECT_EQ(13, config.MetadataApiNumThreads());
EXPECT_EQ(true, config.MetadataReporterPurgeDeleted());
EXPECT_EQ("foobar/foobaz", config.MetadataReporterUserAgent());
}

TEST_F(MetadataAgentConfigurationTest, CommentSkipped) {
ParseConfiguration(
"ProjectId: TestProjectId\n"
"#MetadataApiNumThreads: 13\n"
"MetadataReporterPurgeDeleted: true"
"MetadataReporterPurgeDeleted: true\n"
);
EXPECT_EQ(3, config.MetadataApiNumThreads());
}
Expand All @@ -79,7 +84,7 @@ TEST_F(MetadataAgentConfigurationTest, BlankLine) {
"ProjectId: TestProjectId\n"
"\n"
"\n"
"MetadataReporterPurgeDeleted: true"
"MetadataReporterPurgeDeleted: true\n"
);
EXPECT_EQ("TestProjectId", config.ProjectId());
EXPECT_EQ(true, config.MetadataReporterPurgeDeleted());
Expand Down

0 comments on commit f58374b

Please sign in to comment.