mirror of
https://github.com/prometheus-operator/prometheus-operator.git
synced 2025-04-21 03:38:43 +00:00
commit
addcad5bc8
15 changed files with 321 additions and 92 deletions
22
Makefile
22
Makefile
|
@ -1,15 +1,25 @@
|
|||
all: build
|
||||
|
||||
REPO?=quay.io/coreos/prometheus-operator
|
||||
TAG?=$(shell git rev-parse --short HEAD)
|
||||
NAMESPACE?=prometheus-operator-e2e-tests-$(shell LC_CTYPE=C tr -dc a-z0-9 < /dev/urandom | head -c 13 ; echo '')
|
||||
|
||||
CLUSTER_IP?=$(shell minikube ip)
|
||||
|
||||
pkgs = $(shell go list ./... | grep -v /vendor/ | grep -v /test/)
|
||||
|
||||
all: check-license format build test
|
||||
|
||||
build:
|
||||
./scripts/check_license.sh
|
||||
go build github.com/coreos/prometheus-operator/cmd/operator
|
||||
|
||||
test:
|
||||
@go test -short $(pkgs)
|
||||
|
||||
format:
|
||||
go fmt $(pkgs)
|
||||
|
||||
check-license:
|
||||
./scripts/check_license.sh
|
||||
|
||||
container:
|
||||
GOOS=linux $(MAKE) build
|
||||
docker build -t $(REPO):$(TAG) .
|
||||
|
@ -18,14 +28,14 @@ e2e-test:
|
|||
go test -timeout 20m -v ./test/e2e/ $(TEST_RUN_ARGS) --kubeconfig "$(HOME)/.kube/config" --operator-image=quay.io/coreos/prometheus-operator:$(TAG) --namespace=$(NAMESPACE) --cluster-ip=$(CLUSTER_IP)
|
||||
|
||||
e2e-status:
|
||||
kubectl get prometheus,alertmanager,servicemonitor,statefulsets,deploy,svc,endpoints,pods --all-namespaces
|
||||
kubectl get prometheus,alertmanager,servicemonitor,statefulsets,deploy,svc,endpoints,pods,cm --all-namespaces
|
||||
|
||||
e2e:
|
||||
$(MAKE) container
|
||||
$(MAKE) e2e-test
|
||||
|
||||
clean-e2e:
|
||||
kubectl -n $(NAMESPACE) delete prometheus,alertmanager,servicemonitor,statefulsets,deploy,svc,endpoints,pods --all
|
||||
kubectl -n $(NAMESPACE) delete prometheus,alertmanager,servicemonitor,statefulsets,deploy,svc,endpoints,pods,cm --all
|
||||
kubectl delete namespace $(NAMESPACE)
|
||||
|
||||
.PHONY: all build container e2e clean-e2e
|
||||
.PHONY: all build test format check-license container e2e-test e2e-status e2e clean-e2e
|
||||
|
|
|
@ -11,4 +11,4 @@ spec:
|
|||
protocol: TCP
|
||||
targetPort: web
|
||||
selector:
|
||||
alertmanager: alertmanager-main
|
||||
alertmanager: main
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
apiVersion: "monitoring.coreos.com/v1alpha1"
|
||||
kind: "Alertmanager"
|
||||
metadata:
|
||||
name: "alertmanager-main"
|
||||
name: "main"
|
||||
labels:
|
||||
alertmanager: "main"
|
||||
spec:
|
||||
|
|
|
@ -11,4 +11,4 @@ spec:
|
|||
protocol: TCP
|
||||
targetPort: web
|
||||
selector:
|
||||
prometheus: prometheus-main
|
||||
prometheus: main
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
apiVersion: "monitoring.coreos.com/v1alpha1"
|
||||
kind: "Prometheus"
|
||||
metadata:
|
||||
name: "prometheus-main"
|
||||
name: "main"
|
||||
labels:
|
||||
prometheus: "main"
|
||||
spec:
|
||||
|
|
|
@ -225,13 +225,14 @@ func (c *Operator) worker() {
|
|||
}
|
||||
}
|
||||
|
||||
func (c *Operator) alertmanagerForStatefulSet(ps interface{}) *v1alpha1.Alertmanager {
|
||||
key, ok := c.keyFunc(ps)
|
||||
func (c *Operator) alertmanagerForStatefulSet(sset interface{}) *v1alpha1.Alertmanager {
|
||||
key, ok := c.keyFunc(sset)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
// Namespace/Name are one-to-one so the key will find the respective Alertmanager resource.
|
||||
a, exists, err := c.alrtInf.GetStore().GetByKey(key)
|
||||
|
||||
aKey := statefulSetKeyToAlertmanagerKey(key)
|
||||
a, exists, err := c.alrtInf.GetStore().GetByKey(aKey)
|
||||
if err != nil {
|
||||
utilruntime.HandleError(fmt.Errorf("get Alertmanager resource: %s", err))
|
||||
return nil
|
||||
|
@ -242,6 +243,20 @@ func (c *Operator) alertmanagerForStatefulSet(ps interface{}) *v1alpha1.Alertman
|
|||
return a.(*v1alpha1.Alertmanager)
|
||||
}
|
||||
|
||||
func alertmanagerNameFromStatefulSetName(name string) string {
|
||||
return strings.TrimPrefix(name, "alertmanager-")
|
||||
}
|
||||
|
||||
func statefulSetKeyToAlertmanagerKey(key string) string {
|
||||
keyParts := strings.Split(key, "/")
|
||||
return keyParts[0] + "/" + strings.TrimPrefix(keyParts[1], "alertmanager-")
|
||||
}
|
||||
|
||||
func alertmanagerKeyToStatefulSetKey(key string) string {
|
||||
keyParts := strings.Split(key, "/")
|
||||
return keyParts[0] + "/alertmanager-" + keyParts[1]
|
||||
}
|
||||
|
||||
func (c *Operator) handleAlertmanagerAdd(obj interface{}) {
|
||||
key, ok := c.keyFunc(obj)
|
||||
if !ok {
|
||||
|
@ -336,7 +351,7 @@ func (c *Operator) sync(key string) error {
|
|||
|
||||
ssetClient := c.kclient.Apps().StatefulSets(am.Namespace)
|
||||
// Ensure we have a StatefulSet running Alertmanager deployed.
|
||||
obj, exists, err = c.ssetInf.GetIndexer().GetByKey(key)
|
||||
obj, exists, err = c.ssetInf.GetIndexer().GetByKey(alertmanagerKeyToStatefulSetKey(key))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -433,7 +448,8 @@ func AlertmanagerStatus(kclient *kubernetes.Clientset, a *v1alpha1.Alertmanager)
|
|||
}
|
||||
|
||||
func (c *Operator) destroyAlertmanager(key string) error {
|
||||
obj, exists, err := c.ssetInf.GetStore().GetByKey(key)
|
||||
ssetKey := alertmanagerKeyToStatefulSetKey(key)
|
||||
obj, exists, err := c.ssetInf.GetStore().GetByKey(ssetKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -455,7 +471,7 @@ func (c *Operator) destroyAlertmanager(key string) error {
|
|||
// TODO(fabxc): temporary solution until StatefulSet status provides necessary info to know
|
||||
// whether scale-down completed.
|
||||
for {
|
||||
pods, err := podClient.List(ListOptions(sset.Name))
|
||||
pods, err := podClient.List(ListOptions(alertmanagerNameFromStatefulSetName(sset.Name)))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -27,30 +27,39 @@ import (
|
|||
"github.com/coreos/prometheus-operator/pkg/client/monitoring/v1alpha1"
|
||||
)
|
||||
|
||||
const (
|
||||
governingServiceName = "alertmanager-operated"
|
||||
defaultBaseImage = "quay.io/prometheus/alertmanager"
|
||||
defaultVersion = "v0.5.1"
|
||||
minReplicas = 1
|
||||
)
|
||||
|
||||
func makeStatefulSet(am *v1alpha1.Alertmanager, old *v1beta1.StatefulSet) *v1beta1.StatefulSet {
|
||||
// TODO(fabxc): is this the right point to inject defaults?
|
||||
// Ideally we would do it before storing but that's currently not possible.
|
||||
// Potentially an update handler on first insertion.
|
||||
|
||||
if am.Spec.BaseImage == "" {
|
||||
am.Spec.BaseImage = "quay.io/prometheus/alertmanager"
|
||||
am.Spec.BaseImage = defaultBaseImage
|
||||
}
|
||||
if am.Spec.Version == "" {
|
||||
am.Spec.Version = "v0.5.1"
|
||||
am.Spec.Version = defaultVersion
|
||||
}
|
||||
if am.Spec.Replicas < 1 {
|
||||
am.Spec.Replicas = 1
|
||||
if am.Spec.Replicas < minReplicas {
|
||||
am.Spec.Replicas = minReplicas
|
||||
}
|
||||
|
||||
statefulset := &v1beta1.StatefulSet{
|
||||
ObjectMeta: v1.ObjectMeta{
|
||||
Name: am.Name,
|
||||
Name: prefixedName(am.Name),
|
||||
Labels: am.ObjectMeta.Labels,
|
||||
Annotations: am.ObjectMeta.Annotations,
|
||||
},
|
||||
Spec: makeStatefulSetSpec(am),
|
||||
}
|
||||
if vc := am.Spec.Storage; vc == nil {
|
||||
statefulset.Spec.Template.Spec.Volumes = append(statefulset.Spec.Template.Spec.Volumes, v1.Volume{
|
||||
Name: fmt.Sprintf("%s-db", am.Name),
|
||||
Name: volumeName(am.Name),
|
||||
VolumeSource: v1.VolumeSource{
|
||||
EmptyDir: &v1.EmptyDirVolumeSource{},
|
||||
},
|
||||
|
@ -58,7 +67,7 @@ func makeStatefulSet(am *v1alpha1.Alertmanager, old *v1beta1.StatefulSet) *v1bet
|
|||
} else {
|
||||
pvc := v1.PersistentVolumeClaim{
|
||||
ObjectMeta: v1.ObjectMeta{
|
||||
Name: fmt.Sprintf("%s-db", am.Name),
|
||||
Name: volumeName(am.Name),
|
||||
},
|
||||
Spec: v1.PersistentVolumeClaimSpec{
|
||||
AccessModes: []v1.PersistentVolumeAccessMode{v1.ReadWriteOnce},
|
||||
|
@ -83,7 +92,7 @@ func makeStatefulSet(am *v1alpha1.Alertmanager, old *v1beta1.StatefulSet) *v1bet
|
|||
func makeStatefulSetService(p *v1alpha1.Alertmanager) *v1.Service {
|
||||
svc := &v1.Service{
|
||||
ObjectMeta: v1.ObjectMeta{
|
||||
Name: "alertmanager",
|
||||
Name: governingServiceName,
|
||||
},
|
||||
Spec: v1.ServiceSpec{
|
||||
ClusterIP: "None",
|
||||
|
@ -136,12 +145,12 @@ func makeStatefulSetSpec(a *v1alpha1.Alertmanager) v1beta1.StatefulSetSpec {
|
|||
}
|
||||
|
||||
for i := int32(0); i < a.Spec.Replicas; i++ {
|
||||
commands = append(commands, fmt.Sprintf("-mesh.peer=%s-%d.%s.%s.svc", a.Name, i, "alertmanager", a.Namespace))
|
||||
commands = append(commands, fmt.Sprintf("-mesh.peer=%s-%d.%s.%s.svc", prefixedName(a.Name), i, "alertmanager", a.Namespace))
|
||||
}
|
||||
|
||||
terminationGracePeriod := int64(0)
|
||||
return v1beta1.StatefulSetSpec{
|
||||
ServiceName: "alertmanager",
|
||||
ServiceName: governingServiceName,
|
||||
Replicas: &a.Spec.Replicas,
|
||||
Template: v1.PodTemplateSpec{
|
||||
ObjectMeta: v1.ObjectMeta{
|
||||
|
@ -155,7 +164,7 @@ func makeStatefulSetSpec(a *v1alpha1.Alertmanager) v1beta1.StatefulSetSpec {
|
|||
Containers: []v1.Container{
|
||||
{
|
||||
Command: commands,
|
||||
Name: a.Name,
|
||||
Name: "alertmanager",
|
||||
Image: image,
|
||||
Ports: []v1.ContainerPort{
|
||||
{
|
||||
|
@ -175,7 +184,7 @@ func makeStatefulSetSpec(a *v1alpha1.Alertmanager) v1beta1.StatefulSetSpec {
|
|||
MountPath: "/etc/alertmanager/config",
|
||||
},
|
||||
{
|
||||
Name: fmt.Sprintf("%s-db", a.Name),
|
||||
Name: volumeName(a.Name),
|
||||
MountPath: "/var/alertmanager/data",
|
||||
SubPath: subPathForStorage(a.Spec.Storage),
|
||||
},
|
||||
|
@ -220,7 +229,7 @@ func makeStatefulSetSpec(a *v1alpha1.Alertmanager) v1beta1.StatefulSetSpec {
|
|||
VolumeSource: v1.VolumeSource{
|
||||
ConfigMap: &v1.ConfigMapVolumeSource{
|
||||
LocalObjectReference: v1.LocalObjectReference{
|
||||
Name: a.Name,
|
||||
Name: configConfigMapName(a.Name),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -231,6 +240,18 @@ func makeStatefulSetSpec(a *v1alpha1.Alertmanager) v1beta1.StatefulSetSpec {
|
|||
}
|
||||
}
|
||||
|
||||
func configConfigMapName(name string) string {
|
||||
return prefixedName(name)
|
||||
}
|
||||
|
||||
func volumeName(name string) string {
|
||||
return fmt.Sprintf("%s-db", prefixedName(name))
|
||||
}
|
||||
|
||||
func prefixedName(name string) string {
|
||||
return fmt.Sprintf("alertmanager-%s", name)
|
||||
}
|
||||
|
||||
func subPathForStorage(s *v1alpha1.StorageSpec) string {
|
||||
if s == nil {
|
||||
return ""
|
||||
|
|
|
@ -330,13 +330,14 @@ func (c *Operator) worker() {
|
|||
}
|
||||
}
|
||||
|
||||
func (c *Operator) prometheusForStatefulSet(ps interface{}) *v1alpha1.Prometheus {
|
||||
key, ok := c.keyFunc(ps)
|
||||
func (c *Operator) prometheusForStatefulSet(sset interface{}) *v1alpha1.Prometheus {
|
||||
key, ok := c.keyFunc(sset)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
// Namespace/Name are one-to-one so the key will find the respective Prometheus resource.
|
||||
p, exists, err := c.promInf.GetStore().GetByKey(key)
|
||||
|
||||
promKey := statefulSetKeyToPrometheusKey(key)
|
||||
p, exists, err := c.promInf.GetStore().GetByKey(promKey)
|
||||
if err != nil {
|
||||
c.logger.Log("msg", "Prometheus lookup failed", "err", err)
|
||||
return nil
|
||||
|
@ -347,6 +348,20 @@ func (c *Operator) prometheusForStatefulSet(ps interface{}) *v1alpha1.Prometheus
|
|||
return p.(*v1alpha1.Prometheus)
|
||||
}
|
||||
|
||||
func prometheusNameFromStatefulSetName(name string) string {
|
||||
return strings.TrimPrefix(name, "prometheus-")
|
||||
}
|
||||
|
||||
func statefulSetKeyToPrometheusKey(key string) string {
|
||||
keyParts := strings.Split(key, "/")
|
||||
return keyParts[0] + "/" + strings.TrimPrefix(keyParts[1], "prometheus-")
|
||||
}
|
||||
|
||||
func prometheusKeyToStatefulSetKey(key string) string {
|
||||
keyParts := strings.Split(key, "/")
|
||||
return keyParts[0] + "/prometheus-" + keyParts[1]
|
||||
}
|
||||
|
||||
func (c *Operator) handleDeleteStatefulSet(obj interface{}) {
|
||||
if ps := c.prometheusForStatefulSet(obj); ps != nil {
|
||||
c.enqueue(ps)
|
||||
|
@ -426,7 +441,7 @@ func (c *Operator) sync(key string) error {
|
|||
|
||||
ssetClient := c.kclient.Apps().StatefulSets(p.Namespace)
|
||||
// Ensure we have a StatefulSet running Prometheus deployed.
|
||||
obj, exists, err = c.ssetInf.GetIndexer().GetByKey(key)
|
||||
obj, exists, err = c.ssetInf.GetIndexer().GetByKey(prometheusKeyToStatefulSetKey(key))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -523,7 +538,8 @@ func PrometheusStatus(kclient *kubernetes.Clientset, p *v1alpha1.Prometheus) (*v
|
|||
}
|
||||
|
||||
func (c *Operator) destroyPrometheus(key string) error {
|
||||
obj, exists, err := c.ssetInf.GetStore().GetByKey(key)
|
||||
ssetKey := prometheusKeyToStatefulSetKey(key)
|
||||
obj, exists, err := c.ssetInf.GetStore().GetByKey(ssetKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -545,7 +561,7 @@ func (c *Operator) destroyPrometheus(key string) error {
|
|||
// TODO(fabxc): temprorary solution until StatefulSet status provides necessary info to know
|
||||
// whether scale-down completed.
|
||||
for {
|
||||
pods, err := podClient.List(ListOptions(sset.Name))
|
||||
pods, err := podClient.List(ListOptions(prometheusNameFromStatefulSetName(sset.Name)))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -587,7 +603,7 @@ func (c *Operator) createConfig(p *v1alpha1.Prometheus) error {
|
|||
|
||||
cm := &v1.ConfigMap{
|
||||
ObjectMeta: v1.ObjectMeta{
|
||||
Name: p.Name,
|
||||
Name: configConfigMapName(p.Name),
|
||||
},
|
||||
Data: map[string]string{
|
||||
"prometheus.yaml": string(b),
|
||||
|
@ -596,7 +612,7 @@ func (c *Operator) createConfig(p *v1alpha1.Prometheus) error {
|
|||
|
||||
cmClient := c.kclient.CoreV1().ConfigMaps(p.Namespace)
|
||||
|
||||
_, err = cmClient.Get(p.Name, metav1.GetOptions{})
|
||||
_, err = cmClient.Get(cm.Name, metav1.GetOptions{})
|
||||
if apierrors.IsNotFound(err) {
|
||||
_, err = cmClient.Create(cm)
|
||||
} else if err == nil {
|
||||
|
|
|
@ -27,22 +27,30 @@ import (
|
|||
"github.com/coreos/prometheus-operator/pkg/client/monitoring/v1alpha1"
|
||||
)
|
||||
|
||||
const (
|
||||
governingServiceName = "prometheus-operated"
|
||||
defaultBaseImage = "quay.io/prometheus/prometheus"
|
||||
defaultVersion = "v1.4.0"
|
||||
minReplicas = 1
|
||||
defaultRetention = "24h"
|
||||
)
|
||||
|
||||
func makeStatefulSet(p v1alpha1.Prometheus, old *v1beta1.StatefulSet) *v1beta1.StatefulSet {
|
||||
// TODO(fabxc): is this the right point to inject defaults?
|
||||
// Ideally we would do it before storing but that's currently not possible.
|
||||
// Potentially an update handler on first insertion.
|
||||
|
||||
if p.Spec.BaseImage == "" {
|
||||
p.Spec.BaseImage = "quay.io/prometheus/prometheus"
|
||||
p.Spec.BaseImage = defaultBaseImage
|
||||
}
|
||||
if p.Spec.Version == "" {
|
||||
p.Spec.Version = "v1.4.0"
|
||||
p.Spec.Version = defaultVersion
|
||||
}
|
||||
if p.Spec.Replicas < 1 {
|
||||
p.Spec.Replicas = 1
|
||||
if p.Spec.Replicas < minReplicas {
|
||||
p.Spec.Replicas = minReplicas
|
||||
}
|
||||
if p.Spec.Retention == "" {
|
||||
p.Spec.Retention = "24h"
|
||||
p.Spec.Retention = defaultRetention
|
||||
}
|
||||
|
||||
if p.Spec.Resources.Requests == nil {
|
||||
|
@ -54,13 +62,15 @@ func makeStatefulSet(p v1alpha1.Prometheus, old *v1beta1.StatefulSet) *v1beta1.S
|
|||
|
||||
statefulset := &v1beta1.StatefulSet{
|
||||
ObjectMeta: v1.ObjectMeta{
|
||||
Name: p.Name,
|
||||
Name: prefixedName(p.Name),
|
||||
Labels: p.ObjectMeta.Labels,
|
||||
Annotations: p.ObjectMeta.Annotations,
|
||||
},
|
||||
Spec: makeStatefulSetSpec(p),
|
||||
}
|
||||
if vc := p.Spec.Storage; vc == nil {
|
||||
statefulset.Spec.Template.Spec.Volumes = append(statefulset.Spec.Template.Spec.Volumes, v1.Volume{
|
||||
Name: fmt.Sprintf("%s-db", p.Name),
|
||||
Name: volumeName(p.Name),
|
||||
VolumeSource: v1.VolumeSource{
|
||||
EmptyDir: &v1.EmptyDirVolumeSource{},
|
||||
},
|
||||
|
@ -68,7 +78,7 @@ func makeStatefulSet(p v1alpha1.Prometheus, old *v1beta1.StatefulSet) *v1beta1.S
|
|||
} else {
|
||||
pvc := v1.PersistentVolumeClaim{
|
||||
ObjectMeta: v1.ObjectMeta{
|
||||
Name: fmt.Sprintf("%s-db", p.Name),
|
||||
Name: volumeName(p.Name),
|
||||
},
|
||||
Spec: v1.PersistentVolumeClaimSpec{
|
||||
AccessModes: []v1.PersistentVolumeAccessMode{v1.ReadWriteOnce},
|
||||
|
@ -93,7 +103,7 @@ func makeStatefulSet(p v1alpha1.Prometheus, old *v1beta1.StatefulSet) *v1beta1.S
|
|||
func makeEmptyConfig(name string) *v1.ConfigMap {
|
||||
return &v1.ConfigMap{
|
||||
ObjectMeta: v1.ObjectMeta{
|
||||
Name: fmt.Sprintf("%s", name),
|
||||
Name: configConfigMapName(name),
|
||||
},
|
||||
Data: map[string]string{
|
||||
"prometheus.yaml": "",
|
||||
|
@ -104,7 +114,7 @@ func makeEmptyConfig(name string) *v1.ConfigMap {
|
|||
func makeEmptyRules(name string) *v1.ConfigMap {
|
||||
return &v1.ConfigMap{
|
||||
ObjectMeta: v1.ObjectMeta{
|
||||
Name: fmt.Sprintf("%s-rules", name),
|
||||
Name: rulesConfigMapName(name),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -112,7 +122,7 @@ func makeEmptyRules(name string) *v1.ConfigMap {
|
|||
func makeStatefulSetService(p *v1alpha1.Prometheus) *v1.Service {
|
||||
svc := &v1.Service{
|
||||
ObjectMeta: v1.ObjectMeta{
|
||||
Name: "prometheus",
|
||||
Name: governingServiceName,
|
||||
},
|
||||
Spec: v1.ServiceSpec{
|
||||
ClusterIP: "None",
|
||||
|
@ -207,7 +217,7 @@ func makeStatefulSetSpec(p v1alpha1.Prometheus) v1beta1.StatefulSetSpec {
|
|||
MountPath: "/etc/prometheus/rules",
|
||||
},
|
||||
{
|
||||
Name: fmt.Sprintf("%s-db", p.Name),
|
||||
Name: volumeName(p.Name),
|
||||
MountPath: "/var/prometheus/data",
|
||||
SubPath: subPathForStorage(p.Spec.Storage),
|
||||
},
|
||||
|
@ -233,6 +243,7 @@ func makeStatefulSetSpec(p v1alpha1.Prometheus) v1beta1.StatefulSetSpec {
|
|||
Args: []string{
|
||||
fmt.Sprintf("-webhook-url=%s", localReloadURL),
|
||||
"-volume-dir=/etc/prometheus/config",
|
||||
"-volume-dir=/etc/prometheus/rules/",
|
||||
},
|
||||
VolumeMounts: []v1.VolumeMount{
|
||||
{
|
||||
|
@ -240,6 +251,11 @@ func makeStatefulSetSpec(p v1alpha1.Prometheus) v1beta1.StatefulSetSpec {
|
|||
ReadOnly: true,
|
||||
MountPath: "/etc/prometheus/config",
|
||||
},
|
||||
{
|
||||
Name: "rules",
|
||||
ReadOnly: true,
|
||||
MountPath: "/etc/prometheus/rules",
|
||||
},
|
||||
},
|
||||
Resources: v1.ResourceRequirements{
|
||||
Limits: v1.ResourceList{
|
||||
|
@ -247,20 +263,6 @@ func makeStatefulSetSpec(p v1alpha1.Prometheus) v1beta1.StatefulSetSpec {
|
|||
v1.ResourceMemory: resource.MustParse("10Mi"),
|
||||
},
|
||||
},
|
||||
}, {
|
||||
Name: "rules-reloader",
|
||||
Image: "jimmidyson/configmap-reload",
|
||||
Args: []string{
|
||||
fmt.Sprintf("-webhook-url=%s", localReloadURL),
|
||||
"-volume-dir=/etc/prometheus/rules/",
|
||||
},
|
||||
VolumeMounts: []v1.VolumeMount{
|
||||
{
|
||||
Name: "rules",
|
||||
ReadOnly: true,
|
||||
MountPath: "/etc/prometheus/rules",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
TerminationGracePeriodSeconds: &terminationGracePeriod,
|
||||
|
@ -270,7 +272,7 @@ func makeStatefulSetSpec(p v1alpha1.Prometheus) v1beta1.StatefulSetSpec {
|
|||
VolumeSource: v1.VolumeSource{
|
||||
ConfigMap: &v1.ConfigMapVolumeSource{
|
||||
LocalObjectReference: v1.LocalObjectReference{
|
||||
Name: p.Name,
|
||||
Name: configConfigMapName(p.Name),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -280,7 +282,7 @@ func makeStatefulSetSpec(p v1alpha1.Prometheus) v1beta1.StatefulSetSpec {
|
|||
VolumeSource: v1.VolumeSource{
|
||||
ConfigMap: &v1.ConfigMapVolumeSource{
|
||||
LocalObjectReference: v1.LocalObjectReference{
|
||||
Name: fmt.Sprintf("%s-rules", p.Name),
|
||||
Name: rulesConfigMapName(p.Name),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -291,6 +293,22 @@ func makeStatefulSetSpec(p v1alpha1.Prometheus) v1beta1.StatefulSetSpec {
|
|||
}
|
||||
}
|
||||
|
||||
func configConfigMapName(name string) string {
|
||||
return prefixedName(name)
|
||||
}
|
||||
|
||||
func rulesConfigMapName(name string) string {
|
||||
return fmt.Sprintf("%s-rules", prefixedName(name))
|
||||
}
|
||||
|
||||
func volumeName(name string) string {
|
||||
return fmt.Sprintf("%s-db", prefixedName(name))
|
||||
}
|
||||
|
||||
func prefixedName(name string) string {
|
||||
return fmt.Sprintf("prometheus-%s", name)
|
||||
}
|
||||
|
||||
func subPathForStorage(s *v1alpha1.StorageSpec) string {
|
||||
if s == nil {
|
||||
return ""
|
||||
|
|
30
pkg/prometheus/statefulset_test.go
Normal file
30
pkg/prometheus/statefulset_test.go
Normal file
|
@ -0,0 +1,30 @@
|
|||
package prometheus
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"k8s.io/client-go/pkg/api/v1"
|
||||
|
||||
"github.com/coreos/prometheus-operator/pkg/client/monitoring/v1alpha1"
|
||||
)
|
||||
|
||||
func TestStatefulSetLabelingAndAnnotations(t *testing.T) {
|
||||
labels := map[string]string{
|
||||
"testlabel": "testlabelvalue",
|
||||
}
|
||||
annotations := map[string]string{
|
||||
"testannotation": "testannotationvalue",
|
||||
}
|
||||
|
||||
sset := makeStatefulSet(v1alpha1.Prometheus{
|
||||
ObjectMeta: v1.ObjectMeta{
|
||||
Labels: labels,
|
||||
Annotations: annotations,
|
||||
},
|
||||
}, nil)
|
||||
|
||||
if !reflect.DeepEqual(labels, sset.Labels) || !reflect.DeepEqual(annotations, sset.Annotations) {
|
||||
t.Fatal("Labels or Annotations are not properly being propagated to the StatefulSet")
|
||||
}
|
||||
}
|
|
@ -19,7 +19,7 @@ import (
|
|||
)
|
||||
|
||||
func TestAlertmanagerCreateDeleteCluster(t *testing.T) {
|
||||
name := "alertmanager-test"
|
||||
name := "test"
|
||||
|
||||
defer func() {
|
||||
if err := framework.DeleteAlertmanagerAndWaitUntilGone(name); err != nil {
|
||||
|
@ -33,7 +33,7 @@ func TestAlertmanagerCreateDeleteCluster(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestAlertmanagerScaling(t *testing.T) {
|
||||
name := "alertmanager-test"
|
||||
name := "test"
|
||||
|
||||
defer func() {
|
||||
if err := framework.DeleteAlertmanagerAndWaitUntilGone(name); err != nil {
|
||||
|
@ -55,7 +55,7 @@ func TestAlertmanagerScaling(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestAlertmanagerVersionMigration(t *testing.T) {
|
||||
name := "alertmanager-test"
|
||||
name := "test"
|
||||
|
||||
defer func() {
|
||||
if err := framework.DeleteAlertmanagerAndWaitUntilGone(name); err != nil {
|
||||
|
|
|
@ -55,7 +55,7 @@ func (f *Framework) MakeBasicAlertmanager(name string, replicas int32) *v1alpha1
|
|||
func (f *Framework) MakeAlertmanagerService(name, group string) *v1.Service {
|
||||
return &v1.Service{
|
||||
ObjectMeta: v1.ObjectMeta{
|
||||
Name: name,
|
||||
Name: fmt.Sprintf("alertmanager-%s", name),
|
||||
Labels: map[string]string{
|
||||
"group": group,
|
||||
},
|
||||
|
@ -82,7 +82,7 @@ func (f *Framework) CreateAlertmanagerAndWaitUntilReady(a *v1alpha1.Alertmanager
|
|||
_, err := f.KubeClient.CoreV1().ConfigMaps(f.Namespace.Name).Create(
|
||||
&v1.ConfigMap{
|
||||
ObjectMeta: v1.ObjectMeta{
|
||||
Name: a.Name,
|
||||
Name: fmt.Sprintf("alertmanager-%s", a.Name),
|
||||
},
|
||||
Data: map[string]string{
|
||||
"alertmanager.yaml": ValidAlertmanagerConfig,
|
||||
|
@ -135,7 +135,7 @@ func (f *Framework) DeleteAlertmanagerAndWaitUntilGone(name string) error {
|
|||
return fmt.Errorf("failed to teardown Alertmanager (%s) instances: %v", name, err)
|
||||
}
|
||||
|
||||
return f.KubeClient.CoreV1().ConfigMaps(f.Namespace.Name).Delete(name, nil)
|
||||
return f.KubeClient.CoreV1().ConfigMaps(f.Namespace.Name).Delete(fmt.Sprintf("alertmanager-%s", name), nil)
|
||||
}
|
||||
|
||||
func amImage(version string) string {
|
||||
|
|
|
@ -147,6 +147,18 @@ func (f *Framework) setupPrometheusOperator(opImage string) error {
|
|||
|
||||
// Teardown tears down a previously initialized test environment.
|
||||
func (f *Framework) Teardown() error {
|
||||
if err := f.KubeClient.Core().Services(f.Namespace.Name).Delete("prometheus-operated", nil); err != nil && !k8sutil.IsResourceNotFoundError(err) {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := f.KubeClient.Core().Services(f.Namespace.Name).Delete("alertmanager-operated", nil); err != nil && !k8sutil.IsResourceNotFoundError(err) {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := f.KubeClient.Extensions().Deployments(f.Namespace.Name).Delete("prometheus-operator", nil); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := f.KubeClient.Core().Namespaces().Delete(f.Namespace.Name, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -220,3 +232,17 @@ func (f *Framework) createDeployment(deploy *v1beta1.Deployment) error {
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *Framework) GetLogs(podName, containerName string) (string, error) {
|
||||
logs, err := f.KubeClient.Core().RESTClient().Get().
|
||||
Resource("pods").
|
||||
Namespace(f.Namespace.Name).
|
||||
Name(podName).SubResource("log").
|
||||
Param("container", containerName).
|
||||
Do().
|
||||
Raw()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(logs), err
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@ func (f *Framework) AddAlertingToPrometheus(p *v1alpha1.Prometheus, name string)
|
|||
Alertmanagers: []v1alpha1.AlertmanagerEndpoints{
|
||||
v1alpha1.AlertmanagerEndpoints{
|
||||
Namespace: f.Namespace.Name,
|
||||
Name: name,
|
||||
Name: fmt.Sprintf("alertmanager-%s", name),
|
||||
Port: intstr.FromString("web"),
|
||||
},
|
||||
},
|
||||
|
@ -89,7 +89,7 @@ func (f *Framework) MakeBasicServiceMonitor(name string) *v1alpha1.ServiceMonito
|
|||
func (f *Framework) MakePrometheusService(name, group string) *v1.Service {
|
||||
return &v1.Service{
|
||||
ObjectMeta: v1.ObjectMeta{
|
||||
Name: name,
|
||||
Name: fmt.Sprintf("prometheus-%s", name),
|
||||
Labels: map[string]string{
|
||||
"group": group,
|
||||
},
|
||||
|
|
|
@ -21,9 +21,11 @@ import (
|
|||
"net/http"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"k8s.io/client-go/pkg/api/v1"
|
||||
metav1 "k8s.io/client-go/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/coreos/prometheus-operator/pkg/alertmanager"
|
||||
|
@ -31,21 +33,19 @@ import (
|
|||
)
|
||||
|
||||
func TestPrometheusCreateDeleteCluster(t *testing.T) {
|
||||
name := "prometheus-test"
|
||||
|
||||
defer func() {
|
||||
if err := framework.DeletePrometheusAndWaitUntilGone(name); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}()
|
||||
name := "test"
|
||||
|
||||
if err := framework.CreatePrometheusAndWaitUntilReady(framework.MakeBasicPrometheus(name, name, 1)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err := framework.DeletePrometheusAndWaitUntilGone(name); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPrometheusScaleUpDownCluster(t *testing.T) {
|
||||
name := "prometheus-test"
|
||||
name := "test"
|
||||
|
||||
defer func() {
|
||||
if err := framework.DeletePrometheusAndWaitUntilGone(name); err != nil {
|
||||
|
@ -67,7 +67,7 @@ func TestPrometheusScaleUpDownCluster(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestPrometheusVersionMigration(t *testing.T) {
|
||||
name := "prometheus-test"
|
||||
name := "test"
|
||||
|
||||
defer func() {
|
||||
if err := framework.DeletePrometheusAndWaitUntilGone(name); err != nil {
|
||||
|
@ -93,8 +93,100 @@ func TestPrometheusVersionMigration(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestPrometheusReloadConfig(t *testing.T) {
|
||||
name := "test"
|
||||
|
||||
defer func() {
|
||||
if err := framework.DeletePrometheusAndWaitUntilGone(name); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}()
|
||||
|
||||
cfg := &v1.ConfigMap{
|
||||
ObjectMeta: v1.ObjectMeta{
|
||||
Name: fmt.Sprintf("prometheus-%s", name),
|
||||
},
|
||||
Data: map[string]string{
|
||||
"prometheus.yaml": "",
|
||||
},
|
||||
}
|
||||
|
||||
if _, err := framework.KubeClient.CoreV1().ConfigMaps(framework.Namespace.Name).Create(cfg); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err := framework.CreatePrometheusAndWaitUntilReady(framework.MakeBasicPrometheus(name, name, 1)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
cfg.Data["prometheus.yaml"] = "global:\n scrape_interval: 1m"
|
||||
if _, err := framework.KubeClient.CoreV1().ConfigMaps(framework.Namespace.Name).Update(cfg); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// remounting a ConfigMap can take some time
|
||||
err := poll(time.Minute*5, time.Second*20, func() (bool, error) {
|
||||
logs, err := framework.GetLogs(fmt.Sprintf("prometheus-%s-0", name), "config-reloader")
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if strings.Contains(logs, "config map updated") && strings.Contains(logs, "successfully triggered reload") {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
return false, nil
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPrometheusReloadRules(t *testing.T) {
|
||||
name := "test"
|
||||
|
||||
defer func() {
|
||||
if err := framework.DeletePrometheusAndWaitUntilGone(name); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}()
|
||||
|
||||
if err := framework.CreatePrometheusAndWaitUntilReady(framework.MakeBasicPrometheus(name, name, 1)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
_, err := framework.KubeClient.CoreV1().ConfigMaps(framework.Namespace.Name).Update(&v1.ConfigMap{
|
||||
ObjectMeta: v1.ObjectMeta{
|
||||
Name: fmt.Sprintf("prometheus-%s-rules", name),
|
||||
},
|
||||
Data: map[string]string{
|
||||
"test.rules": "",
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// remounting a ConfigMap can take some time
|
||||
err = poll(time.Minute*5, time.Second*20, func() (bool, error) {
|
||||
logs, err := framework.GetLogs(fmt.Sprintf("prometheus-%s-0", name), "config-reloader")
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if strings.Contains(logs, "config map updated") && strings.Contains(logs, "successfully triggered reload") {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
return false, nil
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPrometheusDiscovery(t *testing.T) {
|
||||
prometheusName := "prometheus-test"
|
||||
prometheusName := "test"
|
||||
group := "servicediscovery-test"
|
||||
|
||||
defer func() {
|
||||
|
@ -104,7 +196,7 @@ func TestPrometheusDiscovery(t *testing.T) {
|
|||
if err := framework.MonClient.ServiceMonitors(framework.Namespace.Name).Delete(group, nil); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := framework.KubeClient.CoreV1().Services(framework.Namespace.Name).Delete(prometheusName, nil); err != nil {
|
||||
if err := framework.KubeClient.CoreV1().Services(framework.Namespace.Name).Delete(fmt.Sprintf("prometheus-%s", prometheusName), nil); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}()
|
||||
|
@ -128,7 +220,7 @@ func TestPrometheusDiscovery(t *testing.T) {
|
|||
}
|
||||
|
||||
log.Print("Validating Prometheus ConfigMap was created")
|
||||
_, err := framework.KubeClient.CoreV1().ConfigMaps(framework.Namespace.Name).Get(prometheusName, metav1.GetOptions{})
|
||||
_, err := framework.KubeClient.CoreV1().ConfigMaps(framework.Namespace.Name).Get(fmt.Sprintf("prometheus-%s", prometheusName), metav1.GetOptions{})
|
||||
if err != nil {
|
||||
t.Fatalf("Generated ConfigMap could not be retrieved: %s", err)
|
||||
}
|
||||
|
@ -141,15 +233,15 @@ func TestPrometheusDiscovery(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestPrometheusAlertmanagerDiscovery(t *testing.T) {
|
||||
prometheusName := "prometheus-test"
|
||||
alertmanagerName := "alertmanager-test"
|
||||
prometheusName := "test"
|
||||
alertmanagerName := "test"
|
||||
group := "servicediscovery-test"
|
||||
|
||||
defer func() {
|
||||
if err := framework.DeleteAlertmanagerAndWaitUntilGone(alertmanagerName); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := framework.KubeClient.CoreV1().Services(framework.Namespace.Name).Delete(alertmanagerName, nil); err != nil {
|
||||
if err := framework.KubeClient.CoreV1().Services(framework.Namespace.Name).Delete(fmt.Sprintf("alertmanager-%s", alertmanagerName), nil); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := framework.DeletePrometheusAndWaitUntilGone(prometheusName); err != nil {
|
||||
|
@ -158,7 +250,7 @@ func TestPrometheusAlertmanagerDiscovery(t *testing.T) {
|
|||
if err := framework.MonClient.ServiceMonitors(framework.Namespace.Name).Delete(group, nil); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := framework.KubeClient.CoreV1().Services(framework.Namespace.Name).Delete(prometheusName, nil); err != nil {
|
||||
if err := framework.KubeClient.CoreV1().Services(framework.Namespace.Name).Delete(fmt.Sprintf("prometheus-%s", prometheusName), nil); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}()
|
||||
|
@ -183,7 +275,7 @@ func TestPrometheusAlertmanagerDiscovery(t *testing.T) {
|
|||
}
|
||||
|
||||
log.Print("Validating Prometheus ConfigMap was created")
|
||||
_, err := framework.KubeClient.CoreV1().ConfigMaps(framework.Namespace.Name).Get(prometheusName, metav1.GetOptions{})
|
||||
_, err := framework.KubeClient.CoreV1().ConfigMaps(framework.Namespace.Name).Get(fmt.Sprintf("prometheus-%s", prometheusName), metav1.GetOptions{})
|
||||
if err != nil {
|
||||
t.Fatalf("Generated ConfigMap could not be retrieved: %s", err)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue