1
0
mirror of https://github.com/ribbybibby/ssl_exporter.git synced 2025-07-12 23:50:14 +02:00
Files
ssl_exporter/prober/kubernetes.go

97 lines
2.7 KiB
Go
Raw Normal View History

2020-11-15 22:05:51 +00:00
package prober
import (
"context"
"fmt"
"regexp"
2020-11-15 22:05:51 +00:00
"strings"
"github.com/bmatcuk/doublestar/v2"
"github.com/go-kit/log"
2020-11-15 22:05:51 +00:00
"github.com/prometheus/client_golang/prometheus"
2022-05-07 09:31:08 +01:00
"github.com/ribbybibby/ssl_exporter/v2/config"
2020-11-15 22:05:51 +00:00
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/clientcmd"
// Support oidc in kube config files
_ "k8s.io/client-go/plugin/pkg/client/auth/oidc"
)
var (
2020-11-16 00:48:15 +00:00
// ErrKubeBadTarget is returned when the target doesn't match the
// expected form for the kubernetes prober
2020-11-15 22:05:51 +00:00
ErrKubeBadTarget = fmt.Errorf("Target secret must be provided in the form: <namespace>/<name>")
globPattern = regexp.MustCompile(`^.*(\*|\?|\{|\}|\[|\])+.*$`)
2020-11-15 22:05:51 +00:00
)
2020-11-16 00:48:15 +00:00
// ProbeKubernetes collects certificate metrics from kubernetes.io/tls Secrets
func ProbeKubernetes(ctx context.Context, logger log.Logger, target string, module config.Module, registry *prometheus.Registry) error {
2020-11-15 22:05:51 +00:00
client, err := newKubeClient(module.Kubernetes.Kubeconfig)
if err != nil {
return err
}
return probeKubernetes(ctx, target, module, registry, client)
}
func probeKubernetes(ctx context.Context, target string, module config.Module, registry *prometheus.Registry, client kubernetes.Interface) error {
parts := strings.Split(target, "/")
if len(parts) != 2 || parts[0] == "" || parts[1] == "" {
return ErrKubeBadTarget
}
ns := parts[0]
name := parts[1]
// If the namespace contains a glob pattern then we need to filter on
// all the secrets in the cluster
selector := ns
if globPattern.MatchString(ns) {
selector = ""
}
2020-11-15 22:05:51 +00:00
var tlsSecrets []v1.Secret
secrets, err := client.CoreV1().Secrets(selector).List(ctx, metav1.ListOptions{FieldSelector: "type=kubernetes.io/tls"})
2020-11-15 22:05:51 +00:00
if err != nil {
return err
}
for _, secret := range secrets.Items {
nMatch, err := doublestar.Match(ns, secret.Namespace)
if err != nil {
return err
}
sMatch, err := doublestar.Match(name, secret.Name)
if err != nil {
return err
}
if nMatch && sMatch {
tlsSecrets = append(tlsSecrets, secret)
2020-11-15 22:05:51 +00:00
}
}
return collectKubernetesSecretMetrics(tlsSecrets, registry)
}
// newKubeClient returns a Kubernetes client (clientset) from the supplied
// kubeconfig path, the KUBECONFIG environment variable, the default config file
// location ($HOME/.kube/config) or from the in-cluster service account environment.
func newKubeClient(path string) (*kubernetes.Clientset, error) {
loadingRules := clientcmd.NewDefaultClientConfigLoadingRules()
if path != "" {
loadingRules.ExplicitPath = path
}
kubeConfig := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(
loadingRules,
&clientcmd.ConfigOverrides{},
)
config, err := kubeConfig.ClientConfig()
if err != nil {
return nil, err
}
return kubernetes.NewForConfig(config)
}