github.com/fabianvf/ocp-release-operator-sdk@v0.0.0-20190426141702-57620ee2f090/pkg/metrics/service-monitor.go (about)

     1  // Copyright 2018 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 metrics
    16  
    17  import (
    18  	monitoringv1 "github.com/coreos/prometheus-operator/pkg/apis/monitoring/v1"
    19  	monclientv1 "github.com/coreos/prometheus-operator/pkg/client/versioned/typed/monitoring/v1"
    20  	"github.com/operator-framework/operator-sdk/pkg/k8sutil"
    21  	v1 "k8s.io/api/core/v1"
    22  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    23  	"k8s.io/client-go/discovery"
    24  	"k8s.io/client-go/rest"
    25  )
    26  
    27  // CreateServiceMonitors creates ServiceMonitors objects based on an array of Service objects.
    28  // If CR ServiceMonitor is not registered in the Cluster it will not attempt at creating resources.
    29  func CreateServiceMonitors(config *rest.Config, ns string, services []*v1.Service) ([]*monitoringv1.ServiceMonitor, error) {
    30  	// check if we can even create ServiceMonitors
    31  	exists, err := hasServiceMonitor(config)
    32  	if err != nil {
    33  		return nil, err
    34  	}
    35  	if !exists {
    36  		// ServiceMonitor was not registered, but we don't want to produce more errors just return.
    37  		return nil, nil
    38  	}
    39  
    40  	var serviceMonitors []*monitoringv1.ServiceMonitor
    41  	mclient := monclientv1.NewForConfigOrDie(config)
    42  
    43  	for _, s := range services {
    44  		sm := GenerateServiceMonitor(s)
    45  		smc, err := mclient.ServiceMonitors(ns).Create(sm)
    46  		if err != nil {
    47  			return serviceMonitors, err
    48  		}
    49  		serviceMonitors = append(serviceMonitors, smc)
    50  	}
    51  
    52  	return serviceMonitors, nil
    53  }
    54  
    55  // GenerateServiceMonitor generates a prometheus-operator ServiceMonitor object
    56  // based on the passed Service object.
    57  func GenerateServiceMonitor(s *v1.Service) *monitoringv1.ServiceMonitor {
    58  	labels := make(map[string]string)
    59  	for k, v := range s.ObjectMeta.Labels {
    60  		labels[k] = v
    61  	}
    62  
    63  	return &monitoringv1.ServiceMonitor{
    64  		TypeMeta: metav1.TypeMeta{
    65  			Kind:       "ServiceMonitor",
    66  			APIVersion: "monitoring.coreos.com/v1",
    67  		},
    68  		ObjectMeta: metav1.ObjectMeta{
    69  			Name:      s.ObjectMeta.Name,
    70  			Namespace: s.ObjectMeta.Namespace,
    71  			Labels:    labels,
    72  		},
    73  		Spec: monitoringv1.ServiceMonitorSpec{
    74  			Selector: metav1.LabelSelector{
    75  				MatchLabels: labels,
    76  			},
    77  			Endpoints: []monitoringv1.Endpoint{
    78  				{
    79  					Port: s.Spec.Ports[0].Name,
    80  				},
    81  			},
    82  		},
    83  	}
    84  }
    85  
    86  // hasServiceMonitor checks if ServiceMonitor is registered in the cluster.
    87  func hasServiceMonitor(config *rest.Config) (bool, error) {
    88  	dc := discovery.NewDiscoveryClientForConfigOrDie(config)
    89  	apiVersion := "monitoring.coreos.com/v1"
    90  	kind := "ServiceMonitor"
    91  
    92  	return k8sutil.ResourceExists(dc, apiVersion, kind)
    93  }