commit 4b4191d06088103bd6024e12931f0898518d4a40 Author: Fabian Reinartz <fab.reinartz@gmail.com> Date: Wed Sep 21 13:48:13 2016 +0200 Initial commit. Adds a basic controller that creates a client and connects to a Kubernetes cluster from within or external. diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 000000000..47bf1b926 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,5 @@ +FROM quay.io/prometheus/busybox:latest + +ADD controller /bin/controller + +ENTRYPOINT ["/bin/controller"] \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 000000000..05fb6df79 --- /dev/null +++ b/Makefile @@ -0,0 +1,2 @@ +build: + go build github.com/coreos/kube-prometheus-controller/cmd/controller diff --git a/cmd/controller/main.go b/cmd/controller/main.go new file mode 100644 index 000000000..db6bb6237 --- /dev/null +++ b/cmd/controller/main.go @@ -0,0 +1,36 @@ +package main + +import ( + "flag" + "fmt" + "os" + + "github.com/coreos/kube-prometheus-controller/pkg/controller" +) + +var cfg controller.Config + +func init() { + flagset := flag.NewFlagSet(os.Args[0], flag.ExitOnError) + + flagset.StringVar(&cfg.Host, "apiserver", "", "API Server addr, e.g. ' - NOT RECOMMENDED FOR PRODUCTION - http://127.0.0.1:8080'. Omit parameter to run in on-cluster mode and utilize the service account token.") + flagset.StringVar(&cfg.TLSConfig.CertFile, "cert-file", "", " - NOT RECOMMENDED FOR PRODUCTION - Path to public TLS certificate file.") + flagset.StringVar(&cfg.TLSConfig.KeyFile, "key-file", "", "- NOT RECOMMENDED FOR PRODUCTION - Path to private TLS certificate file.") + flagset.StringVar(&cfg.TLSConfig.CAFile, "ca-file", "", "- NOT RECOMMENDED FOR PRODUCTION - Path to TLS CA file.") + flagset.BoolVar(&cfg.TLSInsecure, "tls-insecure", false, "- NOT RECOMMENDED FOR PRODUCTION - Don't verify API server's CA certificate.") + + flagset.Parse(os.Args[1:]) +} + +func main() { + + c, err := controller.New(cfg) + if err != nil { + fmt.Fprint(os.Stderr, err) + os.Exit(1) + } + if err := c.Run(); err != nil { + fmt.Fprint(os.Stderr, err) + os.Exit(1) + } +} diff --git a/example/prometheus-controller.yaml b/example/prometheus-controller.yaml new file mode 100644 index 000000000..4ec4fbe90 --- /dev/null +++ b/example/prometheus-controller.yaml @@ -0,0 +1,10 @@ +apiVersion: v2 +kind: Pod +metadata: + name: prometheus-ctrl + labels: + name: prometheus-ctrl +spec: + containers: + - name: prometheus-ctrl + image: quay.io/fabxc/prometheus-ctrl:latest diff --git a/hack/controller-external.sh b/hack/controller-external.sh new file mode 100755 index 000000000..29f6a392d --- /dev/null +++ b/hack/controller-external.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +if [[ -z "$1" ]]; then + echo "missing cluster name" + exit 1 +fi + +apiserver=$(kubectl config view -o jsonpath="{.clusters[?(@.name == \"$1\")].cluster.server}") +cafile=$(kubectl config view -o jsonpath="{.clusters[?(@.name == \"$1\")].cluster.certificate-authority}") +certfile=$(kubectl config view -o jsonpath="{.users[?(@.name == \"$1\")].user.client-certificate}") +keyfile=$(kubectl config view -o jsonpath="{.users[?(@.name == \"$1\")].user.client-key}") + +./controller --apiserver=$apiserver --ca-file=$cafile --cert-file=$certfile --key-file=$keyfile diff --git a/pkg/controller/controller.go b/pkg/controller/controller.go new file mode 100644 index 000000000..b0222c3dc --- /dev/null +++ b/pkg/controller/controller.go @@ -0,0 +1,84 @@ +package controller + +import ( + "fmt" + "net/url" + "os" + + "github.com/go-kit/kit/log" + "k8s.io/client-go/1.4/kubernetes" + "k8s.io/client-go/1.4/rest" +) + +const ( + tprMonitor = "monitor.prometheus.coreos.com" + tprPrometheus = "prometheus.prometheus.coreos.com" +) + +// Controller manages lify cycle of Prometheus deployments and +// monitoring configurations. +type Controller struct { + kclient *kubernetes.Clientset + logger log.Logger +} + +type Config struct { + Host string + TLSInsecure bool + TLSConfig rest.TLSClientConfig +} + +func newClient(host string, tlsInsecure bool, tlsConfig *rest.TLSClientConfig) (*kubernetes.Clientset, error) { + var cfg *rest.Config + var err error + + if len(host) == 0 { + if cfg, err = rest.InClusterConfig(); err != nil { + return nil, err + } + } else { + cfg = &rest.Config{ + Host: host, + } + hostURL, err := url.Parse(host) + if err != nil { + return nil, fmt.Errorf("error parsing host url %s : %v", host, err) + } + if hostURL.Scheme == "https" { + cfg.TLSClientConfig = *tlsConfig + cfg.Insecure = tlsInsecure + } + } + cfg.QPS = 100 + cfg.Burst = 100 + + c, err := kubernetes.NewForConfig(cfg) + if err != nil { + return nil, err + } + return c, nil +} + +// New creates a new controller. +func New(c Config) (*Controller, error) { + client, err := newClient(c.Host, c.TLSInsecure, &c.TLSConfig) + if err != nil { + return nil, err + } + return &Controller{ + kclient: client, + logger: log.NewLogfmtLogger(os.Stdout), + }, nil +} + +// Run the controller. +func (c *Controller) Run() error { + v, err := c.kclient.Discovery().ServerVersion() + if err != nil { + return fmt.Errorf("communicating with server failed: %s", err) + } + c.logger.Log("msg", "connection established", "version", v) + + select {} + panic("unreachable") +}