diff --git a/Makefile b/Makefile index 79ef0da940..4d8a8d523a 100644 --- a/Makefile +++ b/Makefile @@ -42,7 +42,7 @@ doccheck: generate @git diff --exit-code @echo "- Checking if the documentation is in sync with the code..." @grep -hoE '(kube_[^ |]+)' docs/* --exclude=README.md| sort -u > documented_metrics - @sed -n 's/.*# TYPE \(kube_[^ ]\+\).*/\1/p' internal/collector/*_test.go | sort -u > tested_metrics + @sed -n 's/.*# TYPE \(kube_[^ ]\+\).*/\1/p' internal/store/*_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/internal/collector/builder.go b/internal/collector/builder.go deleted file mode 100644 index e4b22f5153..0000000000 --- a/internal/collector/builder.go +++ /dev/null @@ -1,293 +0,0 @@ -/* -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 collector - -import ( - "sort" - "strings" - - "k8s.io/klog" - - "golang.org/x/net/context" - appsv1 "k8s.io/api/apps/v1" - autoscaling "k8s.io/api/autoscaling/v2beta1" - batchv1 "k8s.io/api/batch/v1" - batchv1beta1 "k8s.io/api/batch/v1beta1" - certv1beta1 "k8s.io/api/certificates/v1beta1" - v1 "k8s.io/api/core/v1" - extensions "k8s.io/api/extensions/v1beta1" - policy "k8s.io/api/policy/v1beta1" - storagev1 "k8s.io/api/storage/v1" - clientset "k8s.io/client-go/kubernetes" - "k8s.io/client-go/tools/cache" - "k8s.io/kube-state-metrics/pkg/metric" - metricsstore "k8s.io/kube-state-metrics/pkg/metrics_store" - "k8s.io/kube-state-metrics/pkg/options" -) - -type whiteBlackLister interface { - IsIncluded(string) bool - IsExcluded(string) bool -} - -// Builder helps to build collector. It follows the builder pattern -// (https://en.wikipedia.org/wiki/Builder_pattern). -type Builder struct { - kubeClient clientset.Interface - namespaces options.NamespaceList - ctx context.Context - enabledCollectors []string - whiteBlackList whiteBlackLister -} - -// NewBuilder returns a new builder. -func NewBuilder( - ctx context.Context, -) *Builder { - return &Builder{ - ctx: ctx, - } -} - -// WithEnabledCollectors sets the enabledCollectors property of a Builder. -func (b *Builder) WithEnabledCollectors(c []string) { - var copy []string - copy = append(copy, c...) - - sort.Strings(copy) - - b.enabledCollectors = copy -} - -// WithNamespaces sets the namespaces property of a Builder. -func (b *Builder) WithNamespaces(n options.NamespaceList) { - b.namespaces = n -} - -// WithKubeClient sets the kubeClient property of a Builder. -func (b *Builder) WithKubeClient(c clientset.Interface) { - b.kubeClient = c -} - -// WithWhiteBlackList configures the white or blacklisted metric to be exposed -// by the collector build by the Builder -func (b *Builder) WithWhiteBlackList(l whiteBlackLister) { - b.whiteBlackList = l -} - -// Build initializes and registers all enabled collectors. -func (b *Builder) Build() []*metricsstore.MetricsStore { - if b.whiteBlackList == nil { - panic("whiteBlackList should not be nil") - } - - collectors := []*metricsstore.MetricsStore{} - activeCollectorNames := []string{} - - for _, c := range b.enabledCollectors { - constructor, ok := availableCollectors[c] - if ok { - collector := constructor(b) - activeCollectorNames = append(activeCollectorNames, c) - collectors = append(collectors, collector) - } - } - - klog.Infof("Active collectors: %s", strings.Join(activeCollectorNames, ",")) - - return collectors -} - -<<<<<<< HEAD -var availableCollectors = map[string]func(f *Builder) *coll.Collector{ - "certificatesigningrequests": func(b *Builder) *coll.Collector { return b.buildCsrCollector() }, - "configmaps": func(b *Builder) *coll.Collector { return b.buildConfigMapCollector() }, - "cronjobs": func(b *Builder) *coll.Collector { return b.buildCronJobCollector() }, - "daemonsets": func(b *Builder) *coll.Collector { return b.buildDaemonSetCollector() }, - "deployments": func(b *Builder) *coll.Collector { return b.buildDeploymentCollector() }, - "endpoints": func(b *Builder) *coll.Collector { return b.buildEndpointsCollector() }, - "horizontalpodautoscalers": func(b *Builder) *coll.Collector { return b.buildHPACollector() }, - "ingresses": func(b *Builder) *coll.Collector { return b.buildIngressCollector() }, - "jobs": func(b *Builder) *coll.Collector { return b.buildJobCollector() }, - "limitranges": func(b *Builder) *coll.Collector { return b.buildLimitRangeCollector() }, - "namespaces": func(b *Builder) *coll.Collector { return b.buildNamespaceCollector() }, - "nodes": func(b *Builder) *coll.Collector { return b.buildNodeCollector() }, - "persistentvolumeclaims": func(b *Builder) *coll.Collector { return b.buildPersistentVolumeClaimCollector() }, - "persistentvolumes": func(b *Builder) *coll.Collector { return b.buildPersistentVolumeCollector() }, - "poddisruptionbudgets": func(b *Builder) *coll.Collector { return b.buildPodDisruptionBudgetCollector() }, - "pods": func(b *Builder) *coll.Collector { return b.buildPodCollector() }, - "replicasets": func(b *Builder) *coll.Collector { return b.buildReplicaSetCollector() }, - "replicationcontrollers": func(b *Builder) *coll.Collector { return b.buildReplicationControllerCollector() }, - "resourcequotas": func(b *Builder) *coll.Collector { return b.buildResourceQuotaCollector() }, - "secrets": func(b *Builder) *coll.Collector { return b.buildSecretCollector() }, - "services": func(b *Builder) *coll.Collector { return b.buildServiceCollector() }, - "statefulsets": func(b *Builder) *coll.Collector { return b.buildStatefulSetCollector() }, - "storageclasses": func(b *Builder) *coll.Collector { return b.buildStorageClassCollector() }, -} - -func (b *Builder) buildConfigMapCollector() *coll.Collector { -======= -var availableCollectors = map[string]func(f *Builder) *metricsstore.MetricsStore{ - "certificatesigningrequests": func(b *Builder) *metricsstore.MetricsStore { return b.buildCsrCollector() }, - "configmaps": func(b *Builder) *metricsstore.MetricsStore { return b.buildConfigMapCollector() }, - "cronjobs": func(b *Builder) *metricsstore.MetricsStore { return b.buildCronJobCollector() }, - "daemonsets": func(b *Builder) *metricsstore.MetricsStore { return b.buildDaemonSetCollector() }, - "deployments": func(b *Builder) *metricsstore.MetricsStore { return b.buildDeploymentCollector() }, - "endpoints": func(b *Builder) *metricsstore.MetricsStore { return b.buildEndpointsCollector() }, - "horizontalpodautoscalers": func(b *Builder) *metricsstore.MetricsStore { return b.buildHPACollector() }, - "ingresses": func(b *Builder) *metricsstore.MetricsStore { return b.buildIngressCollector() }, - "jobs": func(b *Builder) *metricsstore.MetricsStore { return b.buildJobCollector() }, - "limitranges": func(b *Builder) *metricsstore.MetricsStore { return b.buildLimitRangeCollector() }, - "namespaces": func(b *Builder) *metricsstore.MetricsStore { return b.buildNamespaceCollector() }, - "nodes": func(b *Builder) *metricsstore.MetricsStore { return b.buildNodeCollector() }, - "persistentvolumeclaims": func(b *Builder) *metricsstore.MetricsStore { return b.buildPersistentVolumeClaimCollector() }, - "persistentvolumes": func(b *Builder) *metricsstore.MetricsStore { return b.buildPersistentVolumeCollector() }, - "poddisruptionbudgets": func(b *Builder) *metricsstore.MetricsStore { return b.buildPodDisruptionBudgetCollector() }, - "pods": func(b *Builder) *metricsstore.MetricsStore { return b.buildPodCollector() }, - "replicasets": func(b *Builder) *metricsstore.MetricsStore { return b.buildReplicaSetCollector() }, - "replicationcontrollers": func(b *Builder) *metricsstore.MetricsStore { return b.buildReplicationControllerCollector() }, - "resourcequotas": func(b *Builder) *metricsstore.MetricsStore { return b.buildResourceQuotaCollector() }, - "secrets": func(b *Builder) *metricsstore.MetricsStore { return b.buildSecretCollector() }, - "services": func(b *Builder) *metricsstore.MetricsStore { return b.buildServiceCollector() }, - "statefulsets": func(b *Builder) *metricsstore.MetricsStore { return b.buildStatefulSetCollector() }, -} - -func (b *Builder) buildConfigMapCollector() *metricsstore.MetricsStore { - return b.buildCollector(configMapMetricFamilies, &v1.ConfigMap{}, createConfigMapListWatch) -} - -func (b *Builder) buildCronJobCollector() *metricsstore.MetricsStore { - return b.buildCollector(cronJobMetricFamilies, &batchv1beta1.CronJob{}, createCronJobListWatch) -} - -func (b *Builder) buildDaemonSetCollector() *metricsstore.MetricsStore { - return b.buildCollector(daemonSetMetricFamilies, &appsv1.DaemonSet{}, createDaemonSetListWatch) -} - -func (b *Builder) buildDeploymentCollector() *metricsstore.MetricsStore { - return b.buildCollector(deploymentMetricFamilies, &appsv1.Deployment{}, createDeploymentListWatch) -} - -func (b *Builder) buildEndpointsCollector() *metricsstore.MetricsStore { - return b.buildCollector(endpointMetricFamilies, &v1.Endpoints{}, createEndpointsListWatch) -} - -func (b *Builder) buildHPACollector() *metricsstore.MetricsStore { - return b.buildCollector(hpaMetricFamilies, &autoscaling.HorizontalPodAutoscaler{}, createHPAListWatch) -} - -func (b *Builder) buildIngressCollector() *metricsstore.MetricsStore { - return b.buildCollector(ingressMetricFamilies, &extensions.Ingress{}, createIngressListWatch) -} - -func (b *Builder) buildJobCollector() *metricsstore.MetricsStore { - return b.buildCollector(jobMetricFamilies, &batchv1.Job{}, createJobListWatch) -} - -func (b *Builder) buildLimitRangeCollector() *metricsstore.MetricsStore { - return b.buildCollector(limitRangeMetricFamilies, &v1.LimitRange{}, createLimitRangeListWatch) -} - -func (b *Builder) buildNamespaceCollector() *metricsstore.MetricsStore { - return b.buildCollector(namespaceMetricFamilies, &v1.Namespace{}, createNamespaceListWatch) -} - -func (b *Builder) buildNodeCollector() *metricsstore.MetricsStore { - return b.buildCollector(nodeMetricFamilies, &v1.Node{}, createNodeListWatch) -} - -func (b *Builder) buildPersistentVolumeClaimCollector() *metricsstore.MetricsStore { - return b.buildCollector(persistentVolumeClaimMetricFamilies, &v1.PersistentVolumeClaim{}, createPersistentVolumeClaimListWatch) -} - -func (b *Builder) buildPersistentVolumeCollector() *metricsstore.MetricsStore { - return b.buildCollector(persistentVolumeMetricFamilies, &v1.PersistentVolume{}, createPersistentVolumeListWatch) -} - -func (b *Builder) buildPodDisruptionBudgetCollector() *metricsstore.MetricsStore { - return b.buildCollector(podDisruptionBudgetMetricFamilies, &policy.PodDisruptionBudget{}, createPodDisruptionBudgetListWatch) -} - -func (b *Builder) buildReplicaSetCollector() *metricsstore.MetricsStore { - return b.buildCollector(replicaSetMetricFamilies, &extensions.ReplicaSet{}, createReplicaSetListWatch) -} - -func (b *Builder) buildReplicationControllerCollector() *metricsstore.MetricsStore { - return b.buildCollector(replicationControllerMetricFamilies, &v1.ReplicationController{}, createReplicationControllerListWatch) -} - -func (b *Builder) buildResourceQuotaCollector() *metricsstore.MetricsStore { - return b.buildCollector(resourceQuotaMetricFamilies, &v1.ResourceQuota{}, createResourceQuotaListWatch) -} - -func (b *Builder) buildSecretCollector() *metricsstore.MetricsStore { - return b.buildCollector(secretMetricFamilies, &v1.Secret{}, createSecretListWatch) -} - -func (b *Builder) buildServiceCollector() *metricsstore.MetricsStore { - return b.buildCollector(serviceMetricFamilies, &v1.Service{}, createServiceListWatch) -} - -func (b *Builder) buildStatefulSetCollector() *metricsstore.MetricsStore { - return b.buildCollector(statefulSetMetricFamilies, &appsv1.StatefulSet{}, createStatefulSetListWatch) -} - -<<<<<<< HEAD -func (b *Builder) buildStorageClassCollector() *coll.Collector { - return b.buildCollector(storageClassMetricFamilies, &storagev1.StorageClass{}, createStorageClassListWatch) -} - -func (b *Builder) buildPodCollector() *metricsstore.MetricsStore { - return b.buildCollector(podMetricFamilies, &v1.Pod{}, createPodListWatch) -} - -func (b *Builder) buildCsrCollector() *metricsstore.MetricsStore { - return b.buildCollector(csrMetricFamilies, &certv1beta1.CertificateSigningRequest{}, createCSRListWatch) -} - -func (b *Builder) buildCollector( - metricFamilies []metric.FamilyGenerator, - expectedType interface{}, - listWatchFunc func(kubeClient clientset.Interface, ns string) cache.ListerWatcher, -) *metricsstore.MetricsStore { - filteredMetricFamilies := metric.FilterMetricFamilies(b.whiteBlackList, metricFamilies) - composedMetricGenFuncs := metric.ComposeMetricGenFuncs(filteredMetricFamilies) - - familyHeaders := metric.ExtractMetricFamilyHeaders(filteredMetricFamilies) - - store := metricsstore.NewMetricsStore( - familyHeaders, - composedMetricGenFuncs, - ) - b.reflectorPerNamespace(expectedType, store, listWatchFunc) - - return store -} - -// reflectorPerNamespace creates a Kubernetes client-go reflector with the given -// listWatchFunc for each given namespace and registers it with the given store. -func (b *Builder) reflectorPerNamespace( - expectedType interface{}, - store cache.Store, - listWatchFunc func(kubeClient clientset.Interface, ns string) cache.ListerWatcher, -) { - for _, ns := range b.namespaces { - lw := listWatchFunc(b.kubeClient, ns) - reflector := cache.NewReflector(lw, expectedType, store, 0) - go reflector.Run(b.ctx.Done()) - } -} diff --git a/internal/store/builder.go b/internal/store/builder.go new file mode 100644 index 0000000000..f13102dd1b --- /dev/null +++ b/internal/store/builder.go @@ -0,0 +1,264 @@ +/* +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 store + +import ( + "sort" + "strings" + + "k8s.io/klog" + + "golang.org/x/net/context" + appsv1 "k8s.io/api/apps/v1" + autoscaling "k8s.io/api/autoscaling/v2beta1" + batchv1 "k8s.io/api/batch/v1" + batchv1beta1 "k8s.io/api/batch/v1beta1" + certv1beta1 "k8s.io/api/certificates/v1beta1" + v1 "k8s.io/api/core/v1" + extensions "k8s.io/api/extensions/v1beta1" + policy "k8s.io/api/policy/v1beta1" + storagev1 "k8s.io/api/storage/v1" + clientset "k8s.io/client-go/kubernetes" + "k8s.io/client-go/tools/cache" + "k8s.io/kube-state-metrics/pkg/metric" + metricsstore "k8s.io/kube-state-metrics/pkg/metrics_store" + "k8s.io/kube-state-metrics/pkg/options" +) + +type whiteBlackLister interface { + IsIncluded(string) bool + IsExcluded(string) bool +} + +// Builder helps to build store. It follows the builder pattern +// (https://en.wikipedia.org/wiki/Builder_pattern). +type Builder struct { + kubeClient clientset.Interface + namespaces options.NamespaceList + ctx context.Context + enabledResources []string + whiteBlackList whiteBlackLister +} + +// NewBuilder returns a new builder. +func NewBuilder( + ctx context.Context, +) *Builder { + return &Builder{ + ctx: ctx, + } +} + +// WithEnabledResources sets the enabledResources property of a Builder. +func (b *Builder) WithEnabledResources(c []string) { + var copy []string + copy = append(copy, c...) + + sort.Strings(copy) + + b.enabledResources = copy +} + +// WithNamespaces sets the namespaces property of a Builder. +func (b *Builder) WithNamespaces(n options.NamespaceList) { + b.namespaces = n +} + +// WithKubeClient sets the kubeClient property of a Builder. +func (b *Builder) WithKubeClient(c clientset.Interface) { + b.kubeClient = c +} + +// WithWhiteBlackList configures the white or blacklisted metric to be exposed +// by the store build by the Builder. +func (b *Builder) WithWhiteBlackList(l whiteBlackLister) { + b.whiteBlackList = l +} + +// Build initializes and registers all enabled stores. +func (b *Builder) Build() []*metricsstore.MetricsStore { + if b.whiteBlackList == nil { + panic("whiteBlackList should not be nil") + } + + stores := []*metricsstore.MetricsStore{} + activeStoreNames := []string{} + + for _, c := range b.enabledResources { + constructor, ok := availableStores[c] + if ok { + store := constructor(b) + activeStoreNames = append(activeStoreNames, c) + stores = append(stores, store) + } + } + + klog.Infof("Active collectors: %s", strings.Join(activeStoreNames, ",")) + + return stores +} + +var availableStores = map[string]func(f *Builder) *metricsstore.MetricsStore{ + "certificatesigningrequests": func(b *Builder) *metricsstore.MetricsStore { return b.buildCsrStore() }, + "configmaps": func(b *Builder) *metricsstore.MetricsStore { return b.buildConfigMapStore() }, + "cronjobs": func(b *Builder) *metricsstore.MetricsStore { return b.buildCronJobStore() }, + "daemonsets": func(b *Builder) *metricsstore.MetricsStore { return b.buildDaemonSetStore() }, + "deployments": func(b *Builder) *metricsstore.MetricsStore { return b.buildDeploymentStore() }, + "endpoints": func(b *Builder) *metricsstore.MetricsStore { return b.buildEndpointsStore() }, + "horizontalpodautoscalers": func(b *Builder) *metricsstore.MetricsStore { return b.buildHPAStore() }, + "ingresses": func(b *Builder) *metricsstore.MetricsStore { return b.buildIngressStore() }, + "jobs": func(b *Builder) *metricsstore.MetricsStore { return b.buildJobStore() }, + "limitranges": func(b *Builder) *metricsstore.MetricsStore { return b.buildLimitRangeStore() }, + "namespaces": func(b *Builder) *metricsstore.MetricsStore { return b.buildNamespaceStore() }, + "nodes": func(b *Builder) *metricsstore.MetricsStore { return b.buildNodeStore() }, + "persistentvolumeclaims": func(b *Builder) *metricsstore.MetricsStore { return b.buildPersistentVolumeClaimStore() }, + "persistentvolumes": func(b *Builder) *metricsstore.MetricsStore { return b.buildPersistentVolumeStore() }, + "poddisruptionbudgets": func(b *Builder) *metricsstore.MetricsStore { return b.buildPodDisruptionBudgetStore() }, + "pods": func(b *Builder) *metricsstore.MetricsStore { return b.buildPodStore() }, + "replicasets": func(b *Builder) *metricsstore.MetricsStore { return b.buildReplicaSetStore() }, + "replicationcontrollers": func(b *Builder) *metricsstore.MetricsStore { return b.buildReplicationControllerStore() }, + "resourcequotas": func(b *Builder) *metricsstore.MetricsStore { return b.buildResourceQuotaStore() }, + "secrets": func(b *Builder) *metricsstore.MetricsStore { return b.buildSecretStore() }, + "services": func(b *Builder) *metricsstore.MetricsStore { return b.buildServiceStore() }, + "statefulsets": func(b *Builder) *metricsstore.MetricsStore { return b.buildStatefulSetStore() }, + "storageclasses": func(b *Builder) *metricsstore.MetricsStore { return b.buildStorageClassStore() }, +} + +func (b *Builder) buildConfigMapStore() *metricsstore.MetricsStore { + return b.buildStore(configMapMetricFamilies, &v1.ConfigMap{}, createConfigMapListWatch) +} + +func (b *Builder) buildCronJobStore() *metricsstore.MetricsStore { + return b.buildStore(cronJobMetricFamilies, &batchv1beta1.CronJob{}, createCronJobListWatch) +} + +func (b *Builder) buildDaemonSetStore() *metricsstore.MetricsStore { + return b.buildStore(daemonSetMetricFamilies, &appsv1.DaemonSet{}, createDaemonSetListWatch) +} + +func (b *Builder) buildDeploymentStore() *metricsstore.MetricsStore { + return b.buildStore(deploymentMetricFamilies, &appsv1.Deployment{}, createDeploymentListWatch) +} + +func (b *Builder) buildEndpointsStore() *metricsstore.MetricsStore { + return b.buildStore(endpointMetricFamilies, &v1.Endpoints{}, createEndpointsListWatch) +} + +func (b *Builder) buildHPAStore() *metricsstore.MetricsStore { + return b.buildStore(hpaMetricFamilies, &autoscaling.HorizontalPodAutoscaler{}, createHPAListWatch) +} + +func (b *Builder) buildIngressStore() *metricsstore.MetricsStore { + return b.buildStore(ingressMetricFamilies, &extensions.Ingress{}, createIngressListWatch) +} + +func (b *Builder) buildJobStore() *metricsstore.MetricsStore { + return b.buildStore(jobMetricFamilies, &batchv1.Job{}, createJobListWatch) +} + +func (b *Builder) buildLimitRangeStore() *metricsstore.MetricsStore { + return b.buildStore(limitRangeMetricFamilies, &v1.LimitRange{}, createLimitRangeListWatch) +} + +func (b *Builder) buildNamespaceStore() *metricsstore.MetricsStore { + return b.buildStore(namespaceMetricFamilies, &v1.Namespace{}, createNamespaceListWatch) +} + +func (b *Builder) buildNodeStore() *metricsstore.MetricsStore { + return b.buildStore(nodeMetricFamilies, &v1.Node{}, createNodeListWatch) +} + +func (b *Builder) buildPersistentVolumeClaimStore() *metricsstore.MetricsStore { + return b.buildStore(persistentVolumeClaimMetricFamilies, &v1.PersistentVolumeClaim{}, createPersistentVolumeClaimListWatch) +} + +func (b *Builder) buildPersistentVolumeStore() *metricsstore.MetricsStore { + return b.buildStore(persistentVolumeMetricFamilies, &v1.PersistentVolume{}, createPersistentVolumeListWatch) +} + +func (b *Builder) buildPodDisruptionBudgetStore() *metricsstore.MetricsStore { + return b.buildStore(podDisruptionBudgetMetricFamilies, &policy.PodDisruptionBudget{}, createPodDisruptionBudgetListWatch) +} + +func (b *Builder) buildReplicaSetStore() *metricsstore.MetricsStore { + return b.buildStore(replicaSetMetricFamilies, &extensions.ReplicaSet{}, createReplicaSetListWatch) +} + +func (b *Builder) buildReplicationControllerStore() *metricsstore.MetricsStore { + return b.buildStore(replicationControllerMetricFamilies, &v1.ReplicationController{}, createReplicationControllerListWatch) +} + +func (b *Builder) buildResourceQuotaStore() *metricsstore.MetricsStore { + return b.buildStore(resourceQuotaMetricFamilies, &v1.ResourceQuota{}, createResourceQuotaListWatch) +} + +func (b *Builder) buildSecretStore() *metricsstore.MetricsStore { + return b.buildStore(secretMetricFamilies, &v1.Secret{}, createSecretListWatch) +} + +func (b *Builder) buildServiceStore() *metricsstore.MetricsStore { + return b.buildStore(serviceMetricFamilies, &v1.Service{}, createServiceListWatch) +} + +func (b *Builder) buildStatefulSetStore() *metricsstore.MetricsStore { + return b.buildStore(statefulSetMetricFamilies, &appsv1.StatefulSet{}, createStatefulSetListWatch) +} + +func (b *Builder) buildStorageClassStore() *metricsstore.MetricsStore { + return b.buildStore(storageClassMetricFamilies, &storagev1.StorageClass{}, createStorageClassListWatch) +} + +func (b *Builder) buildPodStore() *metricsstore.MetricsStore { + return b.buildStore(podMetricFamilies, &v1.Pod{}, createPodListWatch) +} + +func (b *Builder) buildCsrStore() *metricsstore.MetricsStore { + return b.buildStore(csrMetricFamilies, &certv1beta1.CertificateSigningRequest{}, createCSRListWatch) +} + +func (b *Builder) buildStore( + metricFamilies []metric.FamilyGenerator, + expectedType interface{}, + listWatchFunc func(kubeClient clientset.Interface, ns string) cache.ListerWatcher, +) *metricsstore.MetricsStore { + filteredMetricFamilies := metric.FilterMetricFamilies(b.whiteBlackList, metricFamilies) + composedMetricGenFuncs := metric.ComposeMetricGenFuncs(filteredMetricFamilies) + + familyHeaders := metric.ExtractMetricFamilyHeaders(filteredMetricFamilies) + + store := metricsstore.NewMetricsStore( + familyHeaders, + composedMetricGenFuncs, + ) + b.reflectorPerNamespace(expectedType, store, listWatchFunc) + + return store +} + +// reflectorPerNamespace creates a Kubernetes client-go reflector with the given +// listWatchFunc for each given namespace and registers it with the given store. +func (b *Builder) reflectorPerNamespace( + expectedType interface{}, + store cache.Store, + listWatchFunc func(kubeClient clientset.Interface, ns string) cache.ListerWatcher, +) { + for _, ns := range b.namespaces { + lw := listWatchFunc(b.kubeClient, ns) + reflector := cache.NewReflector(lw, expectedType, store, 0) + go reflector.Run(b.ctx.Done()) + } +} diff --git a/internal/collector/certificatesigningrequest.go b/internal/store/certificatesigningrequest.go similarity index 99% rename from internal/collector/certificatesigningrequest.go rename to internal/store/certificatesigningrequest.go index c068d5af08..7c5ab5ee61 100644 --- a/internal/collector/certificatesigningrequest.go +++ b/internal/store/certificatesigningrequest.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package collector +package store import ( "k8s.io/kube-state-metrics/pkg/metric" diff --git a/internal/collector/certificatesigningrequest_test.go b/internal/store/certificatesigningrequest_test.go similarity index 99% rename from internal/collector/certificatesigningrequest_test.go rename to internal/store/certificatesigningrequest_test.go index 007d3ba6ce..88ac5e5c1b 100644 --- a/internal/collector/certificatesigningrequest_test.go +++ b/internal/store/certificatesigningrequest_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package collector +package store import ( "testing" @@ -26,7 +26,7 @@ import ( "k8s.io/kube-state-metrics/pkg/metric" ) -func TestCsrCollector(t *testing.T) { +func TestCsrStore(t *testing.T) { const metadata = ` # HELP kube_certificatesigningrequest_labels Kubernetes labels converted to Prometheus labels. # TYPE kube_certificatesigningrequest_labels gauge diff --git a/internal/collector/configmap.go b/internal/store/configmap.go similarity index 99% rename from internal/collector/configmap.go rename to internal/store/configmap.go index f4f10ecaa7..164d786be6 100644 --- a/internal/collector/configmap.go +++ b/internal/store/configmap.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package collector +package store import ( v1 "k8s.io/api/core/v1" diff --git a/internal/collector/configmap_test.go b/internal/store/configmap_test.go similarity index 97% rename from internal/collector/configmap_test.go rename to internal/store/configmap_test.go index 09e277bbd4..33be480c8b 100644 --- a/internal/collector/configmap_test.go +++ b/internal/store/configmap_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package collector +package store import ( "testing" @@ -24,7 +24,7 @@ import ( "k8s.io/kube-state-metrics/pkg/metric" ) -func TestConfigMapCollector(t *testing.T) { +func TestConfigMapStore(t *testing.T) { // Fixed metadata on type and help text. We prepend this to every expected // output so we only have to modify a single place when doing adjustments. diff --git a/internal/collector/cronjob.go b/internal/store/cronjob.go similarity index 99% rename from internal/collector/cronjob.go rename to internal/store/cronjob.go index 81bc9fc8c9..8be2dd250b 100644 --- a/internal/collector/cronjob.go +++ b/internal/store/cronjob.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package collector +package store import ( "time" diff --git a/internal/collector/cronjob_test.go b/internal/store/cronjob_test.go similarity index 99% rename from internal/collector/cronjob_test.go rename to internal/store/cronjob_test.go index 307a28e210..7e7de08b00 100644 --- a/internal/collector/cronjob_test.go +++ b/internal/store/cronjob_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package collector +package store import ( "fmt" @@ -39,7 +39,7 @@ var ( ActiveCronJob1NoLastScheduledCreationTimestamp = time.Unix(1520742896+6.5*3600, 0) ) -func TestCronJobCollector(t *testing.T) { +func TestCronJobStore(t *testing.T) { // Fixed metadata on type and help text. We prepend this to every expected // output so we only have to modify a single place when doing adjustments. diff --git a/internal/collector/daemonset.go b/internal/store/daemonset.go similarity index 99% rename from internal/collector/daemonset.go rename to internal/store/daemonset.go index d17dde1502..f5315b4da8 100644 --- a/internal/collector/daemonset.go +++ b/internal/store/daemonset.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package collector +package store import ( v1 "k8s.io/api/apps/v1" diff --git a/internal/collector/daemonset_test.go b/internal/store/daemonset_test.go similarity index 99% rename from internal/collector/daemonset_test.go rename to internal/store/daemonset_test.go index 77aee8a69e..6bc9e3c6b2 100644 --- a/internal/collector/daemonset_test.go +++ b/internal/store/daemonset_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package collector +package store import ( "testing" @@ -25,7 +25,7 @@ import ( "k8s.io/kube-state-metrics/pkg/metric" ) -func TestDaemonSetCollector(t *testing.T) { +func TestDaemonSetStore(t *testing.T) { // Fixed metadata on type and help text. We prepend this to every expected // output so we only have to modify a single place when doing adjustments. const metadata = ` diff --git a/internal/collector/deployment.go b/internal/store/deployment.go similarity index 99% rename from internal/collector/deployment.go rename to internal/store/deployment.go index 2a910900e4..5f04eae368 100644 --- a/internal/collector/deployment.go +++ b/internal/store/deployment.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package collector +package store import ( "k8s.io/kube-state-metrics/pkg/metric" diff --git a/internal/collector/deployment_test.go b/internal/store/deployment_test.go similarity index 99% rename from internal/collector/deployment_test.go rename to internal/store/deployment_test.go index 3a5e1ea7a8..28e6c24ad5 100644 --- a/internal/collector/deployment_test.go +++ b/internal/store/deployment_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package collector +package store import ( "testing" @@ -37,7 +37,7 @@ var ( depl2MaxSurge = intstr.FromString("20%") ) -func TestDeploymentCollector(t *testing.T) { +func TestDeploymentStore(t *testing.T) { // Fixed metadata on type and help text. We prepend this to every expected // output so we only have to modify a single place when doing adjustments. const metadata = ` diff --git a/internal/collector/endpoint.go b/internal/store/endpoint.go similarity index 99% rename from internal/collector/endpoint.go rename to internal/store/endpoint.go index 6d6faa953e..ae823ac9c1 100644 --- a/internal/collector/endpoint.go +++ b/internal/store/endpoint.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package collector +package store import ( v1 "k8s.io/api/core/v1" diff --git a/internal/collector/endpoint_test.go b/internal/store/endpoint_test.go similarity index 98% rename from internal/collector/endpoint_test.go rename to internal/store/endpoint_test.go index b3fa59a5f2..f45761b790 100644 --- a/internal/collector/endpoint_test.go +++ b/internal/store/endpoint_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package collector +package store // TODO: Shouldn't this file be called endpoints? @@ -27,7 +27,7 @@ import ( "k8s.io/kube-state-metrics/pkg/metric" ) -func TestEndpointCollector(t *testing.T) { +func TestEndpointStore(t *testing.T) { // Fixed metadata on type and help text. We prepend this to every expected // output so we only have to modify a single place when doing adjustments. const metadata = ` diff --git a/internal/collector/hpa.go b/internal/store/hpa.go similarity index 99% rename from internal/collector/hpa.go rename to internal/store/hpa.go index 35347c427c..1a59d822b4 100644 --- a/internal/collector/hpa.go +++ b/internal/store/hpa.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package collector +package store import ( "k8s.io/kube-state-metrics/pkg/metric" diff --git a/internal/collector/hpa_test.go b/internal/store/hpa_test.go similarity index 98% rename from internal/collector/hpa_test.go rename to internal/store/hpa_test.go index eb3afd4118..3433ad4c3f 100644 --- a/internal/collector/hpa_test.go +++ b/internal/store/hpa_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package collector +package store import ( "testing" @@ -30,7 +30,7 @@ var ( hpa1MinReplicas int32 = 2 ) -func TestHPACollector(t *testing.T) { +func TestHPAStore(t *testing.T) { // Fixed metadata on type and help text. We prepend this to every expected // output so we only have to modify a single place when doing adjustments. const metadata = ` diff --git a/internal/collector/ingress.go b/internal/store/ingress.go similarity index 99% rename from internal/collector/ingress.go rename to internal/store/ingress.go index 6e11c5be43..0ec76fb8e9 100644 --- a/internal/collector/ingress.go +++ b/internal/store/ingress.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package collector +package store import ( "k8s.io/kube-state-metrics/pkg/metric" diff --git a/internal/collector/ingress_test.go b/internal/store/ingress_test.go similarity index 98% rename from internal/collector/ingress_test.go rename to internal/store/ingress_test.go index 1d4319fd39..09fefaa69a 100644 --- a/internal/collector/ingress_test.go +++ b/internal/store/ingress_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package collector +package store import ( "testing" @@ -25,7 +25,7 @@ import ( "k8s.io/kube-state-metrics/pkg/metric" ) -func TestIngressCollector(t *testing.T) { +func TestIngressStore(t *testing.T) { // Fixed metadata on type and help text. We prepend this to every expected // output so we only have to modify a single place when doing adjustments. diff --git a/internal/collector/job.go b/internal/store/job.go similarity index 99% rename from internal/collector/job.go rename to internal/store/job.go index 56f0480cf5..57c79113a6 100644 --- a/internal/collector/job.go +++ b/internal/store/job.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package collector +package store import ( "strconv" diff --git a/internal/collector/job_test.go b/internal/store/job_test.go similarity index 99% rename from internal/collector/job_test.go rename to internal/store/job_test.go index 47e585107c..3144d952af 100644 --- a/internal/collector/job_test.go +++ b/internal/store/job_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package collector +package store import ( "testing" @@ -41,7 +41,7 @@ var ( SuccessfulJob2CompletionTime, _ = time.Parse(time.RFC3339, "2017-05-26T13:10:07Z") ) -func TestJobCollector(t *testing.T) { +func TestJobStore(t *testing.T) { var trueValue = true // Fixed metadata on type and help text. We prepend this to every expected diff --git a/internal/collector/limitrange.go b/internal/store/limitrange.go similarity index 99% rename from internal/collector/limitrange.go rename to internal/store/limitrange.go index 134c0aa4aa..660f217284 100644 --- a/internal/collector/limitrange.go +++ b/internal/store/limitrange.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package collector +package store import ( v1 "k8s.io/api/core/v1" diff --git a/internal/collector/limitrange_test.go b/internal/store/limitrange_test.go similarity index 99% rename from internal/collector/limitrange_test.go rename to internal/store/limitrange_test.go index 79ea0bda07..d9e2ca4c5d 100644 --- a/internal/collector/limitrange_test.go +++ b/internal/store/limitrange_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package collector +package store import ( "testing" diff --git a/internal/collector/namespace.go b/internal/store/namespace.go similarity index 99% rename from internal/collector/namespace.go rename to internal/store/namespace.go index be08396ffc..1c68e1ef30 100644 --- a/internal/collector/namespace.go +++ b/internal/store/namespace.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package collector +package store import ( "k8s.io/kube-state-metrics/pkg/metric" diff --git a/internal/collector/namespace_test.go b/internal/store/namespace_test.go similarity index 98% rename from internal/collector/namespace_test.go rename to internal/store/namespace_test.go index c61656635a..7c189b5b09 100644 --- a/internal/collector/namespace_test.go +++ b/internal/store/namespace_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package collector +package store import ( "testing" @@ -25,7 +25,7 @@ import ( "k8s.io/kube-state-metrics/pkg/metric" ) -func TestNamespaceCollector(t *testing.T) { +func TestNamespaceStore(t *testing.T) { // Fixed metadata on type and help text. We prepend this to every expected // output so we only have to modify a single place when doing adjustments. const metadata = ` diff --git a/internal/collector/node.go b/internal/store/node.go similarity index 99% rename from internal/collector/node.go rename to internal/store/node.go index 141cc67ea0..cdcfaccc9f 100644 --- a/internal/collector/node.go +++ b/internal/store/node.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package collector +package store import ( "k8s.io/kube-state-metrics/pkg/constant" diff --git a/internal/collector/node_test.go b/internal/store/node_test.go similarity index 99% rename from internal/collector/node_test.go rename to internal/store/node_test.go index 8b56841603..c7a222c805 100644 --- a/internal/collector/node_test.go +++ b/internal/store/node_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package collector +package store import ( "testing" @@ -26,7 +26,7 @@ import ( "k8s.io/kube-state-metrics/pkg/metric" ) -func TestNodeCollector(t *testing.T) { +func TestNodeStore(t *testing.T) { // Fixed metadata on type and help text. We prepend this to every expected // output so we only have to modify a single place when doing adjustments. const metadata = ` diff --git a/internal/collector/persistentvolume.go b/internal/store/persistentvolume.go similarity index 99% rename from internal/collector/persistentvolume.go rename to internal/store/persistentvolume.go index 1ce7e20651..9737df0925 100644 --- a/internal/collector/persistentvolume.go +++ b/internal/store/persistentvolume.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package collector +package store import ( "k8s.io/kube-state-metrics/pkg/metric" diff --git a/internal/collector/persistentvolume_test.go b/internal/store/persistentvolume_test.go similarity index 99% rename from internal/collector/persistentvolume_test.go rename to internal/store/persistentvolume_test.go index 9e0be3ac0f..61a4fb424e 100644 --- a/internal/collector/persistentvolume_test.go +++ b/internal/store/persistentvolume_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package collector +package store import ( "testing" @@ -25,7 +25,7 @@ import ( "k8s.io/kube-state-metrics/pkg/metric" ) -func TestPersistentVolumeCollector(t *testing.T) { +func TestPersistentVolumeStore(t *testing.T) { // Fixed metadata on type and help text. We prepend this to every expected // output so we only have to modify a single place when doing adjustments. const metadata = ` diff --git a/internal/collector/persistentvolumeclaim.go b/internal/store/persistentvolumeclaim.go similarity index 99% rename from internal/collector/persistentvolumeclaim.go rename to internal/store/persistentvolumeclaim.go index 10d57234b4..a236700887 100644 --- a/internal/collector/persistentvolumeclaim.go +++ b/internal/store/persistentvolumeclaim.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package collector +package store import ( "k8s.io/kube-state-metrics/pkg/metric" diff --git a/internal/collector/persistentvolumeclaim_test.go b/internal/store/persistentvolumeclaim_test.go similarity index 98% rename from internal/collector/persistentvolumeclaim_test.go rename to internal/store/persistentvolumeclaim_test.go index 1b2207ed85..97219240e9 100644 --- a/internal/collector/persistentvolumeclaim_test.go +++ b/internal/store/persistentvolumeclaim_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package collector +package store import ( "testing" @@ -25,7 +25,7 @@ import ( "k8s.io/kube-state-metrics/pkg/metric" ) -func TestPersistentVolumeClaimCollector(t *testing.T) { +func TestPersistentVolumeClaimStore(t *testing.T) { // Fixed metadata on type and help text. We prepend this to every expected // output so we only have to modify a single place when doing adjustments. const metadata = ` diff --git a/internal/collector/pod.go b/internal/store/pod.go similarity index 99% rename from internal/collector/pod.go rename to internal/store/pod.go index 56021605e7..bc3cddaacf 100644 --- a/internal/collector/pod.go +++ b/internal/store/pod.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package collector +package store import ( "strconv" diff --git a/internal/collector/pod_test.go b/internal/store/pod_test.go similarity index 99% rename from internal/collector/pod_test.go rename to internal/store/pod_test.go index 0759fe9ea7..cf3e6eba70 100644 --- a/internal/collector/pod_test.go +++ b/internal/store/pod_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package collector +package store import ( "testing" @@ -26,7 +26,7 @@ import ( "k8s.io/kube-state-metrics/pkg/metric" ) -func TestPodCollector(t *testing.T) { +func TestPodStore(t *testing.T) { // Fixed metadata on type and help text. We prepend this to every expected // output so we only have to modify a single place when doing adjustments. var test = true @@ -1330,7 +1330,7 @@ kube_pod_container_status_last_terminated_reason{container="container7",namespac } } -func BenchmarkPodCollector(b *testing.B) { +func BenchmarkPodStore(b *testing.B) { b.ReportAllocs() f := metric.ComposeMetricGenFuncs(podMetricFamilies) diff --git a/internal/collector/poddisruptionbudget.go b/internal/store/poddisruptionbudget.go similarity index 99% rename from internal/collector/poddisruptionbudget.go rename to internal/store/poddisruptionbudget.go index da8ae9c73a..8bbb0a4fdb 100644 --- a/internal/collector/poddisruptionbudget.go +++ b/internal/store/poddisruptionbudget.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package collector +package store import ( "k8s.io/api/policy/v1beta1" diff --git a/internal/collector/poddisruptionbudget_test.go b/internal/store/poddisruptionbudget_test.go similarity index 98% rename from internal/collector/poddisruptionbudget_test.go rename to internal/store/poddisruptionbudget_test.go index b1178282da..e9bafc7af7 100644 --- a/internal/collector/poddisruptionbudget_test.go +++ b/internal/store/poddisruptionbudget_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package collector +package store import ( "testing" @@ -25,7 +25,7 @@ import ( "k8s.io/kube-state-metrics/pkg/metric" ) -func TestPodDisruptionBudgetCollector(t *testing.T) { +func TestPodDisruptionBudgetStore(t *testing.T) { // Fixed metadata on type and help text. We prepend this to every expected // output so we only have to modify a single place when doing adjustments. const metadata = ` diff --git a/internal/collector/replicaset.go b/internal/store/replicaset.go similarity index 99% rename from internal/collector/replicaset.go rename to internal/store/replicaset.go index 2bcd683a68..df5abf7a9c 100644 --- a/internal/collector/replicaset.go +++ b/internal/store/replicaset.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package collector +package store import ( "strconv" diff --git a/internal/collector/replicaset_test.go b/internal/store/replicaset_test.go similarity index 98% rename from internal/collector/replicaset_test.go rename to internal/store/replicaset_test.go index 73d5442228..f2e04fe5e4 100644 --- a/internal/collector/replicaset_test.go +++ b/internal/store/replicaset_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package collector +package store import ( "testing" @@ -30,7 +30,7 @@ var ( rs2Replicas int32 ) -func TestReplicaSetCollector(t *testing.T) { +func TestReplicaSetStore(t *testing.T) { // Fixed metadata on type and help text. We prepend this to every expected // output so we only have to modify a single place when doing adjustments. var test = true diff --git a/internal/collector/replicationcontroller.go b/internal/store/replicationcontroller.go similarity index 99% rename from internal/collector/replicationcontroller.go rename to internal/store/replicationcontroller.go index ab8463df1b..2a1a708275 100644 --- a/internal/collector/replicationcontroller.go +++ b/internal/store/replicationcontroller.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package collector +package store import ( v1 "k8s.io/api/core/v1" diff --git a/internal/collector/replicationcontroller_test.go b/internal/store/replicationcontroller_test.go similarity index 98% rename from internal/collector/replicationcontroller_test.go rename to internal/store/replicationcontroller_test.go index dd5e46bbbe..c65a6dd377 100644 --- a/internal/collector/replicationcontroller_test.go +++ b/internal/store/replicationcontroller_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package collector +package store import ( "testing" @@ -30,7 +30,7 @@ var ( rc2Replicas int32 ) -func TestReplicationControllerCollector(t *testing.T) { +func TestReplicationControllerStore(t *testing.T) { // Fixed metadata on type and help text. We prepend this to every expected // output so we only have to modify a single place when doing adjustments. const metadata = ` diff --git a/internal/collector/resourcequota.go b/internal/store/resourcequota.go similarity index 99% rename from internal/collector/resourcequota.go rename to internal/store/resourcequota.go index 8178641e9d..791ad8606b 100644 --- a/internal/collector/resourcequota.go +++ b/internal/store/resourcequota.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package collector +package store import ( v1 "k8s.io/api/core/v1" diff --git a/internal/collector/resourcequota_test.go b/internal/store/resourcequota_test.go similarity index 99% rename from internal/collector/resourcequota_test.go rename to internal/store/resourcequota_test.go index 474b198fbf..a4e49ebb84 100644 --- a/internal/collector/resourcequota_test.go +++ b/internal/store/resourcequota_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package collector +package store import ( "testing" @@ -26,7 +26,7 @@ import ( "k8s.io/kube-state-metrics/pkg/metric" ) -func TestResourceQuotaCollector(t *testing.T) { +func TestResourceQuotaStore(t *testing.T) { // Fixed metadata on type and help text. We prepend this to every expected // output so we only have to modify a single place when doing adjustments. const metadata = ` diff --git a/internal/collector/secret.go b/internal/store/secret.go similarity index 99% rename from internal/collector/secret.go rename to internal/store/secret.go index 2914fd4ec2..8e4c0ee46c 100644 --- a/internal/collector/secret.go +++ b/internal/store/secret.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package collector +package store import ( v1 "k8s.io/api/core/v1" diff --git a/internal/collector/secret_test.go b/internal/store/secret_test.go similarity index 98% rename from internal/collector/secret_test.go rename to internal/store/secret_test.go index d6c2f76531..9d48dce78c 100644 --- a/internal/collector/secret_test.go +++ b/internal/store/secret_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package collector +package store import ( "testing" @@ -24,7 +24,7 @@ import ( "k8s.io/kube-state-metrics/pkg/metric" ) -func TestSecretCollector(t *testing.T) { +func TestSecretStore(t *testing.T) { // Fixed metadata on type and help text. We prepend this to every expected // output so we only have to modify a single place when doing adjustments. diff --git a/internal/collector/service.go b/internal/store/service.go similarity index 99% rename from internal/collector/service.go rename to internal/store/service.go index 26d32bd6f5..a2ecb8d78d 100644 --- a/internal/collector/service.go +++ b/internal/store/service.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package collector +package store import ( v1 "k8s.io/api/core/v1" diff --git a/internal/collector/service_test.go b/internal/store/service_test.go similarity index 99% rename from internal/collector/service_test.go rename to internal/store/service_test.go index 30b06017ff..6c65cc2a34 100644 --- a/internal/collector/service_test.go +++ b/internal/store/service_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package collector +package store import ( "testing" @@ -25,7 +25,7 @@ import ( "k8s.io/kube-state-metrics/pkg/metric" ) -func TestServiceCollector(t *testing.T) { +func TestServiceStore(t *testing.T) { // Fixed metadata on type and help text. We prepend this to every expected // output so we only have to modify a single place when doing adjustments. const metadata = ` diff --git a/internal/collector/statefulset.go b/internal/store/statefulset.go similarity index 99% rename from internal/collector/statefulset.go rename to internal/store/statefulset.go index e345b8aa5d..e7f6b0cbf8 100644 --- a/internal/collector/statefulset.go +++ b/internal/store/statefulset.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package collector +package store import ( "k8s.io/kube-state-metrics/pkg/metric" diff --git a/internal/collector/statefulset_test.go b/internal/store/statefulset_test.go similarity index 99% rename from internal/collector/statefulset_test.go rename to internal/store/statefulset_test.go index 5b86ade900..b12690358b 100644 --- a/internal/collector/statefulset_test.go +++ b/internal/store/statefulset_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package collector +package store import ( "testing" @@ -34,7 +34,7 @@ var ( statefulSet2ObservedGeneration int64 = 2 ) -func TestStatefuleSetCollector(t *testing.T) { +func TestStatefuleSetStore(t *testing.T) { // Fixed metadata on type and help text. We prepend this to every expected // output so we only have to modify a single place when doing adjustments. const metadata = ` diff --git a/internal/collector/storageclass.go b/internal/store/storageclass.go similarity index 99% rename from internal/collector/storageclass.go rename to internal/store/storageclass.go index c9124876bc..6bf91a29d5 100644 --- a/internal/collector/storageclass.go +++ b/internal/store/storageclass.go @@ -11,7 +11,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package collector +package store import ( "k8s.io/kube-state-metrics/pkg/metric" diff --git a/internal/collector/storageclass_test.go b/internal/store/storageclass_test.go similarity index 97% rename from internal/collector/storageclass_test.go rename to internal/store/storageclass_test.go index ad228e9a5b..87ee23613d 100644 --- a/internal/collector/storageclass_test.go +++ b/internal/store/storageclass_test.go @@ -11,7 +11,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package collector +package store import ( "testing" @@ -22,7 +22,7 @@ import ( "k8s.io/kube-state-metrics/pkg/metric" ) -func TestStorageClassCollector(t *testing.T) { +func TestStorageClassStore(t *testing.T) { // Fixed metadata on type and help text. We prepend this to every expected // output so we only have to modify a single place when doing adjustments. diff --git a/internal/collector/testutils.go b/internal/store/testutils.go similarity index 99% rename from internal/collector/testutils.go rename to internal/store/testutils.go index c031a0a08b..952a2283fb 100644 --- a/internal/collector/testutils.go +++ b/internal/store/testutils.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package collector +package store // TODO: Does this file need to be renamed to not be compiled in production? diff --git a/internal/collector/testutils_test.go b/internal/store/testutils_test.go similarity index 99% rename from internal/collector/testutils_test.go rename to internal/store/testutils_test.go index 7d8e636d76..b413b7c92f 100644 --- a/internal/collector/testutils_test.go +++ b/internal/store/testutils_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package collector +package store import ( "testing" diff --git a/internal/collector/utils.go b/internal/store/utils.go similarity index 99% rename from internal/collector/utils.go rename to internal/store/utils.go index aaa9b98f24..fd4658f9d8 100644 --- a/internal/collector/utils.go +++ b/internal/store/utils.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package collector +package store import ( "fmt" diff --git a/internal/collector/utils_test.go b/internal/store/utils_test.go similarity index 99% rename from internal/collector/utils_test.go rename to internal/store/utils_test.go index 5f9b62d114..e4300c7f83 100644 --- a/internal/collector/utils_test.go +++ b/internal/store/utils_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package collector +package store import ( "fmt" diff --git a/main.go b/main.go index 933f8828f3..d6b1128564 100644 --- a/main.go +++ b/main.go @@ -38,7 +38,7 @@ import ( _ "k8s.io/client-go/plugin/pkg/client/auth" "k8s.io/client-go/tools/clientcmd" "k8s.io/klog" - kcoll "k8s.io/kube-state-metrics/internal/collector" + "k8s.io/kube-state-metrics/internal/store" metricsstore "k8s.io/kube-state-metrics/pkg/metrics_store" "k8s.io/kube-state-metrics/pkg/options" "k8s.io/kube-state-metrics/pkg/version" @@ -79,26 +79,26 @@ func main() { os.Exit(0) } - collectorBuilder := kcoll.NewBuilder(ctx) + storeBuilder := store.NewBuilder(ctx) if len(opts.Collectors) == 0 { klog.Info("Using default collectors") - collectorBuilder.WithEnabledCollectors(options.DefaultCollectors.AsSlice()) + storeBuilder.WithEnabledResources(options.DefaultCollectors.AsSlice()) } else { klog.Infof("Using collectors %s", opts.Collectors.String()) - collectorBuilder.WithEnabledCollectors(opts.Collectors.AsSlice()) + storeBuilder.WithEnabledResources(opts.Collectors.AsSlice()) } if len(opts.Namespaces) == 0 { klog.Info("Using all namespace") - collectorBuilder.WithNamespaces(options.DefaultNamespaces) + storeBuilder.WithNamespaces(options.DefaultNamespaces) } else { if opts.Namespaces.IsAllNamespaces() { klog.Info("Using all namespace") } else { klog.Infof("Using %s namespaces", opts.Namespaces) } - collectorBuilder.WithNamespaces(opts.Namespaces) + storeBuilder.WithNamespaces(opts.Namespaces) } whiteBlackList, err := whiteblacklist.New(opts.MetricWhitelist, opts.MetricBlacklist) @@ -128,7 +128,7 @@ func main() { klog.Infof("metric white-blacklisting: %v", whiteBlackList.Status()) - collectorBuilder.WithWhiteBlackList(whiteBlackList) + storeBuilder.WithWhiteBlackList(whiteBlackList) proc.StartReaper() @@ -136,16 +136,16 @@ func main() { if err != nil { klog.Fatalf("Failed to create client: %v", err) } - collectorBuilder.WithKubeClient(kubeClient) + storeBuilder.WithKubeClient(kubeClient) ksmMetricsRegistry := prometheus.NewRegistry() ksmMetricsRegistry.Register(prometheus.NewProcessCollector(prometheus.ProcessCollectorOpts{})) ksmMetricsRegistry.Register(prometheus.NewGoCollector()) go telemetryServer(ksmMetricsRegistry, opts.TelemetryHost, opts.TelemetryPort) - collectors := collectorBuilder.Build() + stores := storeBuilder.Build() - serveMetrics(collectors, opts.Host, opts.Port, opts.EnableGZIPEncoding) + serveMetrics(stores, opts.Host, opts.Port, opts.EnableGZIPEncoding) } func createKubeClient(apiserver string, kubeconfig string) (clientset.Interface, error) { @@ -203,7 +203,7 @@ func telemetryServer(registry prometheus.Gatherer, host string, port int) { log.Fatal(http.ListenAndServe(listenAddress, mux)) } -func serveMetrics(collectors []*metricsstore.MetricsStore, host string, port int, enableGZIPEncoding bool) { +func serveMetrics(stores []*metricsstore.MetricsStore, host string, port int, enableGZIPEncoding bool) { // Address to listen on for web interface and telemetry listenAddress := net.JoinHostPort(host, strconv.Itoa(port)) @@ -219,7 +219,7 @@ func serveMetrics(collectors []*metricsstore.MetricsStore, host string, port int mux.Handle("/debug/pprof/trace", http.HandlerFunc(pprof.Trace)) // Add metricsPath - mux.Handle(metricsPath, &metricHandler{collectors, enableGZIPEncoding}) + mux.Handle(metricsPath, &metricHandler{stores, enableGZIPEncoding}) // Add healthzPath mux.HandleFunc(healthzPath, func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) @@ -242,7 +242,7 @@ func serveMetrics(collectors []*metricsstore.MetricsStore, host string, port int } type metricHandler struct { - collectors []*metricsstore.MetricsStore + stores []*metricsstore.MetricsStore enableGZIPEncoding bool } @@ -268,7 +268,7 @@ func (m *metricHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { } } - for _, c := range m.collectors { + for _, c := range m.stores { c.WriteAll(w) } diff --git a/main_test.go b/main_test.go index 5e0b3a5f53..db0cbe50a7 100644 --- a/main_test.go +++ b/main_test.go @@ -27,19 +27,19 @@ import ( "testing" "time" - kcoll "k8s.io/kube-state-metrics/internal/collector" + "k8s.io/kube-state-metrics/internal/store" metricsstore "k8s.io/kube-state-metrics/pkg/metrics_store" "k8s.io/kube-state-metrics/pkg/options" + "k8s.io/kube-state-metrics/pkg/whiteblacklist" v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes/fake" - "k8s.io/kube-state-metrics/pkg/whiteblacklist" ) func BenchmarkKubeStateMetrics(b *testing.B) { - var collectors []*metricsstore.MetricsStore + var stores []*metricsstore.MetricsStore fixtureMultiplier := 1000 requestCount := 1000 @@ -56,8 +56,8 @@ func BenchmarkKubeStateMetrics(b *testing.B) { } ctx, cancel := context.WithCancel(context.Background()) defer cancel() - builder := kcoll.NewBuilder(ctx) - builder.WithEnabledCollectors(options.DefaultCollectors.AsSlice()) + builder := store.NewBuilder(ctx) + builder.WithEnabledResources(options.DefaultCollectors.AsSlice()) builder.WithKubeClient(kubeClient) builder.WithNamespaces(options.DefaultNamespaces) @@ -70,13 +70,13 @@ func BenchmarkKubeStateMetrics(b *testing.B) { // This test is not suitable to be compared in terms of time, as it includes // a one second wait. Use for memory allocation comparisons, profiling, ... b.Run("GenerateMetrics", func(b *testing.B) { - collectors = builder.Build() + stores = builder.Build() // Wait for caches to fill time.Sleep(time.Second) }) - handler := metricHandler{collectors, false} + handler := metricHandler{stores, false} req := httptest.NewRequest("GET", "http://localhost:8080/metrics", nil) b.Run("MakeRequests", func(b *testing.B) { @@ -116,8 +116,8 @@ func TestFullScrapeCycle(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - builder := kcoll.NewBuilder(ctx) - builder.WithEnabledCollectors(options.DefaultCollectors.AsSlice()) + builder := store.NewBuilder(ctx) + builder.WithEnabledResources(options.DefaultCollectors.AsSlice()) builder.WithKubeClient(kubeClient) builder.WithNamespaces(options.DefaultNamespaces) @@ -127,12 +127,12 @@ func TestFullScrapeCycle(t *testing.T) { } builder.WithWhiteBlackList(l) - collectors := builder.Build() + stores := builder.Build() // Wait for caches to fill time.Sleep(time.Second) - handler := metricHandler{collectors, false} + handler := metricHandler{stores, false} req := httptest.NewRequest("GET", "http://localhost:8080/metrics", nil) w := httptest.NewRecorder() diff --git a/tests/e2e.sh b/tests/e2e.sh index c6e22dd095..67bfd8b622 100755 --- a/tests/e2e.sh +++ b/tests/e2e.sh @@ -166,11 +166,11 @@ echo "check metrics format with promtool" [[ -n "$E2E_SETUP_PROMTOOL" ]] && setup_promtool < ${KUBE_STATE_METRICS_LOG_DIR}/metrics promtool check metrics -collectors=$(find internal/collector/ -maxdepth 1 -name "*.go" -not -name "*_test.go" -not -name "builder.go" -not -name "testutils.go" -not -name "utils.go" -print0 | xargs -0 -n1 basename | awk -F. '{print $1}') -echo "available collectors: $collectors" -for collector in ${collectors}; do - echo "checking that kube_${collector}* metrics exists" - grep "^kube_${collector}_" ${KUBE_STATE_METRICS_LOG_DIR}/metrics +resources=$(find internal/store/ -maxdepth 1 -name "*.go" -not -name "*_test.go" -not -name "builder.go" -not -name "testutils.go" -not -name "utils.go" -print0 | xargs -0 -n1 basename | awk -F. '{print $1}') +echo "available resources: $resources" +for resource in ${resources}; do + echo "checking that kube_${resource}* metrics exists" + grep "^kube_${resource}_" ${KUBE_STATE_METRICS_LOG_DIR}/metrics done KUBE_STATE_METRICS_STATUS=$(curl -s "http://localhost:8001/api/v1/namespaces/kube-system/services/kube-state-metrics:http-metrics/proxy/healthz")