-
Notifications
You must be signed in to change notification settings - Fork 11
Add support for collecting services. #112
Add support for collecting services. #112
Conversation
igorpeshansky
left a comment
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.
The basic implementation structure looks good.
src/kubernetes.cc
Outdated
| return std::move(result); | ||
| } | ||
|
|
||
|
|
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.
No need for an extra blank line 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.
done
src/kubernetes.cc
Outdated
|
|
||
| std::vector<json::value> KubernetesReader::GetServiceList( | ||
| const std::string cluster_name, const std::string location | ||
| ) const throw(json::Exception) { |
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 better to format this as:
std::vector<json::value> KubernetesReader::GetServiceList(
const std::string& cluster_name, const std::string& location) const
throw(json::Exception) {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.
done
src/kubernetes.cc
Outdated
|
|
||
|
|
||
| std::vector<json::value> KubernetesReader::GetServiceList( | ||
| const std::string cluster_name, const std::string location |
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.
const std::string& in both cases.
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.
done
src/kubernetes.cc
Outdated
| ) const throw(json::Exception) { | ||
| std::lock_guard<std::recursive_mutex> lock(service_mutex_); | ||
| std::vector<json::value> service_list; | ||
| for (auto const& service_it : service_to_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.
const auto& is more conventional...
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.
done
src/kubernetes.h
Outdated
| // A memoized map from an encoded owner reference to the owner object. | ||
| mutable std::map<std::string, json::value> owners_; | ||
| // Mutex for the service related caches. | ||
| mutable std::recursive_mutex service_mutex_; |
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.
Do you expect to ever call a function while holding this lock that would need to re-acquire the lock? If not, you can just make this an std::mutex instead.
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.
changed - it is not being re-acquired right now.
src/kubernetes.cc
Outdated
|
|
||
| // TODO: using a temporary did not work here. | ||
| std::vector<MetadataUpdater::ResourceMetadata> result_vector; | ||
| result_vector.emplace_back(GetClusterMetadata(collected_at, is_deleted)); |
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.
Careful — this is_deleted refers to the service, right? You don't want to notify the API that the whole cluster has been deleted just because one service was. I would suggest just not having an is_deleted parameter in GetClusterMetadata.
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
src/kubernetes.cc
Outdated
| WatchMaster( | ||
| "Service", | ||
| std::string(kKubernetesEndpointPath) + "/watch/services/", | ||
| [=](const json::Object* service, Timestamp collected_at, bool is_deleted) { |
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.
Fit in 80 columns?
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.
fixed - it was too long
src/kubernetes.cc
Outdated
|
|
||
| // TODO: using a temporary did not work here. | ||
| std::vector<MetadataUpdater::ResourceMetadata> result_vector; | ||
| result_vector.emplace_back(GetClusterMetadata(collected_at, is_deleted)); |
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.
Same here — this is_deleted refers to the endpoints object.
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
| MetadataUpdater::UpdateCallback callback, | ||
| const json::Object* endpoints, Timestamp collected_at, bool is_deleted) | ||
| throw(json::Exception) { | ||
| UpdateServiceToPodsCache(endpoints, is_deleted); |
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.
What does it mean for an endpoint to be deleted? Can one be deleted without the corresponding service being deleted, or are they always correlated?
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.
the two are correlated - endpoints is deleted when the service is deleted.
src/kubernetes.cc
Outdated
| pod_watch_thread_ = std::thread([=]() { | ||
| reader_.WatchPods(watched_node, cb); | ||
| }); | ||
| if (config().KubernetesClusterLevelMetadata()) { |
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 wonder if it makes sense to define an extra option just for service metadata? Or will we always want to retrieve it along with unscheduled pods?
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.
Added a separate option. I wonder how the the two flags interact - i.e. if KubernetesClusterLevelMetadata is false, does it make sense for KubernetesServiceMetadata to be true?
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.
Well, KubernetesClusterLevelMetadata means it's running the separate instance at the cluster level, rather than the per-node one. There are many things we can watch at cluster level. KubernetesServiceMetadata controls specifically whether we watch services/endpoints at cluster level. So KubernetesServiceMetadata is ignored when KubernetesClusterLevelMetadata is false, but it can certainly be set to true. See my other comment about guarding the watch threads.
e0ba7df to
202503c
Compare
src/kubernetes.cc
Outdated
| auto endpoints_it = service_to_pods_.find(service_key); | ||
| const std::vector<std::string>& pod_names = | ||
| (endpoints_it != service_to_pods_.end()) ? endpoints_it->second | ||
| : kNoPods; |
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.
Something's off with the indentation 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.
aligned the "?" and ":"
src/kubernetes.h
Outdated
| void UpdateServiceToPodsCache( | ||
| const json::Object* endpoints, bool is_deleted) throw(json::Exception); | ||
|
|
||
| // Const data. |
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 isn't helpful. How about // An empty vector value for endpoints that have no pods.?
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.
done
src/kubernetes.cc
Outdated
| k8s_cluster, | ||
| #ifdef ENABLE_KUBERNETES_METADATA | ||
| MetadataStore::Metadata(config_.MetadataIngestionRawContentVersion(), | ||
| /*is_deleted=*/ false, created_at, collected_at, |
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.
No space after comment (so it reads /*is_deleted=*/false).
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.
done
src/kubernetes.cc
Outdated
| const json::Object* metadata = service->Get<json::Object>("metadata"); | ||
| const std::string namespace_name = metadata->Get<json::String>("namespace"); | ||
| const std::string service_name = metadata->Get<json::String>("name"); | ||
| const std::string encoded_ref = boost::algorithm::join( |
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.
D'oh. Even better! Yes, please!
src/kubernetes.cc
Outdated
| } else { | ||
| auto it_inserted = | ||
| service_to_pods_.emplace(encoded_ref, std::vector<std::string>()); | ||
| service_to_pods_.at(encoded_ref) = pod_names; |
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.
Let's avoid the extra lookup, and use it_inserted.first->second instead.
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.
done
src/kubernetes.h
Outdated
| // Return the cluster metadata based on the cached values for | ||
| // service_to_metadta_ and service_to_pods_. | ||
| MetadataUpdater::ResourceMetadata GetClusterMetadata( | ||
| Timestamp collected_at) const throw(json::Exception); |
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 can be:
MetadataUpdater::ResourceMetadata GetClusterMetadata(Timestamp collected_at)
const throw(json::Exception);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.
done
src/configuration.cc
Outdated
| kubernetes_cluster_level_metadata_( | ||
| kKubernetesDefaultClusterLevelMetadata), | ||
| kubernetes_service_metadata_( | ||
| kKubernetesDefaultServiceMetadata), |
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.
Fits on one line.
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.
done
src/kubernetes.cc
Outdated
| pod_watch_thread_ = std::thread([=]() { | ||
| reader_.WatchPods(watched_node, cb); | ||
| }); | ||
| if (config().KubernetesServiceMetadata()) { |
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 actually needs both config().KubernetesClusterLevelMetadata() && config().KubernetesServiceMetadata().
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.
done
src/kubernetes.cc
Outdated
| if (service_it == service_to_pods_.end()) { | ||
| service_to_pods_.emplace(encoded_ref, pod_names); | ||
| } else { | ||
| service_it->second = pod_names; |
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.
Ah, you're right. I forgot that we have to re-construct the k8s_cluster resource each time. Oh, well.
I am wondering whether the cost of copying large vectors around would be comparable with the cost of constructing the vector in-place, but we can defer it to later (or, optionally, add a TODO to investigate).
src/kubernetes.cc
Outdated
| pod_watch_thread_ = std::thread([=]() { | ||
| reader_.WatchPods(watched_node, cb); | ||
| }); | ||
| if (config().KubernetesClusterLevelMetadata()) { |
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.
Well, KubernetesClusterLevelMetadata means it's running the separate instance at the cluster level, rather than the per-node one. There are many things we can watch at cluster level. KubernetesServiceMetadata controls specifically whether we watch services/endpoints at cluster level. So KubernetesServiceMetadata is ignored when KubernetesClusterLevelMetadata is false, but it can certainly be set to true. See my other comment about guarding the watch threads.
src/kubernetes.h
Outdated
| mutable std::mutex service_mutex_; | ||
| // Map from service key to service metadata. This map is built based on the | ||
| // response from WatchServices. | ||
| mutable std::map<std::pair<std::string, 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.
[Optional] You can define a private helper type:
using ServiceKey = std::pair<std::string, std::string>;
// Map from service key to service metadata. This map is built based on the
// response from WatchServices.
mutable std::map<ServiceKey, json::value> service_to_metadata_;
// Map from service key to names of pods in the service. This map is built
// based on the response from WatchEndpoints.
mutable std::map<ServiceKey, std::vector<std::string>> service_to_pods_;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.
done
| version_to_kind_to_name_; | ||
| // A memoized map from an encoded owner reference to the owner object. | ||
| mutable std::map<std::string, json::value> owners_; | ||
| // Mutex for the service related caches. |
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.
Let's add a blank line before this group of variables.
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.
done
src/kubernetes.cc
Outdated
| const json::Object* metadata = service->Get<json::Object>("metadata"); | ||
| const std::string namespace_name = metadata->Get<json::String>("namespace"); | ||
| const std::string service_name = metadata->Get<json::String>("name"); | ||
| const std::pair<std::string, std::string> service_key ( |
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.
No space before the ('.
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.
done
src/kubernetes.cc
Outdated
| const std::string namespace_name = metadata->Get<json::String>("namespace"); | ||
| // Endpoints name is same as the matching service name. | ||
| const std::string service_name = metadata->Get<json::String>("name"); | ||
| const std::pair<std::string, std::string> service_key ( |
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.
No space before the ('.
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.
done
src/configuration.cc
Outdated
| constexpr const char kKubernetesDefaultNodeName[] = ""; | ||
| constexpr const bool kKubernetesDefaultUseWatch = true; | ||
| constexpr const bool kKubernetesDefaultClusterLevelMetadata = false; | ||
| constexpr const bool kKubernetesDefaultServiceMetadata = false; |
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.
[Optional] Now that you have an additional guard, this can default to true...
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.
since the cluster level flag is already false, prefer to have it be the same.
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 would mean that users would have to enable cluster-level watches and the service watches. I would have thought they'd want services by default if they're running at cluster level...
Note: I just turned KubernetesUseWatch off by default, so that's an additional guard, too. So, back to the original question: if a customer runs the agent and explicitly turns on both KubernetesUseWatch and KubernetesClusterLevelMetadata, should they expect to see service metadata? I would guess yes.
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.
done
src/configuration.cc
Outdated
| constexpr const char kKubernetesDefaultNodeName[] = ""; | ||
| constexpr const bool kKubernetesDefaultUseWatch = true; | ||
| constexpr const bool kKubernetesDefaultClusterLevelMetadata = false; | ||
| constexpr const bool kKubernetesDefaultServiceMetadata = false; |
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 would mean that users would have to enable cluster-level watches and the service watches. I would have thought they'd want services by default if they're running at cluster level...
Note: I just turned KubernetesUseWatch off by default, so that's an additional guard, too. So, back to the original question: if a customer runs the agent and explicitly turns on both KubernetesUseWatch and KubernetesClusterLevelMetadata, should they expect to see service metadata? I would guess yes.
src/kubernetes.h
Outdated
| // Mutex for the service related caches. | ||
| mutable std::mutex service_mutex_; | ||
|
|
||
| using ServiceKey = std::pair<std::string, 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.
Let's just put this type before the mutex and remove the blank line between them (i.e., have one blank line that delimits this type and the data from the previous data fields).
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.
done
igorpeshansky
left a comment
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.
LGTM ![]()
igorpeshansky
left a comment
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.
Reviewing tests.
test/kubernetes_unittest.cc
Outdated
|
|
||
| void UpdateServiceToMetadataCache( | ||
| KubernetesReader& reader, const json::Object* service, | ||
| bool is_deleted) |
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.
Fits on the previous line.
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.
done
test/kubernetes_unittest.cc
Outdated
|
|
||
| void UpdateServiceToPodsCache( | ||
| KubernetesReader& reader, const json::Object* endpoints, | ||
| bool is_deleted) |
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.
Fits on the previous line.
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.
done
test/kubernetes_unittest.cc
Outdated
| } | ||
|
|
||
| void UpdateServiceToMetadataCache( | ||
| KubernetesReader& reader, const json::Object* service, |
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.
Let's prefer pointers to non-const references (style guide). Also in UpdateServiceToPodsCache.
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.
done
| } | ||
|
|
||
| TEST_F(KubernetesTest, GetClusterMetadataEmpty) { | ||
| Configuration config(std::stringstream( |
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.
std::istringstream everywhere.
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.
done
test/kubernetes_unittest.cc
Outdated
| Environment environment(config); | ||
| KubernetesReader reader(config, nullptr); // Don't need HealthChecker. | ||
| const auto m = GetClusterMetadata(reader, Timestamp()); | ||
| EXPECT_EQ(0, m.ids().size()); |
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.
EXPECT_TRUE(m.ids().empty()). Also below.
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.
done
test/kubernetes_unittest.cc
Outdated
| {"location", "TestClusterLocation"}, | ||
| }), m.resource()); | ||
| EXPECT_EQ("TestVersion", m.metadata().version); | ||
| EXPECT_EQ(false, m.metadata().is_deleted); |
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.
EXPECT_FALSE(m.metadata().is_deleted). Also below.
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.
done
test/kubernetes_unittest.cc
Outdated
| {"metadata", json::object({ | ||
| {"name", json::string("testname")}, | ||
| {"namespace", json::string("testnamespace")}, | ||
| })} |
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.
Let's keep the trailing comma.
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.
done
test/kubernetes_unittest.cc
Outdated
| {"metadata", json::object({ | ||
| {"name", json::string("testname")}, | ||
| {"namespace", json::string("testnamespace")}, | ||
| })} |
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.
Trailing comma.
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.
done
test/kubernetes_unittest.cc
Outdated
| json::object({ | ||
| {"api", json::object({ | ||
| {"pods", json::array({ | ||
| pod_mr.ToJSON(), |
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.
2-space indent.
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.
done
test/kubernetes_unittest.cc
Outdated
| }); | ||
| KubernetesReader reader(config, nullptr); // Don't need HealthChecker. | ||
| UpdateServiceToMetadataCache( | ||
| reader, service->As<json::Object>(), /*is_deleted=*/false); |
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.
Do we need to also test deleted services in a separate test?
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.
added a separate test.
ce9b650 to
4865a82
Compare
test/kubernetes_unittest.cc
Outdated
| UpdateServiceToMetadataCache( | ||
| &reader, service->As<json::Object>(), /*is_deleted=*/false); | ||
| const auto m = GetClusterMetadata(reader, Timestamp()); | ||
| EXPECT_EQ(0, m.ids().size()); |
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.
EXPECT_TRUE(m.ids().empty()).
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.
done
igorpeshansky
left a comment
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.
LGTM ![]()
src/kubernetes.cc
Outdated
| std::vector<json::value> service_list; | ||
| for (const auto& service_it : service_to_metadata_) { | ||
| const std::string& service_key = service_it.first; | ||
| const std::string namespace_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.
Adding a comment that explains what we're extracting would be super helpful.
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.
Done - both here, and a line in the header file.
| EXPECT_EQ("", config.KubernetesClusterLocation()); | ||
| EXPECT_EQ("", config.KubernetesNodeName()); | ||
| EXPECT_EQ(true, config.KubernetesUseWatch()); | ||
| EXPECT_EQ(false, config.KubernetesClusterLevelMetadata()); |
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.
Should we rename this to KubernetesClusterMetadata? I'm not sure what Level is implying.
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 flag is not new in this PR - it is basically set to True if users want cluster level watch for unscheduled pods + service metadata.
The one added here is below: KubernetesServiceMetadata(). I was just updating the unittest to take care of a missing default flag.
I agree that we need documentation around their usage.
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.
"Cluster-level" is the opposite of "node-level". It includes, e.g., unscheduled pods, which are not part of the cluster resource metadata.
| } | ||
|
|
||
| void KubernetesReader::UpdateServiceToPodsCache( | ||
| const json::Object* endpoints, bool is_deleted) throw(json::Exception) { |
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.
Endpoints represents a single endpoint, could we rename this to be singular throughout?
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.
https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.10/#endpoints-v1-core
The resource is called Endpoints, not Endpoint, since it lists all endpoints used by a single service.
Added comments to this method in the header file.
| } | ||
| } | ||
|
|
||
| void KubernetesReader::UpdateServiceToPodsCache( |
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 a little concerned calling this UpdateServiceToPodsCache, a service itself doesn't have pods, the endpoint does. I may have missed a lot of the conversation, but I'm of the opinion that we should address endpoints as endpoints internally, even if we end up mapping it to a service at the end.
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 really is the service that has the pods - Endpoints is just an API that provides the mapping. According to the docs:
Kubernetes offers a simple Endpoints API that is updated whenever the set of Pods in a Service changes.
src/kubernetes.cc
Outdated
| const json::value& service_metadata = service_it.second; | ||
| auto endpoints_it = service_to_pods_.find(service_key); | ||
| const std::vector<std::string>& pod_names = | ||
| (endpoints_it != service_to_pods_.end()) ? endpoints_it->second |
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 an extension of what caused my confusion, I feel like it would be clearer to retain "endpoints_to_pods_", with a shared service key, so that this line makes sense when we read it 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.
see the other comment - the pods really belong to the service, so I prefer to keep the name.
Hope the renaming of the local iterators helps - at this point the source matters less, we should just be referring to the caches with what they contain.
igorpeshansky
left a comment
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.
Looks even better!
| EXPECT_EQ("", config.KubernetesClusterLocation()); | ||
| EXPECT_EQ("", config.KubernetesNodeName()); | ||
| EXPECT_EQ(true, config.KubernetesUseWatch()); | ||
| EXPECT_EQ(false, config.KubernetesClusterLevelMetadata()); |
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.
"Cluster-level" is the opposite of "node-level". It includes, e.g., unscheduled pods, which are not part of the cluster resource metadata.
src/kubernetes.h
Outdated
| // A memoized map from an encoded owner reference to the owner object. | ||
| mutable std::map<std::string, json::value> owners_; | ||
|
|
||
| // Unique identifier of a service in a cluster, based on the namespace 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.
How about: // ServiceKey is a pair of the namespace name and the service name that uniquely identifies a service in a cluster.?
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.
done
src/kubernetes.cc
Outdated
| std::lock_guard<std::mutex> lock(service_mutex_); | ||
| std::vector<json::value> service_list; | ||
| for (const auto& metadata_it : service_to_metadata_) { | ||
| // service_key is a std::pair containing (namespace_name, service_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 seems really redundant... You could have said something like: // The namespace name is the first component of the service key., but even that basically replicates the code in line 464.
Maybe just // A service key consists of a namespace name and a service 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.
done
igorpeshansky
left a comment
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.
LGTM ![]()
7240c18 to
1dab2f2
Compare
bmoyles0117
left a comment
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.
LGTM
|
Looks like you need to rebase again. |
1dab2f2 to
2a7223c
Compare
|
Rebased and tested locally. |
Will add unit tests in the same PR. Would like your feedback on the code first.