Remove BPA from Makefile
[icn.git] / cmd / bpa-operator / vendor / github.com / operator-framework / operator-sdk / pkg / kube-metrics / metrics.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         "fmt"
19         "strings"
20
21         "github.com/pkg/errors"
22         "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
23         "k8s.io/apimachinery/pkg/runtime/schema"
24         "k8s.io/client-go/rest"
25         kcollector "k8s.io/kube-state-metrics/pkg/collector"
26         ksmetric "k8s.io/kube-state-metrics/pkg/metric"
27         logf "sigs.k8s.io/controller-runtime/pkg/runtime/log"
28 )
29
30 var log = logf.Log.WithName("kubemetrics")
31
32 // GenerateAndServeCRMetrics generates CustomResource specific metrics for each custom resource GVK in operatorGVKs.
33 // A list of namespaces, ns, can be passed to ServeCRMetrics to scope the generated metrics. Passing nil or
34 // an empty list of namespaces will result in an error.
35 // The function also starts serving the generated collections of the metrics on given host and port.
36 func GenerateAndServeCRMetrics(cfg *rest.Config,
37         ns []string,
38         operatorGVKs []schema.GroupVersionKind,
39         host string, port int32) error {
40         // We have to have at least one namespace.
41         if len(ns) < 1 {
42                 return errors.New("namespaces were empty; pass at least one namespace to generate custom resource metrics")
43         }
44         // Create new unstructured client.
45         var collectors [][]kcollector.Collector
46         log.V(1).Info("Starting collecting operator types")
47         // Loop through all the possible operator/custom resource specific types.
48         for _, gvk := range operatorGVKs {
49                 apiVersion := gvk.GroupVersion().String()
50                 kind := gvk.Kind
51                 // Generate metric based on the kind.
52                 metricFamilies := generateMetricFamilies(gvk.Kind)
53                 log.V(1).Info("Generating metric families", "apiVersion", apiVersion, "kind", kind)
54                 dclient, err := newClientForGVK(cfg, apiVersion, kind)
55                 if err != nil {
56                         return err
57                 }
58                 // Generate collector based on the group/version, kind and the metric families.
59                 c := NewCollectors(dclient, ns, apiVersion, kind, metricFamilies)
60                 collectors = append(collectors, c)
61         }
62         // Start serving metrics.
63         log.V(1).Info("Starting serving custom resource metrics")
64         go ServeMetrics(collectors, host, port)
65
66         return nil
67 }
68
69 func generateMetricFamilies(kind string) []ksmetric.FamilyGenerator {
70         helpText := fmt.Sprintf("Information about the %s custom resource.", kind)
71         kindName := strings.ToLower(kind)
72         metricName := fmt.Sprintf("%s_info", kindName)
73
74         return []ksmetric.FamilyGenerator{
75                 ksmetric.FamilyGenerator{
76                         Name: metricName,
77                         Type: ksmetric.Gauge,
78                         Help: helpText,
79                         GenerateFunc: func(obj interface{}) *ksmetric.Family {
80                                 crd := obj.(*unstructured.Unstructured)
81                                 return &ksmetric.Family{
82                                         Metrics: []*ksmetric.Metric{
83                                                 {
84                                                         Value:       1,
85                                                         LabelKeys:   []string{"namespace", kindName},
86                                                         LabelValues: []string{crd.GetNamespace(), crd.GetName()},
87                                                 },
88                                         },
89                                 }
90                         },
91                 },
92         }
93 }