From 2f24e40eca26eb20609b628bf32b80a218329765 Mon Sep 17 00:00:00 2001 From: Supriya Garg Date: Tue, 27 Mar 2018 21:23:08 -0400 Subject: [PATCH 1/4] Update the FindTopLevelOwner function to extract only controllers. --- src/kubernetes.cc | 34 +++++++++++++++++++++++++--------- src/kubernetes.h | 6 +++--- 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/src/kubernetes.cc b/src/kubernetes.cc index ad2293b3..63f17166 100644 --- a/src/kubernetes.cc +++ b/src/kubernetes.cc @@ -154,7 +154,7 @@ json::value KubernetesReader::ComputePodAssociations(const json::Object* pod) const std::string namespace_name = metadata->Get("namespace"); const std::string pod_id = metadata->Get("uid"); - const json::value top_level = FindTopLevelOwner(namespace_name, pod->Clone()); + const json::value top_level = FindTopLevelController(namespace_name, pod->Clone()); const json::Object* top_level_controller = top_level->As(); const json::Object* top_level_metadata = top_level_controller->Get("metadata"); @@ -1033,7 +1033,7 @@ json::value KubernetesReader::GetOwner( return owner->Clone(); } -json::value KubernetesReader::FindTopLevelOwner( +json::value KubernetesReader::FindTopLevelController( const std::string& ns, json::value object) const throw(QueryException, json::Exception) { const json::Object* obj = object->As(); @@ -1042,27 +1042,43 @@ json::value KubernetesReader::FindTopLevelOwner( #endif const json::Object* metadata = obj->Get("metadata"); #ifdef VERBOSE - LOG(DEBUG) << "FindTopLevelOwner: metadata is " << *metadata; + LOG(DEBUG) << "FindTopLevelController: metadata is " << *metadata; #endif if (!metadata->Has("ownerReferences")) { #ifdef VERBOSE - LOG(DEBUG) << "FindTopLevelOwner: no owner references in " << *metadata; + LOG(DEBUG) << "FindTopLevelController: no owner references in " << *metadata; #endif return object; } const json::Array* refs = metadata->Get("ownerReferences"); #ifdef VERBOSE - LOG(DEBUG) << "FindTopLevelOwner: refs is " << *refs; + LOG(DEBUG) << "FindTopLevelController: refs is " << *refs; #endif - if (refs->size() > 1) { + std::vector controller_refs; + for (const json::value& ref : *refs) { + const json::Object* ref_obj = ref->As(); + if (ref_obj->Has("controller") && ref_obj->Get("controller")) { + controller_refs.emplace_back(*ref_obj); + } + } +#ifdef VERBOSE + LOG(DEBUG) << "FindTopLevelController: contoller_refs is " << controller_refs; +#endif + if (controller_refs.size() == 0) { +#ifdef VERBOSE + LOG(DEBUG) << "FindTopLevelController: no controller owner references in " << *metadata; +#endif + return object; + } + if (controller_refs.size() > 1) { LOG(WARNING) << "Found multiple owner references for " << *obj << " picking the first one arbitrarily."; } - const json::value& ref = (*refs)[0]; + const json::Object controller_ref = controller_refs[0]; #ifdef VERBOSE - LOG(DEBUG) << "FindTopLevelOwner: ref is " << *ref; + LOG(DEBUG) << "FindTopLevelController: controller_ref is " << controller_ref; #endif - return FindTopLevelOwner(ns, GetOwner(ns, ref->As())); + return FindTopLevelController(ns, GetOwner(ns, &controller_ref)); } bool KubernetesReader::ValidateConfiguration() const { diff --git a/src/kubernetes.h b/src/kubernetes.h index d8b5414a..329c6bde 100644 --- a/src/kubernetes.h +++ b/src/kubernetes.h @@ -136,9 +136,9 @@ class KubernetesReader { json::value GetOwner(const std::string& ns, const json::Object* owner_ref) const throw(QueryException, json::Exception); - // For a given object, returns the top-level owner object. - // When there are multiple owner references, follows the first one. - json::value FindTopLevelOwner(const std::string& ns, json::value object) const + // For a given object, returns the top-level controller object. + // When there are multiple controller references, follows the first one. + json::value FindTopLevelController(const std::string& ns, json::value object) const throw(QueryException, json::Exception); // Cached data. From 00bd7c276f8a59ed7b4f4dd2ec69b91d1bdf6889 Mon Sep 17 00:00:00 2001 From: Supriya Garg Date: Tue, 27 Mar 2018 23:09:02 -0400 Subject: [PATCH 2/4] Reformat long lines and use vector of --- src/kubernetes.cc | 23 ++++++++++++++--------- src/kubernetes.h | 3 ++- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/kubernetes.cc b/src/kubernetes.cc index 63f17166..154efc96 100644 --- a/src/kubernetes.cc +++ b/src/kubernetes.cc @@ -154,7 +154,8 @@ json::value KubernetesReader::ComputePodAssociations(const json::Object* pod) const std::string namespace_name = metadata->Get("namespace"); const std::string pod_id = metadata->Get("uid"); - const json::value top_level = FindTopLevelController(namespace_name, pod->Clone()); + const json::value top_level = FindTopLevelController( + namespace_name, pod->Clone()); const json::Object* top_level_controller = top_level->As(); const json::Object* top_level_metadata = top_level_controller->Get("metadata"); @@ -1046,7 +1047,8 @@ json::value KubernetesReader::FindTopLevelController( #endif if (!metadata->Has("ownerReferences")) { #ifdef VERBOSE - LOG(DEBUG) << "FindTopLevelController: no owner references in " << *metadata; + LOG(DEBUG) << "FindTopLevelController: no owner references in " + << *metadata; #endif return object; } @@ -1054,27 +1056,30 @@ json::value KubernetesReader::FindTopLevelController( #ifdef VERBOSE LOG(DEBUG) << "FindTopLevelController: refs is " << *refs; #endif - std::vector controller_refs; + std::vector controller_refs; for (const json::value& ref : *refs) { const json::Object* ref_obj = ref->As(); - if (ref_obj->Has("controller") && ref_obj->Get("controller")) { - controller_refs.emplace_back(*ref_obj); + if (ref_obj->Has("controller") && + ref_obj->Get("controller")) { + controller_refs.emplace_back(ref_obj); } } #ifdef VERBOSE - LOG(DEBUG) << "FindTopLevelController: contoller_refs is " << controller_refs; + LOG(DEBUG) << "FindTopLevelController: contoller_refs is " + << controller_refs; #endif if (controller_refs.size() == 0) { #ifdef VERBOSE - LOG(DEBUG) << "FindTopLevelController: no controller owner references in " << *metadata; + LOG(DEBUG) << "FindTopLevelController: no controller owner references in " + << *metadata; #endif return object; } if (controller_refs.size() > 1) { - LOG(WARNING) << "Found multiple owner references for " << *obj + LOG(WARNING) << "Found multiple controller references for " << *obj << " picking the first one arbitrarily."; } - const json::Object controller_ref = controller_refs[0]; + const json::Object controller_ref = *controller_refs[0]; #ifdef VERBOSE LOG(DEBUG) << "FindTopLevelController: controller_ref is " << controller_ref; #endif diff --git a/src/kubernetes.h b/src/kubernetes.h index 329c6bde..e8f223de 100644 --- a/src/kubernetes.h +++ b/src/kubernetes.h @@ -138,7 +138,8 @@ class KubernetesReader { // For a given object, returns the top-level controller object. // When there are multiple controller references, follows the first one. - json::value FindTopLevelController(const std::string& ns, json::value object) const + json::value FindTopLevelController( + const std::string& ns, json::value object) const throw(QueryException, json::Exception); // Cached data. From 0159d573755449695784605d5ca2442d202a6faf Mon Sep 17 00:00:00 2001 From: Supriya Garg Date: Wed, 28 Mar 2018 10:33:15 -0400 Subject: [PATCH 3/4] Update controller logic to only extract the first controller. --- src/kubernetes.cc | 27 +++++++++++---------------- src/kubernetes.h | 5 ++--- 2 files changed, 13 insertions(+), 19 deletions(-) diff --git a/src/kubernetes.cc b/src/kubernetes.cc index 154efc96..6c559b2c 100644 --- a/src/kubernetes.cc +++ b/src/kubernetes.cc @@ -1053,37 +1053,32 @@ json::value KubernetesReader::FindTopLevelController( return object; } const json::Array* refs = metadata->Get("ownerReferences"); + #ifdef VERBOSE LOG(DEBUG) << "FindTopLevelController: refs is " << *refs; #endif - std::vector controller_refs; + // Kubernetes objects are supposed to have at most one controller: + // https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.10/#objectmeta-v1-meta. + const json::Object* controller_ref = nullptr; for (const json::value& ref : *refs) { const json::Object* ref_obj = ref->As(); if (ref_obj->Has("controller") && ref_obj->Get("controller")) { - controller_refs.emplace_back(ref_obj); + controller_ref = ref_obj; + break; } } + if (!controller_ref) { #ifdef VERBOSE - LOG(DEBUG) << "FindTopLevelController: contoller_refs is " - << controller_refs; -#endif - if (controller_refs.size() == 0) { -#ifdef VERBOSE - LOG(DEBUG) << "FindTopLevelController: no controller owner references in " - << *metadata; + LOG(DEBUG) << "FindTopLevelController: no controller references in " + << *refs; #endif return object; } - if (controller_refs.size() > 1) { - LOG(WARNING) << "Found multiple controller references for " << *obj - << " picking the first one arbitrarily."; - } - const json::Object controller_ref = *controller_refs[0]; #ifdef VERBOSE - LOG(DEBUG) << "FindTopLevelController: controller_ref is " << controller_ref; + LOG(DEBUG) << "FindTopLevelController: controller_ref is " << *controller_ref; #endif - return FindTopLevelController(ns, GetOwner(ns, &controller_ref)); + return FindTopLevelController(ns, GetOwner(ns, controller_ref)); } bool KubernetesReader::ValidateConfiguration() const { diff --git a/src/kubernetes.h b/src/kubernetes.h index e8f223de..a19b5b3f 100644 --- a/src/kubernetes.h +++ b/src/kubernetes.h @@ -138,9 +138,8 @@ class KubernetesReader { // For a given object, returns the top-level controller object. // When there are multiple controller references, follows the first one. - json::value FindTopLevelController( - const std::string& ns, json::value object) const - throw(QueryException, json::Exception); + json::value FindTopLevelController(const std::string& ns, json::value object) + const throw(QueryException, json::Exception); // Cached data. mutable std::recursive_mutex mutex_; From 5b6ca70b3c4f93f03d0c5ea08d69af8991073b60 Mon Sep 17 00:00:00 2001 From: Supriya Garg Date: Wed, 28 Mar 2018 10:48:44 -0400 Subject: [PATCH 4/4] Address comments --- src/kubernetes.cc | 2 +- src/kubernetes.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/kubernetes.cc b/src/kubernetes.cc index 6c559b2c..93a7f9b5 100644 --- a/src/kubernetes.cc +++ b/src/kubernetes.cc @@ -1053,10 +1053,10 @@ json::value KubernetesReader::FindTopLevelController( return object; } const json::Array* refs = metadata->Get("ownerReferences"); - #ifdef VERBOSE LOG(DEBUG) << "FindTopLevelController: refs is " << *refs; #endif + // Kubernetes objects are supposed to have at most one controller: // https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.10/#objectmeta-v1-meta. const json::Object* controller_ref = nullptr; diff --git a/src/kubernetes.h b/src/kubernetes.h index a19b5b3f..6e3b7b0f 100644 --- a/src/kubernetes.h +++ b/src/kubernetes.h @@ -137,7 +137,6 @@ class KubernetesReader { const throw(QueryException, json::Exception); // For a given object, returns the top-level controller object. - // When there are multiple controller references, follows the first one. json::value FindTopLevelController(const std::string& ns, json::value object) const throw(QueryException, json::Exception);