Code refactoring for bpa operator
[icn.git] / cmd / bpa-operator / vendor / github.com / operator-framework / operator-sdk / pkg / kube-metrics / collector.go
1 // Copyright 2019 The Operator-SDK Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 package kubemetrics
16
17 import (
18         "context"
19
20         metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
21         "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
22         "k8s.io/apimachinery/pkg/runtime"
23         "k8s.io/apimachinery/pkg/watch"
24         "k8s.io/client-go/dynamic"
25         "k8s.io/client-go/tools/cache"
26         kcollector "k8s.io/kube-state-metrics/pkg/collector"
27         "k8s.io/kube-state-metrics/pkg/metric"
28         metricsstore "k8s.io/kube-state-metrics/pkg/metrics_store"
29 )
30
31 // NewCollectors returns collections of metrics in the namespaces provided, per the api/kind resource.
32 // The metrics are registered in the custom generateStore function that needs to be defined.
33 func NewCollectors(dclient dynamic.NamespaceableResourceInterface, namespaces []string, api string, kind string, metricFamily []metric.FamilyGenerator) []kcollector.Collector {
34         namespaces = deduplicateNamespaces(namespaces)
35         var collectors []kcollector.Collector
36         // Generate collector per namespace.
37         for _, ns := range namespaces {
38                 composedMetricGenFuncs := metric.ComposeMetricGenFuncs(metricFamily)
39                 headers := metric.ExtractMetricFamilyHeaders(metricFamily)
40                 store := metricsstore.NewMetricsStore(headers, composedMetricGenFuncs)
41                 reflectorPerNamespace(context.TODO(), dclient, &unstructured.Unstructured{}, store, ns)
42                 collector := kcollector.NewCollector(store)
43                 collectors = append(collectors, *collector)
44         }
45         return collectors
46 }
47
48 func deduplicateNamespaces(ns []string) (list []string) {
49         keys := make(map[string]struct{})
50         for _, entry := range ns {
51                 if _, ok := keys[entry]; !ok {
52                         keys[entry] = struct{}{}
53                         list = append(list, entry)
54                 }
55         }
56         return list
57 }
58
59 func reflectorPerNamespace(
60         ctx context.Context,
61         dynamicInterface dynamic.NamespaceableResourceInterface,
62         expectedType interface{},
63         store cache.Store,
64         ns string,
65 ) {
66         lw := listWatchFunc(dynamicInterface, ns)
67         reflector := cache.NewReflector(&lw, expectedType, store, 0)
68         go reflector.Run(ctx.Done())
69 }
70
71 func listWatchFunc(dynamicInterface dynamic.NamespaceableResourceInterface, namespace string) cache.ListWatch {
72         return cache.ListWatch{
73                 ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) {
74                         return dynamicInterface.Namespace(namespace).List(opts)
75                 },
76                 WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) {
77                         return dynamicInterface.Namespace(namespace).Watch(opts)
78                 },
79         }
80 }