diff --git a/.gitignore b/.gitignore index f3dd882a25..13bdd05a6d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ kube-state-metrics +documented_metrics +tested_metrics # Created by https://www.gitignore.io/api/go diff --git a/Makefile b/Makefile index 87d7aee49e..db6986fbbf 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ ARCH ?= $(shell go env GOARCH) BuildDate = $(shell date -u +'%Y-%m-%dT%H:%M:%SZ') Commit = $(shell git rev-parse --short HEAD) ALL_ARCH = amd64 arm arm64 ppc64le s390x -PKG=k8s.io/kube-state-metrics +PKG=k8s.io/kube-state-metrics/pkg GO_VERSION=1.10.1 IMAGE = $(REGISTRY)/kube-state-metrics @@ -19,7 +19,7 @@ gofmtcheck: doccheck: @echo "- Checking if documentation is up to date..." @grep -hoE '(kube_[^ |]+)' Documentation/* | sort -u > documented_metrics - @sed -n 's/.*# TYPE \(kube_[^ ]\+\).*/\1/p' collectors/*_test.go | sort -u > tested_metrics + @sed -n 's/.*# TYPE \(kube_[^ ]\+\).*/\1/p' pkg/collectors/*_test.go | sort -u > tested_metrics @diff -u0 tested_metrics documented_metrics || (echo "ERROR: Metrics with - are present in tests but missing in documentation, metrics with + are documented but not tested."; exit 1) @echo OK @rm -f tested_metrics documented_metrics diff --git a/main.go b/main.go index cedb69160e..580b06f681 100644 --- a/main.go +++ b/main.go @@ -17,14 +17,12 @@ limitations under the License. package main import ( - "flag" "fmt" "log" "net" "net/http" "net/http/pprof" "os" - "sort" "strconv" "strings" @@ -32,13 +30,12 @@ import ( "github.com/openshift/origin/pkg/util/proc" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp" - "github.com/spf13/pflag" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" clientset "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/clientcmd" - kcollectors "k8s.io/kube-state-metrics/collectors" - "k8s.io/kube-state-metrics/version" + kcollectors "k8s.io/kube-state-metrics/pkg/collectors" + "k8s.io/kube-state-metrics/pkg/options" + "k8s.io/kube-state-metrics/pkg/version" ) const ( @@ -46,52 +43,6 @@ const ( healthzPath = "/healthz" ) -var ( - defaultNamespaces = namespaceList{metav1.NamespaceAll} - defaultCollectors = collectorSet{ - "daemonsets": struct{}{}, - "deployments": struct{}{}, - "limitranges": struct{}{}, - "nodes": struct{}{}, - "pods": struct{}{}, - "replicasets": struct{}{}, - "replicationcontrollers": struct{}{}, - "resourcequotas": struct{}{}, - "services": struct{}{}, - "jobs": struct{}{}, - "cronjobs": struct{}{}, - "statefulsets": struct{}{}, - "persistentvolumes": struct{}{}, - "persistentvolumeclaims": struct{}{}, - "namespaces": struct{}{}, - "horizontalpodautoscalers": struct{}{}, - "endpoints": struct{}{}, - "secrets": struct{}{}, - "configmaps": struct{}{}, - } - availableCollectors = map[string]func(registry prometheus.Registerer, kubeClient clientset.Interface, namespaces []string){ - "cronjobs": kcollectors.RegisterCronJobCollector, - "daemonsets": kcollectors.RegisterDaemonSetCollector, - "deployments": kcollectors.RegisterDeploymentCollector, - "jobs": kcollectors.RegisterJobCollector, - "limitranges": kcollectors.RegisterLimitRangeCollector, - "nodes": kcollectors.RegisterNodeCollector, - "pods": kcollectors.RegisterPodCollector, - "replicasets": kcollectors.RegisterReplicaSetCollector, - "replicationcontrollers": kcollectors.RegisterReplicationControllerCollector, - "resourcequotas": kcollectors.RegisterResourceQuotaCollector, - "services": kcollectors.RegisterServiceCollector, - "statefulsets": kcollectors.RegisterStatefulSetCollector, - "persistentvolumes": kcollectors.RegisterPersistentVolumeCollector, - "persistentvolumeclaims": kcollectors.RegisterPersistentVolumeClaimCollector, - "namespaces": kcollectors.RegisterNamespaceCollector, - "horizontalpodautoscalers": kcollectors.RegisterHorizontalPodAutoScalerCollector, - "endpoints": kcollectors.RegisterEndpointCollector, - "secrets": kcollectors.RegisterSecretCollector, - "configmaps": kcollectors.RegisterConfigMapCollector, - } -) - // promLogger implements promhttp.Logger type promLogger struct{} @@ -99,137 +50,38 @@ func (pl promLogger) Println(v ...interface{}) { glog.Error(v) } -type collectorSet map[string]struct{} - -func (c *collectorSet) String() string { - s := *c - ss := s.asSlice() - sort.Strings(ss) - return strings.Join(ss, ",") -} - -func (c *collectorSet) Set(value string) error { - s := *c - cols := strings.Split(value, ",") - for _, col := range cols { - col = strings.TrimSpace(col) - if len(col) != 0 { - _, ok := availableCollectors[col] - if !ok { - glog.Fatalf("Collector \"%s\" does not exist", col) - } - s[col] = struct{}{} - } - } - return nil -} - -func (c collectorSet) asSlice() []string { - cols := []string{} - for col := range c { - cols = append(cols, col) - } - return cols -} - -func (c collectorSet) isEmpty() bool { - return len(c.asSlice()) == 0 -} - -func (c *collectorSet) Type() string { - return "string" -} - -type namespaceList []string - -func (n *namespaceList) String() string { - return strings.Join(*n, ",") -} - -func (n *namespaceList) IsAllNamespaces() bool { - return len(*n) == 1 && (*n)[0] == metav1.NamespaceAll -} - -func (n *namespaceList) Set(value string) error { - splittedNamespaces := strings.Split(value, ",") - for _, ns := range splittedNamespaces { - ns = strings.TrimSpace(ns) - if len(ns) != 0 { - *n = append(*n, ns) - } - } - return nil -} - -func (n *namespaceList) Type() string { - return "string" -} - -type options struct { - apiserver string - kubeconfig string - help bool - port int - host string - telemetryPort int - telemetryHost string - collectors collectorSet - namespaces namespaceList - version bool -} - func main() { - options := &options{collectors: make(collectorSet)} - flags := pflag.NewFlagSet("", pflag.ExitOnError) - // add glog flags - flags.AddGoFlagSet(flag.CommandLine) - flags.Lookup("logtostderr").Value.Set("true") - flags.Lookup("logtostderr").DefValue = "true" - flags.Lookup("logtostderr").NoOptDefVal = "true" - flags.StringVar(&options.apiserver, "apiserver", "", `The URL of the apiserver to use as a master`) - flags.StringVar(&options.kubeconfig, "kubeconfig", "", "Absolute path to the kubeconfig file") - flags.BoolVarP(&options.help, "help", "h", false, "Print help text") - flags.IntVar(&options.port, "port", 80, `Port to expose metrics on.`) - flags.StringVar(&options.host, "host", "0.0.0.0", `Host to expose metrics on.`) - flags.IntVar(&options.telemetryPort, "telemetry-port", 81, `Port to expose kube-state-metrics self metrics on.`) - flags.StringVar(&options.telemetryHost, "telemetry-host", "0.0.0.0", `Host to expose kube-state-metrics self metrics on.`) - flags.Var(&options.collectors, "collectors", fmt.Sprintf("Comma-separated list of collectors to be enabled. Defaults to %q", &defaultCollectors)) - flags.Var(&options.namespaces, "namespace", fmt.Sprintf("Comma-separated list of namespaces to be enabled. Defaults to %q", &defaultNamespaces)) - flags.BoolVarP(&options.version, "version", "", false, "kube-state-metrics build version information") - - flags.Usage = func() { - fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0]) - flags.PrintDefaults() - } + opts := options.NewOptions() + opts.AddFlags() - err := flags.Parse(os.Args) + err := opts.Parse() if err != nil { glog.Fatalf("Error: %s", err) } - if options.version { + if opts.Version { fmt.Printf("%#v\n", version.GetVersion()) os.Exit(0) } - if options.help { - flags.Usage() + if opts.Help { + opts.Usage() os.Exit(0) } - var collectors collectorSet - if len(options.collectors) == 0 { + var collectors options.CollectorSet + if len(opts.Collectors) == 0 { glog.Info("Using default collectors") - collectors = defaultCollectors + collectors = options.DefaultCollectors } else { - collectors = options.collectors + collectors = opts.Collectors } - var namespaces namespaceList - if len(options.namespaces) == 0 { - namespaces = defaultNamespaces + var namespaces options.NamespaceList + if len(opts.Namespaces) == 0 { + namespaces = options.DefaultNamespaces } else { - namespaces = options.namespaces + namespaces = opts.Namespaces } if namespaces.IsAllNamespaces() { @@ -240,7 +92,7 @@ func main() { proc.StartReaper() - kubeClient, err := createKubeClient(options.apiserver, options.kubeconfig) + kubeClient, err := createKubeClient(opts.Apiserver, opts.Kubeconfig) if err != nil { glog.Fatalf("Failed to create client: %v", err) } @@ -250,11 +102,11 @@ func main() { ksmMetricsRegistry.Register(kcollectors.ScrapeErrorTotalMetric) ksmMetricsRegistry.Register(prometheus.NewProcessCollector(os.Getpid(), "")) ksmMetricsRegistry.Register(prometheus.NewGoCollector()) - go telemetryServer(ksmMetricsRegistry, options.telemetryHost, options.telemetryPort) + go telemetryServer(ksmMetricsRegistry, opts.TelemetryHost, opts.TelemetryPort) registry := prometheus.NewRegistry() registerCollectors(registry, kubeClient, collectors, namespaces) - metricsServer(registry, options.host, options.port) + metricsServer(registry, opts.Host, opts.Port) } func createKubeClient(apiserver string, kubeconfig string) (clientset.Interface, error) { @@ -347,10 +199,10 @@ func metricsServer(registry prometheus.Gatherer, host string, port int) { // registerCollectors creates and starts informers and initializes and // registers metrics for collection. -func registerCollectors(registry prometheus.Registerer, kubeClient clientset.Interface, enabledCollectors collectorSet, namespaces namespaceList) { +func registerCollectors(registry prometheus.Registerer, kubeClient clientset.Interface, enabledCollectors options.CollectorSet, namespaces options.NamespaceList) { activeCollectors := []string{} for c := range enabledCollectors { - f, ok := availableCollectors[c] + f, ok := options.AvailableCollectors[c] if ok { f(registry, kubeClient, namespaces) activeCollectors = append(activeCollectors, c) diff --git a/collectors/collectors.go b/pkg/collectors/collectors.go similarity index 100% rename from collectors/collectors.go rename to pkg/collectors/collectors.go diff --git a/collectors/configmap.go b/pkg/collectors/configmap.go similarity index 100% rename from collectors/configmap.go rename to pkg/collectors/configmap.go diff --git a/collectors/configmap_test.go b/pkg/collectors/configmap_test.go similarity index 98% rename from collectors/configmap_test.go rename to pkg/collectors/configmap_test.go index aefafb87bb..266ae316c9 100644 --- a/collectors/configmap_test.go +++ b/pkg/collectors/configmap_test.go @@ -21,7 +21,7 @@ import ( "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/kube-state-metrics/collectors/testutils" + "k8s.io/kube-state-metrics/pkg/collectors/testutils" ) type mockConfigMapStore struct { diff --git a/collectors/cronjob.go b/pkg/collectors/cronjob.go similarity index 100% rename from collectors/cronjob.go rename to pkg/collectors/cronjob.go diff --git a/collectors/cronjob_test.go b/pkg/collectors/cronjob_test.go similarity index 99% rename from collectors/cronjob_test.go rename to pkg/collectors/cronjob_test.go index f79201d55f..bea115cf85 100644 --- a/collectors/cronjob_test.go +++ b/pkg/collectors/cronjob_test.go @@ -25,7 +25,7 @@ import ( batchv1beta1 "k8s.io/api/batch/v1beta1" "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/kube-state-metrics/collectors/testutils" + "k8s.io/kube-state-metrics/pkg/collectors/testutils" ) var ( diff --git a/collectors/daemonset.go b/pkg/collectors/daemonset.go similarity index 100% rename from collectors/daemonset.go rename to pkg/collectors/daemonset.go diff --git a/collectors/daemonset_test.go b/pkg/collectors/daemonset_test.go similarity index 99% rename from collectors/daemonset_test.go rename to pkg/collectors/daemonset_test.go index c3fec466ee..632e2fe4f3 100644 --- a/collectors/daemonset_test.go +++ b/pkg/collectors/daemonset_test.go @@ -22,7 +22,7 @@ import ( "k8s.io/api/extensions/v1beta1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/kube-state-metrics/collectors/testutils" + "k8s.io/kube-state-metrics/pkg/collectors/testutils" ) type mockDaemonSetStore struct { diff --git a/collectors/deployment.go b/pkg/collectors/deployment.go similarity index 100% rename from collectors/deployment.go rename to pkg/collectors/deployment.go diff --git a/collectors/deployment_test.go b/pkg/collectors/deployment_test.go similarity index 99% rename from collectors/deployment_test.go rename to pkg/collectors/deployment_test.go index d4126ada83..a14a5270b5 100644 --- a/collectors/deployment_test.go +++ b/pkg/collectors/deployment_test.go @@ -23,7 +23,7 @@ import ( "k8s.io/api/extensions/v1beta1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" - "k8s.io/kube-state-metrics/collectors/testutils" + "k8s.io/kube-state-metrics/pkg/collectors/testutils" ) var ( diff --git a/collectors/endpoint.go b/pkg/collectors/endpoint.go similarity index 100% rename from collectors/endpoint.go rename to pkg/collectors/endpoint.go diff --git a/collectors/endpoint_test.go b/pkg/collectors/endpoint_test.go similarity index 98% rename from collectors/endpoint_test.go rename to pkg/collectors/endpoint_test.go index f11938825f..8b11691806 100644 --- a/collectors/endpoint_test.go +++ b/pkg/collectors/endpoint_test.go @@ -22,7 +22,7 @@ import ( "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/kube-state-metrics/collectors/testutils" + "k8s.io/kube-state-metrics/pkg/collectors/testutils" ) type mockEndpointStore struct { diff --git a/collectors/hpa.go b/pkg/collectors/hpa.go similarity index 100% rename from collectors/hpa.go rename to pkg/collectors/hpa.go diff --git a/collectors/hpa_test.go b/pkg/collectors/hpa_test.go similarity index 98% rename from collectors/hpa_test.go rename to pkg/collectors/hpa_test.go index 30da6467f4..73c4cc43a7 100644 --- a/collectors/hpa_test.go +++ b/pkg/collectors/hpa_test.go @@ -21,7 +21,7 @@ import ( autoscaling "k8s.io/api/autoscaling/v2beta1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/kube-state-metrics/collectors/testutils" + "k8s.io/kube-state-metrics/pkg/collectors/testutils" ) var ( diff --git a/collectors/job.go b/pkg/collectors/job.go similarity index 100% rename from collectors/job.go rename to pkg/collectors/job.go diff --git a/collectors/job_test.go b/pkg/collectors/job_test.go similarity index 99% rename from collectors/job_test.go rename to pkg/collectors/job_test.go index 4879c491f2..59403c0112 100644 --- a/collectors/job_test.go +++ b/pkg/collectors/job_test.go @@ -23,7 +23,7 @@ import ( v1batch "k8s.io/api/batch/v1" "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/kube-state-metrics/collectors/testutils" + "k8s.io/kube-state-metrics/pkg/collectors/testutils" ) var ( diff --git a/collectors/limitrange.go b/pkg/collectors/limitrange.go similarity index 100% rename from collectors/limitrange.go rename to pkg/collectors/limitrange.go diff --git a/collectors/limitrange_test.go b/pkg/collectors/limitrange_test.go similarity index 98% rename from collectors/limitrange_test.go rename to pkg/collectors/limitrange_test.go index 8c12e859d0..9226806c4b 100644 --- a/collectors/limitrange_test.go +++ b/pkg/collectors/limitrange_test.go @@ -23,7 +23,7 @@ import ( "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/kube-state-metrics/collectors/testutils" + "k8s.io/kube-state-metrics/pkg/collectors/testutils" ) type mockLimitRangeStore struct { diff --git a/collectors/namespace.go b/pkg/collectors/namespace.go similarity index 100% rename from collectors/namespace.go rename to pkg/collectors/namespace.go diff --git a/collectors/namespace_test.go b/pkg/collectors/namespace_test.go similarity index 98% rename from collectors/namespace_test.go rename to pkg/collectors/namespace_test.go index 3e2d159c59..6e11c273ef 100644 --- a/collectors/namespace_test.go +++ b/pkg/collectors/namespace_test.go @@ -22,7 +22,7 @@ import ( "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/kube-state-metrics/collectors/testutils" + "k8s.io/kube-state-metrics/pkg/collectors/testutils" ) type mockNamespaceStore struct { diff --git a/collectors/node.go b/pkg/collectors/node.go similarity index 100% rename from collectors/node.go rename to pkg/collectors/node.go diff --git a/collectors/node_test.go b/pkg/collectors/node_test.go similarity index 99% rename from collectors/node_test.go rename to pkg/collectors/node_test.go index 3a8d1387b2..81181e8fa8 100644 --- a/collectors/node_test.go +++ b/pkg/collectors/node_test.go @@ -23,7 +23,7 @@ import ( "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/kube-state-metrics/collectors/testutils" + "k8s.io/kube-state-metrics/pkg/collectors/testutils" ) type mockNodeStore struct { diff --git a/collectors/persistentvolume.go b/pkg/collectors/persistentvolume.go similarity index 100% rename from collectors/persistentvolume.go rename to pkg/collectors/persistentvolume.go diff --git a/collectors/persistentvolume_test.go b/pkg/collectors/persistentvolume_test.go similarity index 99% rename from collectors/persistentvolume_test.go rename to pkg/collectors/persistentvolume_test.go index b024474b4e..a64b9780a1 100644 --- a/collectors/persistentvolume_test.go +++ b/pkg/collectors/persistentvolume_test.go @@ -21,7 +21,7 @@ import ( "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/kube-state-metrics/collectors/testutils" + "k8s.io/kube-state-metrics/pkg/collectors/testutils" ) type mockPersistentVolumeStore struct { diff --git a/collectors/persistentvolumeclaim.go b/pkg/collectors/persistentvolumeclaim.go similarity index 100% rename from collectors/persistentvolumeclaim.go rename to pkg/collectors/persistentvolumeclaim.go diff --git a/collectors/persistentvolumeclaim_test.go b/pkg/collectors/persistentvolumeclaim_test.go similarity index 99% rename from collectors/persistentvolumeclaim_test.go rename to pkg/collectors/persistentvolumeclaim_test.go index 752a1da250..aef160c7e1 100644 --- a/collectors/persistentvolumeclaim_test.go +++ b/pkg/collectors/persistentvolumeclaim_test.go @@ -22,7 +22,7 @@ import ( "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/kube-state-metrics/collectors/testutils" + "k8s.io/kube-state-metrics/pkg/collectors/testutils" ) type mockPersistentVolumeClaimStore struct { diff --git a/collectors/pod.go b/pkg/collectors/pod.go similarity index 100% rename from collectors/pod.go rename to pkg/collectors/pod.go diff --git a/collectors/pod_test.go b/pkg/collectors/pod_test.go similarity index 99% rename from collectors/pod_test.go rename to pkg/collectors/pod_test.go index 8c3ab57a1d..b6a073ede9 100644 --- a/collectors/pod_test.go +++ b/pkg/collectors/pod_test.go @@ -23,7 +23,7 @@ import ( "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/kube-state-metrics/collectors/testutils" + "k8s.io/kube-state-metrics/pkg/collectors/testutils" "k8s.io/kubernetes/pkg/util/node" ) diff --git a/collectors/replicaset.go b/pkg/collectors/replicaset.go similarity index 100% rename from collectors/replicaset.go rename to pkg/collectors/replicaset.go diff --git a/collectors/replicaset_test.go b/pkg/collectors/replicaset_test.go similarity index 98% rename from collectors/replicaset_test.go rename to pkg/collectors/replicaset_test.go index 3114ace9b4..7da342bc62 100644 --- a/collectors/replicaset_test.go +++ b/pkg/collectors/replicaset_test.go @@ -22,7 +22,7 @@ import ( "k8s.io/api/extensions/v1beta1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/kube-state-metrics/collectors/testutils" + "k8s.io/kube-state-metrics/pkg/collectors/testutils" ) var ( diff --git a/collectors/replicationcontroller.go b/pkg/collectors/replicationcontroller.go similarity index 100% rename from collectors/replicationcontroller.go rename to pkg/collectors/replicationcontroller.go diff --git a/collectors/replicationcontroller_test.go b/pkg/collectors/replicationcontroller_test.go similarity index 99% rename from collectors/replicationcontroller_test.go rename to pkg/collectors/replicationcontroller_test.go index 84794e6bbc..a1373eb59a 100644 --- a/collectors/replicationcontroller_test.go +++ b/pkg/collectors/replicationcontroller_test.go @@ -22,7 +22,7 @@ import ( "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/kube-state-metrics/collectors/testutils" + "k8s.io/kube-state-metrics/pkg/collectors/testutils" ) var ( diff --git a/collectors/resourcequota.go b/pkg/collectors/resourcequota.go similarity index 100% rename from collectors/resourcequota.go rename to pkg/collectors/resourcequota.go diff --git a/collectors/resourcequota_test.go b/pkg/collectors/resourcequota_test.go similarity index 99% rename from collectors/resourcequota_test.go rename to pkg/collectors/resourcequota_test.go index 4f40823d30..642ffb6d2c 100644 --- a/collectors/resourcequota_test.go +++ b/pkg/collectors/resourcequota_test.go @@ -23,7 +23,7 @@ import ( "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/kube-state-metrics/collectors/testutils" + "k8s.io/kube-state-metrics/pkg/collectors/testutils" ) type mockResourceQuotaStore struct { diff --git a/collectors/secret.go b/pkg/collectors/secret.go similarity index 100% rename from collectors/secret.go rename to pkg/collectors/secret.go diff --git a/collectors/secret_test.go b/pkg/collectors/secret_test.go similarity index 98% rename from collectors/secret_test.go rename to pkg/collectors/secret_test.go index f273202469..8c6dbc5d0f 100644 --- a/collectors/secret_test.go +++ b/pkg/collectors/secret_test.go @@ -21,7 +21,7 @@ import ( "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/kube-state-metrics/collectors/testutils" + "k8s.io/kube-state-metrics/pkg/collectors/testutils" ) type mockSecretStore struct { diff --git a/collectors/service.go b/pkg/collectors/service.go similarity index 100% rename from collectors/service.go rename to pkg/collectors/service.go diff --git a/collectors/service_test.go b/pkg/collectors/service_test.go similarity index 98% rename from collectors/service_test.go rename to pkg/collectors/service_test.go index 507d88bcc1..a2ab02b375 100644 --- a/collectors/service_test.go +++ b/pkg/collectors/service_test.go @@ -22,7 +22,7 @@ import ( "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/kube-state-metrics/collectors/testutils" + "k8s.io/kube-state-metrics/pkg/collectors/testutils" ) type mockServiceStore struct { diff --git a/collectors/statefulset.go b/pkg/collectors/statefulset.go similarity index 100% rename from collectors/statefulset.go rename to pkg/collectors/statefulset.go diff --git a/collectors/statefulset_test.go b/pkg/collectors/statefulset_test.go similarity index 99% rename from collectors/statefulset_test.go rename to pkg/collectors/statefulset_test.go index 87f901d4ce..c9aecce57d 100644 --- a/collectors/statefulset_test.go +++ b/pkg/collectors/statefulset_test.go @@ -22,7 +22,7 @@ import ( "k8s.io/api/apps/v1beta1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/kube-state-metrics/collectors/testutils" + "k8s.io/kube-state-metrics/pkg/collectors/testutils" ) var ( diff --git a/collectors/testutils/testutils.go b/pkg/collectors/testutils/testutils.go similarity index 100% rename from collectors/testutils/testutils.go rename to pkg/collectors/testutils/testutils.go diff --git a/pkg/options/collector.go b/pkg/options/collector.go new file mode 100644 index 0000000000..7a530acac3 --- /dev/null +++ b/pkg/options/collector.go @@ -0,0 +1,70 @@ +/* +Copyright 2018 The Kubernetes Authors All rights reserved. + +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. +*/ + +package options + +import ( + "github.com/prometheus/client_golang/prometheus" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + clientset "k8s.io/client-go/kubernetes" + kcollectors "k8s.io/kube-state-metrics/pkg/collectors" +) + +var ( + DefaultNamespaces = NamespaceList{metav1.NamespaceAll} + DefaultCollectors = CollectorSet{ + "daemonsets": struct{}{}, + "deployments": struct{}{}, + "limitranges": struct{}{}, + "nodes": struct{}{}, + "pods": struct{}{}, + "replicasets": struct{}{}, + "replicationcontrollers": struct{}{}, + "resourcequotas": struct{}{}, + "services": struct{}{}, + "jobs": struct{}{}, + "cronjobs": struct{}{}, + "statefulsets": struct{}{}, + "persistentvolumes": struct{}{}, + "persistentvolumeclaims": struct{}{}, + "Namespaces": struct{}{}, + "horizontalpodautoscalers": struct{}{}, + "endpoints": struct{}{}, + "secrets": struct{}{}, + "configmaps": struct{}{}, + } + AvailableCollectors = map[string]func(registry prometheus.Registerer, kubeClient clientset.Interface, namespaces []string){ + "cronjobs": kcollectors.RegisterCronJobCollector, + "daemonsets": kcollectors.RegisterDaemonSetCollector, + "deployments": kcollectors.RegisterDeploymentCollector, + "jobs": kcollectors.RegisterJobCollector, + "limitranges": kcollectors.RegisterLimitRangeCollector, + "nodes": kcollectors.RegisterNodeCollector, + "pods": kcollectors.RegisterPodCollector, + "replicasets": kcollectors.RegisterReplicaSetCollector, + "replicationcontrollers": kcollectors.RegisterReplicationControllerCollector, + "resourcequotas": kcollectors.RegisterResourceQuotaCollector, + "services": kcollectors.RegisterServiceCollector, + "statefulsets": kcollectors.RegisterStatefulSetCollector, + "persistentvolumes": kcollectors.RegisterPersistentVolumeCollector, + "persistentvolumeclaims": kcollectors.RegisterPersistentVolumeClaimCollector, + "Namespaces": kcollectors.RegisterNamespaceCollector, + "horizontalpodautoscalers": kcollectors.RegisterHorizontalPodAutoScalerCollector, + "endpoints": kcollectors.RegisterEndpointCollector, + "secrets": kcollectors.RegisterSecretCollector, + "configmaps": kcollectors.RegisterConfigMapCollector, + } +) diff --git a/pkg/options/options.go b/pkg/options/options.go new file mode 100644 index 0000000000..2ab1478a61 --- /dev/null +++ b/pkg/options/options.go @@ -0,0 +1,78 @@ +/* +Copyright 2018 The Kubernetes Authors All rights reserved. + +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. +*/ + +package options + +import ( + "flag" + "fmt" + "os" + + "github.com/spf13/pflag" +) + +type options struct { + Apiserver string + Kubeconfig string + Help bool + Port int + Host string + TelemetryPort int + TelemetryHost string + Collectors CollectorSet + Namespaces NamespaceList + Version bool + + flags *pflag.FlagSet +} + +func NewOptions() *options { + return &options{} +} + +func (o *options) AddFlags() { + o.flags = pflag.NewFlagSet("", pflag.ExitOnError) + // add glog flags + o.flags.AddGoFlagSet(flag.CommandLine) + o.flags.Lookup("logtostderr").Value.Set("true") + o.flags.Lookup("logtostderr").DefValue = "true" + o.flags.Lookup("logtostderr").NoOptDefVal = "true" + + o.flags.Usage = func() { + fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0]) + o.flags.PrintDefaults() + } + + o.flags.StringVar(&o.Apiserver, "apiserver", "", `The URL of the apiserver to use as a master`) + o.flags.StringVar(&o.Kubeconfig, "kubeconfig", "", "Absolute path to the kubeconfig file") + o.flags.BoolVarP(&o.Help, "help", "h", false, "Print Help text") + o.flags.IntVar(&o.Port, "port", 80, `Port to expose metrics on.`) + o.flags.StringVar(&o.Host, "host", "0.0.0.0", `Host to expose metrics on.`) + o.flags.IntVar(&o.TelemetryPort, "telemetry-port", 81, `Port to expose kube-state-metrics self metrics on.`) + o.flags.StringVar(&o.TelemetryHost, "telemetry-host", "0.0.0.0", `Host to expose kube-state-metrics self metrics on.`) + o.flags.Var(&o.Collectors, "collectors", fmt.Sprintf("Comma-separated list of collectors to be enabled. Defaults to %q", &DefaultCollectors)) + o.flags.Var(&o.Namespaces, "namespace", fmt.Sprintf("Comma-separated list of namespaces to be enabled. Defaults to %q", &DefaultNamespaces)) + o.flags.BoolVarP(&o.Version, "version", "", false, "kube-state-metrics build version information") +} + +func (o *options) Parse() error { + err := o.flags.Parse(os.Args) + return err +} + +func (o *options) Usage() { + o.flags.Usage() +} diff --git a/pkg/options/types.go b/pkg/options/types.go new file mode 100644 index 0000000000..c52b1af0b6 --- /dev/null +++ b/pkg/options/types.go @@ -0,0 +1,92 @@ +/* +Copyright 2018 The Kubernetes Authors All rights reserved. + +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. +*/ + +package options + +import ( + "sort" + "strings" + + "github.com/golang/glog" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +type CollectorSet map[string]struct{} + +func (c *CollectorSet) String() string { + s := *c + ss := s.asSlice() + sort.Strings(ss) + return strings.Join(ss, ",") +} + +func (c *CollectorSet) Set(value string) error { + s := *c + cols := strings.Split(value, ",") + for _, col := range cols { + col = strings.TrimSpace(col) + if len(col) != 0 { + _, ok := AvailableCollectors[col] + if !ok { + glog.Fatalf("Collector \"%s\" does not exist", col) + } + s[col] = struct{}{} + } + } + return nil +} + +func (c CollectorSet) asSlice() []string { + cols := []string{} + for col := range c { + cols = append(cols, col) + } + return cols +} + +func (c CollectorSet) isEmpty() bool { + return len(c.asSlice()) == 0 +} + +func (c *CollectorSet) Type() string { + return "string" +} + +type NamespaceList []string + +func (n *NamespaceList) String() string { + return strings.Join(*n, ",") +} + +func (n *NamespaceList) IsAllNamespaces() bool { + return len(*n) == 1 && (*n)[0] == metav1.NamespaceAll +} + +func (n *NamespaceList) Set(value string) error { + splittedNamespaces := strings.Split(value, ",") + for _, ns := range splittedNamespaces { + ns = strings.TrimSpace(ns) + if len(ns) != 0 { + *n = append(*n, ns) + } + } + return nil +} + +func (n *NamespaceList) Type() string { + return "string" +} diff --git a/version/version.go b/pkg/version/version.go similarity index 100% rename from version/version.go rename to pkg/version/version.go diff --git a/tests/e2e.sh b/tests/e2e.sh index 586f0a054b..1d00402f83 100755 --- a/tests/e2e.sh +++ b/tests/e2e.sh @@ -168,7 +168,7 @@ echo "check metrics format with promtool" [ -n "$E2E_SETUP_PROMTOOL" ] && setup_promtool cat $KUBE_STATE_METRICS_LOG_DIR/metrics | promtool check metrics -collectors=$(find collectors/ -maxdepth 1 -name "*.go" -not -name "*_test.go" -not -name "collectors.go" | xargs -n1 basename | awk -F. '{print $1}') +collectors=$(find pkg/collectors/ -maxdepth 1 -name "*.go" -not -name "*_test.go" -not -name "collectors.go" | xargs -n1 basename | awk -F. '{print $1}') echo "available collectors: $collectors" for collector in $collectors; do echo "checking that kube_${collector}* metrics exists"