-
Notifications
You must be signed in to change notification settings - Fork 11
RFC: Update the agent to send data to the v1beta3 API #141
base: v1beta3-working-branch
Are you sure you want to change the base?
RFC: Update the agent to send data to the v1beta3 API #141
Conversation
c1a5806
to
d9612e4
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
General comments on the approach.
{metadata.version, | ||
json::object({ | ||
{"schemaName", json::string(metadata.schema_name)}, | ||
{"stringContent", json::string(metadata.metadata->ToString())}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should be able to just use {"structContent", std::move(metadata.metadata)}
here...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes - that is doable.
But sending a string is better since that is the format the backend validates / provides on the read path.
The current implementation will minimize conversions on the backend, and lower chances of data corruption.
We are doing JSON -> string right now.
Sending structContent would mean: JSON -> proto -> JSON -> string
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm confused — we're sending JSON already. What you wrote amounts to sending:
{
"<version>": {
"schemaName": "<schema_name>",
"stringContent": "{\"my_metadata_field\": \"some value\",...}"
}
}
Why would we want to go through the extra layer of encoding at the agent level and parsing at the API level?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using structContent would mean that the API is seeing a struct proto, not pure JSON. This would also mean conversion from JSON -> struct proto -> JSON, possibly leading to some data corruption. That is what I am trying to avoid here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't the conversion be done at the ESF translation layer, before the API gets the data? I'm really wary of sending raw strings around — if this is what is required for fidelity, then this is bad API design.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is correct. I really want to prevent any conversion of the JSON to proto, since that can cause possible mismatches. Sending it as string means that the only conversion is back to JSON
src/kubernetes.h
Outdated
MetadataUpdater::UpdateCallback callback) const; | ||
|
||
// Service watcher. | ||
void WatchServices(MetadataUpdater::UpdateCallback callback); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are we not supposed to be sending in service/endpoints metadata?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes we are, but I wanted to focus on getting Nodes / Pods right first before expanding to other types.
The code for services / endpoints will change a lot anyway because we can now publish them individually. Further, we can abstract the code so we don't have separate watch / callbacks per type, but rather one (or a few) so that they can simply be called as:
WatchResource("Pod", "v1", callback)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is done, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes.
src/store.cc
Outdated
Metadata&& entry) { | ||
if (full_resource_name.empty()) { | ||
if (config_.VerboseLogging()) { | ||
LOG(INFO) << "Dropping metadata entry with a blank full resource name"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This now does the same thing as entry.ignored
(except that I never thought of just dropping that entry in the first place). Do we want to get rid of one or the other?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated this code to to check for both: empty full resource name OR entry.ignored, and removed the check from MetadataReporter::SendMetadata()
src/reporter.cc
Outdated
LOG(INFO) << "About to send request: POST " << endpoint | ||
<< " User-Agent: " << user_agent | ||
<< " " << *update_metadata_request; | ||
// TODO: Convert this into a batch request. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's good to have this TODO, but I think we actually need to do it before this is ready to be tested.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated the code to send batch requests.
682b5f9
to
7fe7b36
Compare
{metadata.version, | ||
json::object({ | ||
{"schemaName", json::string(metadata.schema_name)}, | ||
{"stringContent", json::string(metadata.metadata->ToString())}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm confused — we're sending JSON already. What you wrote amounts to sending:
{
"<version>": {
"schemaName": "<schema_name>",
"stringContent": "{\"my_metadata_field\": \"some value\",...}"
}
}
Why would we want to go through the extra layer of encoding at the agent level and parsing at the API level?
src/configuration.cc
Outdated
config["MetadataIngestionEndpointFormat"].as<std::string>( | ||
metadata_ingestion_endpoint_format_); | ||
metadata_ingestion_host_ = | ||
config["MetadataIngestionHost"].as<std::string>( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This makes the change not backwards-compatible, and thus this is no longer a drop-in replacement for the v1beta2 version.
src/reporter.cc
Outdated
<< " User-Agent: " << user_agent | ||
<< " " << *update_metadata_request; | ||
} | ||
if (use_batch) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why would you ever not use batch?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added the switch since the batch endpoint was not ready. Even now, it is not quite working yet.
src/reporter.cc
Outdated
const std::string location) const { | ||
|
||
int num_dashes = std::count(location.begin(), location.end(), '-'); | ||
if (num_dashes == 2) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yuck! This API is broken.
src/kubernetes.cc
Outdated
reader_.WatchEndpoints(cb); | ||
}); | ||
} | ||
service_watch_thread_ = std::thread([=]() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are still cluster-level, aren't they? Are you going to have every node agent watch for services and endpoints?
I would also prefer to keep the KubernetesServiceMetadata
option, at least for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes - they are still cluster-level. Added back the two checks.
What does keeping the KubernetesServiceMetadata
option for now mean? Would it only apply to services and endpoints? Or other cluster level resources too?
src/kubernetes.h
Outdated
MetadataUpdater::UpdateCallback callback) const; | ||
|
||
// Service watcher. | ||
void WatchServices(MetadataUpdater::UpdateCallback callback); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is done, right?
82e0f72
to
01277e5
Compare
The related config variables have been kept around for now.
…adataCallback. The ResourceMetadata now has a full_resource_name component. Use "" as a dummy full_resource_name when initiliazing ResourceMetadata.
Drop all code for watching services and endpoints.
Main change is to handle batch requests to the v1beta3 endpoint.
Also, update the GetPodMetadata / GetNodeMetadata tests to test all properties of the Metadata object.
For services and endpoints, we use generic code, since computing resource full name, type, location etc does not need to be type specific.
The API is about to deprecate it.
The batch endpoint works fine now, so we no longer need the switch. However, batch requests need > 1 individual requests inside, so we still have the code to send a single request without the batch wrapper.
This allows the updated agent to be a drop in replacement for the v1beta2 version of the agent.
When we happen to have a single pending request, make a duplicate, without the "views" field, and send it in a batch request.
14cd869
to
f46fc20
Compare
8b06da6
to
74f1e02
Compare
9eb2e79
to
a8e609c
Compare
This PR deletes all docker related code, drops k8s cluster / services / endpoints, and allows sending nodes and pods to the v1beta3 API