Skip to content
This repository was archived by the owner on Aug 19, 2019. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ SRCS=\
api_server.cc \
configuration.cc \
updater.cc \
instance.cc \
docker.cc \
kubernetes.cc \
resource.cc \
Expand Down
27 changes: 26 additions & 1 deletion src/configuration.cc
Original file line number Diff line number Diff line change
Expand Up @@ -31,19 +31,25 @@ constexpr const char kDefaultProjectId[] = "";
constexpr const char kDefaultCredentialsFile[] = "";
constexpr const int kMetadataApiDefaultNumThreads = 3;
constexpr const int kMetadataApiDefaultPort = 8000;
constexpr const char kMetadataApiDefaultResourceTypeSeparator[] = ".";
constexpr const int kMetadataReporterDefaultIntervalSeconds = 60;
constexpr const char kMetadataIngestionDefaultEndpointFormat[] =
"https://stackdriver.googleapis.com/v1beta2/projects/{{project_id}}"
"/resourceMetadata:batchUpdate";
constexpr const int kMetadataIngestionDefaultRequestSizeLimitBytes =
8*1024*1024;
constexpr const char kMetadataIngestionDefaultRawContentVersion[] = "0.1";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was previously only used for Kubernetes, is it reasonable to say that the agent will evolve all resources linearly with a single version? Is it possible for the raw content to change over time at different rates over different resource types? I'm not sure how this contract works with the API.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this is the version of the envelope schema for the metadata ingestion API. The next PR will use it for Docker container resources as well.

constexpr const int kInstanceUpdaterDefaultIntervalSeconds = 60*60;
constexpr const char kDefaultInstanceResourceType[] =
""; // A blank value means "unspecified; detect via environment".
constexpr const int kDockerUpdaterDefaultIntervalSeconds = 60;
constexpr const char kDockerDefaultEndpointHost[] =
"unix://%2Fvar%2Frun%2Fdocker.sock/";
constexpr const char kDockerDefaultApiVersion[] = "1.23";
constexpr const char kDockerDefaultContainerFilter[] = "limit=30";
constexpr const int kKubernetesUpdaterDefaultIntervalSeconds = 60;
constexpr const char kKubernetesDefaultEndpointHost[] = "https://kubernetes.default.svc";
constexpr const char kKubernetesDefaultEndpointHost[] =
"https://kubernetes.default.svc";
constexpr const char kKubernetesDefaultPodLabelSelector[] = "";
constexpr const char kKubernetesDefaultClusterName[] = "";
constexpr const char kKubernetesDefaultNodeName[] = "";
Expand All @@ -59,12 +65,19 @@ MetadataAgentConfiguration::MetadataAgentConfiguration()
verbose_logging_(false),
metadata_api_num_threads_(kMetadataApiDefaultNumThreads),
metadata_api_port_(kMetadataApiDefaultPort),
metadata_api_resource_type_separator_(
kMetadataApiDefaultResourceTypeSeparator),
metadata_reporter_interval_seconds_(
kMetadataReporterDefaultIntervalSeconds),
metadata_ingestion_endpoint_format_(
kMetadataIngestionDefaultEndpointFormat),
metadata_ingestion_request_size_limit_bytes_(
kMetadataIngestionDefaultRequestSizeLimitBytes),
metadata_ingestion_raw_content_version_(
kMetadataIngestionDefaultRawContentVersion),
instance_updater_interval_seconds_(
kInstanceUpdaterDefaultIntervalSeconds),
instance_resource_type_(kDefaultInstanceResourceType),
docker_updater_interval_seconds_(kDockerUpdaterDefaultIntervalSeconds),
docker_endpoint_host_(kDockerDefaultEndpointHost),
docker_api_version_(kDockerDefaultApiVersion),
Expand Down Expand Up @@ -126,6 +139,9 @@ void MetadataAgentConfiguration::ParseConfigFile(const std::string& filename) {
config["MetadataApiNumThreads"].as<int>(kMetadataApiDefaultNumThreads);
metadata_api_port_ =
config["MetadataApiPort"].as<int>(kMetadataApiDefaultPort);
metadata_api_resource_type_separator_ =
config["MetadataApiResourceTypeSeparator"].as<std::string>(
kMetadataApiDefaultResourceTypeSeparator);
metadata_reporter_interval_seconds_ =
config["MetadataReporterIntervalSeconds"].as<int>(
kMetadataReporterDefaultIntervalSeconds);
Expand All @@ -135,6 +151,15 @@ void MetadataAgentConfiguration::ParseConfigFile(const std::string& filename) {
metadata_ingestion_request_size_limit_bytes_ =
config["MetadataIngestionRequestSizeLimitBytes"].as<int>(
kMetadataIngestionDefaultRequestSizeLimitBytes);
metadata_ingestion_raw_content_version_ =
config["MetadataIngestionRawContentVersion"].as<std::string>(
kMetadataIngestionDefaultRawContentVersion);
instance_updater_interval_seconds_ =
config["InstanceUpdaterIntervalSeconds"].as<int>(
kInstanceUpdaterDefaultIntervalSeconds);
instance_resource_type_ =
config["InstanceResourceType"].as<std::string>(
kDefaultInstanceResourceType);
docker_updater_interval_seconds_ =
config["DockerUpdaterIntervalSeconds"].as<int>(
kDockerUpdaterDefaultIntervalSeconds);
Expand Down
21 changes: 21 additions & 0 deletions src/configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ class MetadataAgentConfiguration {
std::lock_guard<std::mutex> lock(mutex_);
return metadata_api_port_;
}
const std::string& MetadataApiResourceTypeSeparator() const {
std::lock_guard<std::mutex> lock(mutex_);
return metadata_api_resource_type_separator_;
}
// Metadata reporter options.
int MetadataReporterIntervalSeconds() const {
std::lock_guard<std::mutex> lock(mutex_);
Expand All @@ -61,6 +65,19 @@ class MetadataAgentConfiguration {
std::lock_guard<std::mutex> lock(mutex_);
return metadata_ingestion_request_size_limit_bytes_;
}
const std::string& MetadataIngestionRawContentVersion() const {
std::lock_guard<std::mutex> lock(mutex_);
return metadata_ingestion_raw_content_version_;
}
// Instance metadata updater options.
int InstanceUpdaterIntervalSeconds() const {
std::lock_guard<std::mutex> lock(mutex_);
return instance_updater_interval_seconds_;
}
const std::string& InstanceResourceType() const {
std::lock_guard<std::mutex> lock(mutex_);
return instance_resource_type_;
}
// Docker metadata updater options.
int DockerUpdaterIntervalSeconds() const {
std::lock_guard<std::mutex> lock(mutex_);
Expand Down Expand Up @@ -122,9 +139,13 @@ class MetadataAgentConfiguration {
bool verbose_logging_;
int metadata_api_num_threads_;
int metadata_api_port_;
std::string metadata_api_resource_type_separator_;
int metadata_reporter_interval_seconds_;
std::string metadata_ingestion_endpoint_format_;
int metadata_ingestion_request_size_limit_bytes_;
std::string metadata_ingestion_raw_content_version_;
int instance_updater_interval_seconds_;
std::string instance_resource_type_;
int docker_updater_interval_seconds_;
std::string docker_endpoint_host_;
std::string docker_api_version_;
Expand Down
6 changes: 3 additions & 3 deletions src/docker.cc
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ constexpr const char docker_endpoint_host[] = "unix://%2Fvar%2Frun%2Fdocker.sock
constexpr const char docker_api_version[] = "1.23";
#endif
constexpr const char docker_endpoint_path[] = "/containers";
constexpr const char resource_type_separator[] = ".";

}

Expand Down Expand Up @@ -85,6 +84,7 @@ std::vector<MetadataUpdater::ResourceMetadata>
if (config_.VerboseLogging()) {
LOG(INFO) << "Parsed metadata: " << *parsed_metadata;
}

const MonitoredResource resource("docker_container", {
{"location", zone},
{"container_id", id},
Expand All @@ -101,10 +101,10 @@ std::vector<MetadataUpdater::ResourceMetadata>
bool is_deleted = state->Get<json::Boolean>("Dead");

const std::string resource_id =
std::string("container") + resource_type_separator + id;
std::string("container") + config_.MetadataApiResourceTypeSeparator() + id;
// The container name reported by Docker will always have a leading '/'.
const std::string resource_name =
std::string("container") + resource_type_separator + name.substr(1);
std::string("container") + config_.MetadataApiResourceTypeSeparator() + name.substr(1);
result.emplace_back(std::vector<std::string>{resource_id, resource_name},
resource,
MetadataAgent::Metadata(config_.DockerApiVersion(),
Expand Down
17 changes: 17 additions & 0 deletions src/environment.cc
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ json::value ReadCredentials(

constexpr const char kGceMetadataServerAddress[] =
"http://metadata.google.internal./computeMetadata/v1/";

constexpr const char kGceInstanceResourceType[] = "gce_instance";

}

Environment::Environment(const MetadataAgentConfiguration& config)
Expand Down Expand Up @@ -164,6 +167,20 @@ const std::string& Environment::InstanceId() const {
return instance_id_;
}

const std::string& Environment::InstanceResourceType() const {
std::lock_guard<std::mutex> lock(mutex_);
if (instance_resource_type_.empty()) {
if (!config_.InstanceResourceType().empty()) {
instance_resource_type_ = config_.InstanceResourceType();
} else {
// Default to a GCE instance.
// TODO: Detect other instance resources.
instance_resource_type_ = kGceInstanceResourceType;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason that config_.InstanceResourceType cannot default to "gce_instance"?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current default (empty value) means "detect via the environment". I've added a comment in configuration.cc to that effect.

}
}
return instance_resource_type_;
}

const std::string& Environment::KubernetesClusterName() const {
std::lock_guard<std::mutex> lock(mutex_);
if (kubernetes_cluster_name_.empty()) {
Expand Down
2 changes: 2 additions & 0 deletions src/environment.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class Environment {
Environment(const MetadataAgentConfiguration& config);

const std::string& NumericProjectId() const;
const std::string& InstanceResourceType() const;
const std::string& InstanceId() const;
const std::string& InstanceZone() const;
const std::string& KubernetesClusterName() const;
Expand All @@ -51,6 +52,7 @@ class Environment {
mutable std::string project_id_;
mutable std::string zone_;
mutable std::string instance_id_;
mutable std::string instance_resource_type_;
mutable std::string kubernetes_cluster_name_;
mutable std::string client_email_;
mutable std::string private_key_;
Expand Down
63 changes: 63 additions & 0 deletions src/instance.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* Copyright 2018 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/

#include "instance.h"

#include <boost/network/protocol/http/client.hpp>
#include <chrono>

#include "json.h"
#include "logging.h"
#include "time.h"

namespace http = boost::network::http;

namespace google {

InstanceReader::InstanceReader(const MetadataAgentConfiguration& config)
: config_(config), environment_(config) {}

/*static*/
MonitoredResource InstanceReader::InstanceResource(const Environment& environment) {
const std::string resource_type = environment.InstanceResourceType();
const std::string instance_id = environment.InstanceId();
const std::string zone = environment.InstanceZone();
return {resource_type, {
{"instance_id", instance_id},
{"zone", zone},
}};
}

std::vector<MetadataUpdater::ResourceMetadata>
InstanceReader::MetadataQuery() const {
if (config_.VerboseLogging()) {
LOG(INFO) << "Instance Query called";
}

MonitoredResource instance_resource = InstanceResource(environment_);

std::vector<MetadataUpdater::ResourceMetadata> result;
result.emplace_back(
std::vector<std::string>{"", environment_.InstanceId()},
instance_resource,
// TODO: Send actual instance metadata.
MetadataAgent::Metadata::IGNORED()
);
return result;
}

}

56 changes: 56 additions & 0 deletions src/instance.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* Copyright 2018 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
#ifndef INSTANCE_H_
#define INSTANCE_H_

//#include "config.h"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Remove if unnecessary.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the pattern in all other files, just to allow using autotools later. I'd like to keep it consistent.


#include <vector>

#include "configuration.h"
#include "environment.h"
#include "resource.h"
#include "updater.h"

namespace google {

class InstanceReader {
public:
InstanceReader(const MetadataAgentConfiguration& config);
// A Instance metadata query function.
std::vector<MetadataUpdater::ResourceMetadata> MetadataQuery() const;

// Gets the monitored resource of the instance the agent is running on.
static MonitoredResource InstanceResource(const Environment& environment);

private:
const MetadataAgentConfiguration& config_;
Environment environment_;
};

class InstanceUpdater : public PollingMetadataUpdater {
public:
InstanceUpdater(MetadataAgent* server)
: reader_(server->config()), PollingMetadataUpdater(
server, server->config().InstanceUpdaterIntervalSeconds(),
std::bind(&google::InstanceReader::MetadataQuery, &reader_)) { }
private:
InstanceReader reader_;
};

}

#endif // INSTANCE_H_
Loading