1 // Copyright 2018 The Operator-SDK Authors
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
7 // http://www.apache.org/licenses/LICENSE-2.0
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.
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"
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)
36 // ServiceMonitor was not registered, but we don't want to produce more errors just return.
40 var serviceMonitors []*monitoringv1.ServiceMonitor
41 mclient := monclientv1.NewForConfigOrDie(config)
43 for _, s := range services {
44 sm := GenerateServiceMonitor(s)
45 smc, err := mclient.ServiceMonitors(ns).Create(sm)
47 return serviceMonitors, err
49 serviceMonitors = append(serviceMonitors, smc)
52 return serviceMonitors, nil
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 {
62 endpoints := populateEndpointsFromServicePorts(s)
64 return &monitoringv1.ServiceMonitor{
65 ObjectMeta: metav1.ObjectMeta{
66 Name: s.ObjectMeta.Name,
67 Namespace: s.ObjectMeta.Namespace,
70 Spec: monitoringv1.ServiceMonitorSpec{
71 Selector: metav1.LabelSelector{
79 func populateEndpointsFromServicePorts(s *v1.Service) []monitoringv1.Endpoint {
80 var endpoints []monitoringv1.Endpoint
81 for _, port := range s.Spec.Ports {
82 endpoints = append(endpoints, monitoringv1.Endpoint{Port: port.Name})
87 // hasServiceMonitor checks if ServiceMonitor is registered in the cluster.
88 func hasServiceMonitor(config *rest.Config) (bool, error) {
89 dc := discovery.NewDiscoveryClientForConfigOrDie(config)
90 apiVersion := "monitoring.coreos.com/v1"
91 kind := "ServiceMonitor"
93 return k8sutil.ResourceExists(dc, apiVersion, kind)