From a3751e2a731af91292a90b097ca12229e386f7e5 Mon Sep 17 00:00:00 2001 From: Ken Simon Date: Mon, 28 Aug 2017 13:20:06 -0700 Subject: [PATCH] Query ServerGroups to see supported API versions We're storing them in /servergroups.json for now, may move this to /server/groups.json later (and move /serverversion.json to /server/version.json as well) Signed-off-by: Ken Simon --- config.json | 1 + docs/configuration.md | 1 + .../ksonnet/components/10-configmaps.jsonnet | 1 + examples/quickstart/aggregate.yaml | 1 + .../quickstart/components/10-configmaps.yaml | 1 + pkg/config/config.go | 11 +++++-- pkg/discovery/queries.go | 33 ++++++++++--------- pkg/discovery/queryrecorder.go | 6 ++++ 8 files changed, 38 insertions(+), 17 deletions(-) diff --git a/config.json b/config.json index efdd91118..7027ef327 100644 --- a/config.json +++ b/config.json @@ -34,6 +34,7 @@ "ResourceQuotas", "RoleBindings", "Roles", + "ServerGroups", "ServiceAccounts", "Services", "StatefulSets" diff --git a/docs/configuration.md b/docs/configuration.md index 0bf896b03..17f0ac51b 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -72,6 +72,7 @@ See [Parameter Reference][3] for a more detailed description of each setting. "RoleBindings", "Roles", "Secrets", + "ServerGroups", "ServiceAccounts", "Services", "StatefulSets" diff --git a/examples/ksonnet/components/10-configmaps.jsonnet b/examples/ksonnet/components/10-configmaps.jsonnet index af6b320be..cdb10e750 100644 --- a/examples/ksonnet/components/10-configmaps.jsonnet +++ b/examples/ksonnet/components/10-configmaps.jsonnet @@ -64,6 +64,7 @@ local sonobuoyConfigData = { "ResourceQuotas", "RoleBindings", "Roles", + "ServerGroups", "ServiceAccounts", "Services", "StatefulSets" diff --git a/examples/quickstart/aggregate.yaml b/examples/quickstart/aggregate.yaml index ae6a1df70..11bc996e3 100644 --- a/examples/quickstart/aggregate.yaml +++ b/examples/quickstart/aggregate.yaml @@ -91,6 +91,7 @@ data: "ResourceQuotas", "RoleBindings", "Roles", + "ServerGroups", "ServiceAccounts", "Services", "StatefulSets" diff --git a/examples/quickstart/components/10-configmaps.yaml b/examples/quickstart/components/10-configmaps.yaml index dcb695e06..26bb0cb65 100644 --- a/examples/quickstart/components/10-configmaps.yaml +++ b/examples/quickstart/components/10-configmaps.yaml @@ -48,6 +48,7 @@ data: "ResourceQuotas", "RoleBindings", "Roles", + "ServerGroups", "ServiceAccounts", "Services", "StatefulSets" diff --git a/pkg/config/config.go b/pkg/config/config.go index a6494038c..20b3ad8ef 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -35,7 +35,6 @@ var ClusterResources = []string{ "Nodes", "PersistentVolumes", "PodSecurityPolicies", - "ServerVersion", "StorageClasses", "ThirdPartyResources", } @@ -55,7 +54,6 @@ var NamespacedResources = []string{ "LimitRanges", "PersistentVolumeClaims", "PodDisruptionBudgets", - "PodLogs", "PodPresets", "PodTemplates", "Pods", @@ -70,6 +68,14 @@ var NamespacedResources = []string{ "StatefulSets", } +// SpecialResources are resources that aren't queried (or stored) the same was +// as the rest, so need special casing for querying them. +var SpecialResources = []string{ + "PodLogs", + "ServerGroups", + "ServerVersion", +} + // FilterOptions allow operators to select sets to include in a report type FilterOptions struct { Namespaces string `json:"Namespaces"` @@ -147,6 +153,7 @@ func NewWithDefaults() *Config { cfg.Resources = ClusterResources cfg.Resources = append(cfg.Resources, NamespacedResources...) + cfg.Resources = append(cfg.Resources, SpecialResources...) cfg.PluginNamespace = metav1.NamespaceSystem diff --git a/pkg/discovery/queries.go b/pkg/discovery/queries.go index 02f741dbf..26d58b58c 100644 --- a/pkg/discovery/queries.go +++ b/pkg/discovery/queries.go @@ -216,16 +216,13 @@ func QueryNSResources(kubeClient kubernetes.Interface, recorder *QueryRecorder, // 3. Execute the ns-query for resourceKind := range resources { - // We use annotations to tag resources as being namespaced vs not, skip any - // that aren't "ns" - if resourceKind != "PodLogs" { - lister := func() (runtime.Object, error) { return queryNsResource(ns, resourceKind, opts, kubeClient) } - query := func() (time.Duration, error) { return objListQuery(outdir+"/", resourceKind+".json", lister) } - timedQuery(recorder, resourceKind, ns, query) - } + lister := func() (runtime.Object, error) { return queryNsResource(ns, resourceKind, opts, kubeClient) } + query := func() (time.Duration, error) { return objListQuery(outdir+"/", resourceKind+".json", lister) } + timedQuery(recorder, resourceKind, ns, query) } - if resources["PodLogs"] { + specialResources := cfg.FilterResources(config.SpecialResources) + if specialResources["PodLogs"] { start := time.Now() err := gatherPodLogs(kubeClient, ns, opts, cfg) if err != nil { @@ -257,12 +254,9 @@ func QueryClusterResources(kubeClient kubernetes.Interface, recorder *QueryRecor // 2. Execute the non-ns-query for resourceKind := range resources { - // Eliminate special cases. - if resourceKind != "ServerVersion" { - lister := func() (runtime.Object, error) { return queryNonNsResource(resourceKind, kubeClient) } - query := func() (time.Duration, error) { return objListQuery(outdir+"/", resourceKind+".json", lister) } - timedQuery(recorder, resourceKind, "", query) - } + lister := func() (runtime.Object, error) { return queryNonNsResource(resourceKind, kubeClient) } + query := func() (time.Duration, error) { return objListQuery(outdir+"/", resourceKind+".json", lister) } + timedQuery(recorder, resourceKind, "", query) } // cfg.Nodes configures whether users want to gather the Nodes resource in the @@ -277,7 +271,8 @@ func QueryClusterResources(kubeClient kubernetes.Interface, recorder *QueryRecor recorder.RecordQuery("Nodes", "", duration, err) } - if resources["ServerVersion"] { + specialResources := cfg.FilterResources(config.SpecialResources) + if specialResources["ServerVersion"] { objqry := func() (interface{}, error) { return kubeClient.Discovery().ServerVersion() } query := func() (time.Duration, error) { return untypedQuery(cfg.OutputDir(), "serverversion.json", objqry) @@ -285,5 +280,13 @@ func QueryClusterResources(kubeClient kubernetes.Interface, recorder *QueryRecor timedQuery(recorder, "serverversion", "", query) } + if specialResources["ServerGroups"] { + objqry := func() (interface{}, error) { return kubeClient.Discovery().ServerGroups() } + query := func() (time.Duration, error) { + return untypedQuery(cfg.OutputDir(), "servergroups.json", objqry) + } + timedQuery(recorder, "servergroups", "", query) + } + return nil } diff --git a/pkg/discovery/queryrecorder.go b/pkg/discovery/queryrecorder.go index 9bd48273d..80030a411 100644 --- a/pkg/discovery/queryrecorder.go +++ b/pkg/discovery/queryrecorder.go @@ -21,6 +21,9 @@ import ( "os" "path" "time" + + "github.com/heptio/sonobuoy/pkg/errlog" + "github.com/pkg/errors" ) type QueryRecorder struct { @@ -42,6 +45,9 @@ type queryData struct { } func (q *QueryRecorder) RecordQuery(name string, namespace string, duration time.Duration, recerr error) { + if recerr != nil { + errlog.LogError(errors.Wrapf(recerr, "error querying %v", name)) + } summary := &queryData{ QueryObj: name, Namespace: namespace,