mirror of
https://github.com/prometheus-operator/prometheus-operator.git
synced 2025-04-21 11:48:53 +00:00
alertmanager: Allows specifying additional secrets
This commit is contained in:
parent
0971f911e2
commit
2d53e51de0
7 changed files with 118 additions and 25 deletions
Documentation
example/prometheus-operator-crd
pkg
alertmanager
client/monitoring/v1
|
@ -91,6 +91,7 @@ Specification of the desired behavior of the Alertmanager cluster. More info: ht
|
|||
| version | Version the cluster should be on. | string | false |
|
||||
| baseImage | Base image that is used to deploy pods, without tag. | string | false |
|
||||
| imagePullSecrets | An optional list of references to secrets in the same namespace to use for pulling prometheus and alertmanager images from registries see http://kubernetes.io/docs/user-guide/images#specifying-imagepullsecrets-on-a-pod | [][v1.LocalObjectReference](https://v1-6.docs.kubernetes.io/docs/api-reference/v1.6/#localobjectreference-v1-core) | false |
|
||||
| secrets | Secrets is a list of Secrets in the same namespace as the Alertmanager object, which shall be mounted into the Alertmanager Pods. The Secrets are mounted into /etc/alertmanager/secrets/<secret-name>. | []string | false |
|
||||
| replicas | Size is the expected size of the alertmanager cluster. The controller will eventually make the size of the running cluster equal to the expected size. | *int32 | false |
|
||||
| storage | Storage is the definition of how storage will be used by the Alertmanager instances. | *[StorageSpec](#storagespec) | false |
|
||||
| externalUrl | The external URL the Alertmanager instances will be available under. This is necessary to generate correct URLs. This is necessary if Alertmanager is not served from root of a DNS name. | string | false |
|
||||
|
|
|
@ -1590,6 +1590,13 @@ spec:
|
|||
the server serves requests under a different route prefix. For example
|
||||
for use with `kubectl proxy`.
|
||||
type: string
|
||||
secrets:
|
||||
description: Secrets is a list of Secrets in the same namespace as the
|
||||
Alertmanager object, which shall be mounted into the Alertmanager
|
||||
Pods. The Secrets are mounted into /etc/alertmanager/secrets/<secret-name>.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
securityContext:
|
||||
description: PodSecurityContext holds pod-level security attributes
|
||||
and common container settings. Some fields are also present in container.securityContext. Field
|
||||
|
|
|
@ -34,6 +34,7 @@ import (
|
|||
const (
|
||||
governingServiceName = "alertmanager-operated"
|
||||
defaultVersion = "v0.14.0"
|
||||
secretsDir = "/etc/alertmanager/secrets/"
|
||||
alertmanagerConfDir = "/etc/alertmanager/config"
|
||||
alertmanagerConfFile = alertmanagerConfDir + "/alertmanager.yaml"
|
||||
alertmanagerStorageDir = "/alertmanager"
|
||||
|
@ -306,6 +307,43 @@ func makeStatefulSetSpec(a *monitoringv1.Alertmanager, config Config) (*appsv1.S
|
|||
return nil, errors.Errorf("unsupported Alertmanager major version %s", version)
|
||||
}
|
||||
|
||||
volumes := []v1.Volume{
|
||||
{
|
||||
Name: "config-volume",
|
||||
VolumeSource: v1.VolumeSource{
|
||||
Secret: &v1.SecretVolumeSource{
|
||||
SecretName: configSecretName(a.Name),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
amVolumeMounts := []v1.VolumeMount{
|
||||
{
|
||||
Name: "config-volume",
|
||||
MountPath: alertmanagerConfDir,
|
||||
},
|
||||
{
|
||||
Name: volumeName(a.Name),
|
||||
MountPath: alertmanagerStorageDir,
|
||||
SubPath: subPathForStorage(a.Spec.Storage),
|
||||
},
|
||||
}
|
||||
for _, s := range a.Spec.Secrets {
|
||||
volumes = append(volumes, v1.Volume{
|
||||
Name: "secret-" + s,
|
||||
VolumeSource: v1.VolumeSource{
|
||||
Secret: &v1.SecretVolumeSource{
|
||||
SecretName: s,
|
||||
},
|
||||
},
|
||||
})
|
||||
amVolumeMounts = append(amVolumeMounts, v1.VolumeMount{
|
||||
Name: "secret-" + s,
|
||||
ReadOnly: true,
|
||||
MountPath: secretsDir + s,
|
||||
})
|
||||
}
|
||||
|
||||
terminationGracePeriod := int64(0)
|
||||
finalLabels := config.Labels.Merge(podLabels)
|
||||
return &appsv1.StatefulSetSpec{
|
||||
|
@ -327,21 +365,11 @@ func makeStatefulSetSpec(a *monitoringv1.Alertmanager, config Config) (*appsv1.S
|
|||
TerminationGracePeriodSeconds: &terminationGracePeriod,
|
||||
Containers: append([]v1.Container{
|
||||
{
|
||||
Args: amArgs,
|
||||
Name: "alertmanager",
|
||||
Image: image,
|
||||
Ports: ports,
|
||||
VolumeMounts: []v1.VolumeMount{
|
||||
{
|
||||
Name: "config-volume",
|
||||
MountPath: alertmanagerConfDir,
|
||||
},
|
||||
{
|
||||
Name: volumeName(a.Name),
|
||||
MountPath: alertmanagerStorageDir,
|
||||
SubPath: subPathForStorage(a.Spec.Storage),
|
||||
},
|
||||
},
|
||||
Args: amArgs,
|
||||
Name: "alertmanager",
|
||||
Image: image,
|
||||
Ports: ports,
|
||||
VolumeMounts: amVolumeMounts,
|
||||
LivenessProbe: livenessProbe,
|
||||
ReadinessProbe: readinessProbe,
|
||||
Resources: a.Spec.Resources,
|
||||
|
@ -367,16 +395,7 @@ func makeStatefulSetSpec(a *monitoringv1.Alertmanager, config Config) (*appsv1.S
|
|||
},
|
||||
},
|
||||
}, a.Spec.Containers...),
|
||||
Volumes: []v1.Volume{
|
||||
{
|
||||
Name: "config-volume",
|
||||
VolumeSource: v1.VolumeSource{
|
||||
Secret: &v1.SecretVolumeSource{
|
||||
SecretName: configSecretName(a.Name),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Volumes: volumes,
|
||||
ServiceAccountName: a.Spec.ServiceAccountName,
|
||||
SecurityContext: securityContext,
|
||||
Tolerations: a.Spec.Tolerations,
|
||||
|
|
|
@ -351,6 +351,49 @@ func TestMakeStatefulSetSpecPeerFlagPort(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestAdditionalSecretsMounted(t *testing.T) {
|
||||
secrets := []string{"secret1", "secret2"}
|
||||
sset, err := makeStatefulSet(&monitoringv1.Alertmanager{
|
||||
ObjectMeta: metav1.ObjectMeta{},
|
||||
Spec: monitoringv1.AlertmanagerSpec{
|
||||
Secrets: secrets,
|
||||
},
|
||||
}, nil, defaultTestConfig)
|
||||
require.NoError(t, err)
|
||||
|
||||
secret1Found := false
|
||||
secret2Found := false
|
||||
for _, v := range sset.Spec.Template.Spec.Volumes {
|
||||
if v.Secret != nil {
|
||||
if v.Secret.SecretName == "secret1" {
|
||||
secret1Found = true
|
||||
}
|
||||
if v.Secret.SecretName == "secret2" {
|
||||
secret2Found = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !(secret1Found && secret2Found) {
|
||||
t.Fatal("Additional secrets were not found.")
|
||||
}
|
||||
|
||||
secret1Found = false
|
||||
secret2Found = false
|
||||
for _, v := range sset.Spec.Template.Spec.Containers[0].VolumeMounts {
|
||||
if v.Name == "secret-secret1" && v.MountPath == "/etc/alertmanager/secrets/secret1" {
|
||||
secret1Found = true
|
||||
}
|
||||
if v.Name == "secret-secret2" && v.MountPath == "/etc/alertmanager/secrets/secret2" {
|
||||
secret2Found = true
|
||||
}
|
||||
}
|
||||
|
||||
if !(secret1Found && secret2Found) {
|
||||
t.Fatal("Additional secrets were not found.")
|
||||
}
|
||||
}
|
||||
|
||||
func sliceContains(slice []string, match string) bool {
|
||||
contains := false
|
||||
for _, s := range slice {
|
||||
|
|
|
@ -231,6 +231,20 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA
|
|||
},
|
||||
},
|
||||
},
|
||||
"secrets": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Secrets is a list of Secrets in the same namespace as the Alertmanager object, which shall be mounted into the Alertmanager Pods. The Secrets are mounted into /etc/alertmanager/secrets/<secret-name>.",
|
||||
Type: []string{"array"},
|
||||
Items: &spec.SchemaOrArray{
|
||||
Schema: &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"replicas": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Size is the expected size of the alertmanager cluster. The controller will eventually make the size of the running cluster equal to the expected size.",
|
||||
|
|
|
@ -402,6 +402,10 @@ type AlertmanagerSpec struct {
|
|||
// to use for pulling prometheus and alertmanager images from registries
|
||||
// see http://kubernetes.io/docs/user-guide/images#specifying-imagepullsecrets-on-a-pod
|
||||
ImagePullSecrets []v1.LocalObjectReference `json:"imagePullSecrets,omitempty"`
|
||||
// Secrets is a list of Secrets in the same namespace as the Alertmanager
|
||||
// object, which shall be mounted into the Alertmanager Pods.
|
||||
// The Secrets are mounted into /etc/alertmanager/secrets/<secret-name>.
|
||||
Secrets []string `json:"secrets,omitempty"`
|
||||
// Size is the expected size of the alertmanager cluster. The controller will
|
||||
// eventually make the size of the running cluster equal to the expected
|
||||
// size.
|
||||
|
|
|
@ -142,6 +142,11 @@ func (in *AlertmanagerSpec) DeepCopyInto(out *AlertmanagerSpec) {
|
|||
*out = make([]core_v1.LocalObjectReference, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Secrets != nil {
|
||||
in, out := &in.Secrets, &out.Secrets
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Replicas != nil {
|
||||
in, out := &in.Replicas, &out.Replicas
|
||||
if *in == nil {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue