1
0
Fork 0
mirror of https://github.com/prometheus-operator/prometheus-operator.git synced 2025-04-21 03:38:43 +00:00

Move duplicated asset code to the assets package ()

* assets: move duplicated asset code to assets pkg

The asset_store code was duplicated in the prometheus and alertmanager
package. Some recent changes added TLS validation to the Prometheus
asset store only. To avoid diverging anymore and allow the alertmanager
code to benefit from the recent additions a refactor was necessary.

Signed-off-by: Damien Grisonnet <dgrisonn@redhat.com>

* pkg/alertmanager: simplify newConfigGenerator

Signed-off-by: Damien Grisonnet <dgrisonn@redhat.com>
This commit is contained in:
Damien Grisonnet 2020-10-23 16:52:03 +02:00 committed by GitHub
parent e32c86ffa4
commit 005278276d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 324 additions and 1178 deletions

View file

@ -24,12 +24,12 @@ import (
"github.com/pkg/errors"
monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
monitoringv1alpha1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1alpha1"
"github.com/prometheus-operator/prometheus-operator/pkg/assets"
"github.com/prometheus/alertmanager/config"
commoncfg "github.com/prometheus/common/config"
"github.com/prometheus/common/model"
"gopkg.in/yaml.v2"
"k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/kubernetes"
)
// Customization of Config type from alertmanager repo:
@ -195,20 +195,14 @@ func (c alertmanagerConfig) String() string {
}
type configGenerator struct {
logger log.Logger
kclient kubernetes.Interface
store *assetStore
logger log.Logger
store *assets.Store
}
func newConfigGenerator(logger log.Logger, kclient kubernetes.Interface, store *assetStore) *configGenerator {
if store == nil {
store = newAssetStore(kclient.CoreV1(), kclient.CoreV1())
}
func newConfigGenerator(logger log.Logger, store *assets.Store) *configGenerator {
cg := &configGenerator{
logger: logger,
kclient: kclient,
store: store,
logger: logger,
store: store,
}
return cg
}
@ -372,7 +366,7 @@ func (cg *configGenerator) convertWebhookConfig(ctx context.Context, in monitori
}
if in.URLSecret != nil {
url, err := cg.store.getSecretKey(ctx, crKey.Namespace, *in.URLSecret)
url, err := cg.store.GetSecretKey(ctx, crKey.Namespace, *in.URLSecret)
if err != nil {
return nil, errors.Errorf("failed to get key %q from secret %q", in.URLSecret.Key, in.URLSecret.Name)
}
@ -404,7 +398,7 @@ func (cg *configGenerator) convertPagerdutyConfig(ctx context.Context, in monito
}
if in.RoutingKey != nil {
routingKey, err := cg.store.getSecretKey(ctx, crKey.Namespace, *in.RoutingKey)
routingKey, err := cg.store.GetSecretKey(ctx, crKey.Namespace, *in.RoutingKey)
if err != nil {
return nil, errors.Errorf("failed to get routing key %q from secret %q", in.RoutingKey.Key, in.RoutingKey.Name)
}
@ -412,7 +406,7 @@ func (cg *configGenerator) convertPagerdutyConfig(ctx context.Context, in monito
}
if in.ServiceKey != nil {
serviceKey, err := cg.store.getSecretKey(ctx, crKey.Namespace, *in.ServiceKey)
serviceKey, err := cg.store.GetSecretKey(ctx, crKey.Namespace, *in.ServiceKey)
if err != nil {
return nil, errors.Errorf("failed to get service key %q from secret %q", in.ServiceKey.Key, in.ServiceKey.Name)
}
@ -479,7 +473,7 @@ func (cg *configGenerator) convertOpsgenieConfig(ctx context.Context, in monitor
}
if in.APIKey != nil {
apiKey, err := cg.store.getSecretKey(ctx, crKey.Namespace, *in.APIKey)
apiKey, err := cg.store.GetSecretKey(ctx, crKey.Namespace, *in.APIKey)
if err != nil {
return nil, errors.Errorf("failed to get api key %q from secret %q", in.APIKey.Key, in.APIKey.Name)
}
@ -615,12 +609,12 @@ func (cg *configGenerator) convertHTTPConfig(ctx context.Context, in monitoringv
}
if in.BasicAuth != nil {
username, err := cg.store.getSecretKey(ctx, crKey.Namespace, in.BasicAuth.Username)
username, err := cg.store.GetSecretKey(ctx, crKey.Namespace, in.BasicAuth.Username)
if err != nil {
return nil, errors.Errorf("failed to get BasicAuth username key %q from secret %q", in.BasicAuth.Username.Key, in.BasicAuth.Username.Name)
}
password, err := cg.store.getSecretKey(ctx, crKey.Namespace, in.BasicAuth.Password)
password, err := cg.store.GetSecretKey(ctx, crKey.Namespace, in.BasicAuth.Password)
if err != nil {
return nil, errors.Errorf("failed to get BasicAuth password key %q from secret %q", in.BasicAuth.Password.Key, in.BasicAuth.Password.Name)
}
@ -635,7 +629,7 @@ func (cg *configGenerator) convertHTTPConfig(ctx context.Context, in monitoringv
}
if in.BearerTokenSecret != nil {
bearerToken, err := cg.store.getSecretKey(ctx, crKey.Namespace, *in.BearerTokenSecret)
bearerToken, err := cg.store.GetSecretKey(ctx, crKey.Namespace, *in.BearerTokenSecret)
if err != nil {
return nil, errors.Errorf("failed to get bearer token key %q from secret %q", in.BearerTokenSecret.Key, in.BearerTokenSecret.Name)
}
@ -652,13 +646,13 @@ func (cg *configGenerator) convertTLSConfig(ctx context.Context, in *monitoringv
}
if in.CA != (monitoringv1.SecretOrConfigMap{}) {
out.CAFile = path.Join(tlsAssetsDir, tlsAssetKeyFromSelector(crKey.Namespace, in.CA).String())
out.CAFile = path.Join(tlsAssetsDir, assets.TLSAssetKeyFromSelector(crKey.Namespace, in.CA).String())
}
if in.Cert != (monitoringv1.SecretOrConfigMap{}) {
out.CertFile = path.Join(tlsAssetsDir, tlsAssetKeyFromSelector(crKey.Namespace, in.Cert).String())
out.CertFile = path.Join(tlsAssetsDir, assets.TLSAssetKeyFromSelector(crKey.Namespace, in.Cert).String())
}
if in.KeySecret != nil {
out.KeyFile = path.Join(tlsAssetsDir, tlsAssetKeyFromSecretSelector(crKey.Namespace, in.KeySecret).String())
out.KeyFile = path.Join(tlsAssetsDir, assets.TLSAssetKeyFromSecretSelector(crKey.Namespace, in.KeySecret).String())
}
return out

View file

@ -22,6 +22,7 @@ import (
"github.com/kylelemons/godebug/pretty"
monitoringv1alpha1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1alpha1"
"github.com/prometheus-operator/prometheus-operator/pkg/assets"
"github.com/prometheus/alertmanager/config"
corev1 "k8s.io/api/core/v1"
@ -347,7 +348,8 @@ templates: []
}
for _, tc := range testCases {
cg := newConfigGenerator(nil, tc.kclient, nil)
store := assets.NewStore(tc.kclient.CoreV1(), tc.kclient.CoreV1())
cg := newConfigGenerator(nil, store)
cfgBytes, err := cg.generateConfig(context.TODO(), tc.baseConfig, tc.amConfigs)
if err != nil {
t.Fatal(err)

View file

@ -1,293 +0,0 @@
// Copyright 2020 The prometheus-operator Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// TODO: This is duplicated from pkg/prometheus
package alertmanager
import (
"context"
"fmt"
monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
monitoringv1alpha1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1alpha1"
"github.com/pkg/errors"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
"k8s.io/client-go/tools/cache"
)
// tlsAssetKey is a key for a TLS asset.
type tlsAssetKey struct {
from string
ns string
name string
key string
}
// tlsAssetKeyFromSecretSelector returns a tlsAssetKey struct from a secret key selector.
func tlsAssetKeyFromSecretSelector(ns string, sel *v1.SecretKeySelector) tlsAssetKey {
return tlsAssetKeyFromSelector(
ns,
monitoringv1.SecretOrConfigMap{
Secret: sel,
},
)
}
// tlsAssetKeyFromSelector returns a tlsAssetKey struct from a secret or configmap key selector.
func tlsAssetKeyFromSelector(ns string, sel monitoringv1.SecretOrConfigMap) tlsAssetKey {
if sel.Secret != nil {
return tlsAssetKey{
from: "secret",
ns: ns,
name: sel.Secret.Name,
key: sel.Secret.Key,
}
}
return tlsAssetKey{
from: "configmap",
ns: ns,
name: sel.ConfigMap.Name,
key: sel.ConfigMap.Key,
}
}
// String implements the fmt.Stringer interface.
func (k tlsAssetKey) String() string {
return fmt.Sprintf("%s_%s_%s_%s", k.from, k.ns, k.name, k.key)
}
// assetStore is a store that fetches and caches TLS materials, bearer tokens
// and auth credentials from configmaps and secrets.
// Data can be referenced directly from a Prometheus object or indirectly (for
// instance via ServiceMonitor). In practice a new store is created and used by
// each reconciliation loop.
//
// assetStore doesn't support concurrent access.
type assetStore struct {
cmClient corev1client.ConfigMapsGetter
sClient corev1client.SecretsGetter
objStore cache.Store
tlsAssets map[tlsAssetKey]TLSAsset
bearerTokenAssets map[string]BearerToken
basicAuthAssets map[string]BasicAuthCredentials
}
// newAssetStore returns an empty assetStore.
func newAssetStore(cmClient corev1client.ConfigMapsGetter, sClient corev1client.SecretsGetter) *assetStore {
return &assetStore{
cmClient: cmClient,
sClient: sClient,
tlsAssets: make(map[tlsAssetKey]TLSAsset),
bearerTokenAssets: make(map[string]BearerToken),
basicAuthAssets: make(map[string]BasicAuthCredentials),
objStore: cache.NewStore(assetKeyFunc),
}
}
func assetKeyFunc(obj interface{}) (string, error) {
switch v := obj.(type) {
case *v1.ConfigMap:
return fmt.Sprintf("0/%s/%s", v.GetNamespace(), v.GetName()), nil
case *v1.Secret:
return fmt.Sprintf("1/%s/%s", v.GetNamespace(), v.GetName()), nil
}
return "", errors.Errorf("unsupported type: %T", obj)
}
// configureHTTPConfigInStore configure the asset store for HTTPConfigs.
func (a *assetStore) configureHTTPConfigInStore(ctx context.Context, httpConfig *monitoringv1alpha1.HTTPConfig, namespace string, key string) error {
if httpConfig == nil {
return nil
}
var err error
if httpConfig.BearerTokenSecret != nil {
if err = a.addBearerToken(ctx, namespace, *httpConfig.BearerTokenSecret, key); err != nil {
return err
}
}
if err = a.addBasicAuth(ctx, namespace, httpConfig.BasicAuth, key); err != nil {
return err
}
if err = a.addTLSConfig(ctx, namespace, httpConfig.TLSConfig); err != nil {
return err
}
return nil
}
// addTLSConfig processes the given *SafeTLSConfig and adds the referenced CA, certifcate and key to the store.
func (a *assetStore) addTLSConfig(ctx context.Context, ns string, tlsConfig *monitoringv1.SafeTLSConfig) error {
if tlsConfig == nil {
return nil
}
if tlsConfig.CA != (monitoringv1.SecretOrConfigMap{}) {
var (
ca string
err error
)
switch {
case tlsConfig.CA.Secret != nil:
ca, err = a.getSecretKey(ctx, ns, *tlsConfig.CA.Secret)
case tlsConfig.CA.ConfigMap != nil:
ca, err = a.getConfigMapKey(ctx, ns, *tlsConfig.CA.ConfigMap)
}
if err != nil {
return errors.Wrap(err, "failed to get CA")
}
a.tlsAssets[tlsAssetKeyFromSelector(ns, tlsConfig.CA)] = TLSAsset(ca)
}
if tlsConfig.Cert != (monitoringv1.SecretOrConfigMap{}) {
var (
cert string
err error
)
switch {
case tlsConfig.Cert.Secret != nil:
cert, err = a.getSecretKey(ctx, ns, *tlsConfig.Cert.Secret)
case tlsConfig.Cert.ConfigMap != nil:
cert, err = a.getConfigMapKey(ctx, ns, *tlsConfig.Cert.ConfigMap)
}
if err != nil {
return errors.Wrap(err, "failed to get cert")
}
a.tlsAssets[tlsAssetKeyFromSelector(ns, tlsConfig.Cert)] = TLSAsset(cert)
}
if tlsConfig.KeySecret != nil {
key, err := a.getSecretKey(ctx, ns, *tlsConfig.KeySecret)
if err != nil {
return errors.Wrap(err, "failed to get key")
}
a.tlsAssets[tlsAssetKeyFromSelector(ns, monitoringv1.SecretOrConfigMap{Secret: tlsConfig.KeySecret})] = TLSAsset(key)
}
return nil
}
// addBasicAuth processes the given *BasicAuth and adds the referenced credentials to the store.
func (a *assetStore) addBasicAuth(ctx context.Context, ns string, ba *monitoringv1.BasicAuth, key string) error {
if ba == nil {
return nil
}
username, err := a.getSecretKey(ctx, ns, ba.Username)
if err != nil {
return errors.Wrap(err, "failed to get basic auth username")
}
password, err := a.getSecretKey(ctx, ns, ba.Password)
if err != nil {
return errors.Wrap(err, "failed to get basic auth password")
}
a.basicAuthAssets[key] = BasicAuthCredentials{
username: username,
password: password,
}
return nil
}
// addBearerToken processes the given SecretKeySelector and adds the referenced data to the store.
func (a *assetStore) addBearerToken(ctx context.Context, ns string, sel v1.SecretKeySelector, key string) error {
if sel.Name == "" {
return nil
}
bearerToken, err := a.getSecretKey(ctx, ns, sel)
if err != nil {
return errors.Wrap(err, "failed to get bearer token")
}
a.bearerTokenAssets[key] = BearerToken(bearerToken)
return nil
}
func (a *assetStore) getConfigMapKey(ctx context.Context, namespace string, sel v1.ConfigMapKeySelector) (string, error) {
obj, exists, err := a.objStore.Get(&v1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: sel.Name,
Namespace: namespace,
},
})
if err != nil {
return "", errors.Wrapf(err, "unexpected store error when getting configmap %q", sel.Name)
}
if !exists {
cm, err := a.cmClient.ConfigMaps(namespace).Get(ctx, sel.Name, metav1.GetOptions{})
if err != nil {
return "", errors.Wrapf(err, "unable to get configmap %q", sel.Name)
}
if err = a.objStore.Add(cm); err != nil {
return "", errors.Wrapf(err, "unexpected store error when adding configmap %q", sel.Name)
}
obj = cm
}
cm := obj.(*v1.ConfigMap)
if _, found := cm.Data[sel.Key]; !found {
return "", errors.Errorf("key %q in configmap %q not found", sel.Key, sel.Name)
}
return cm.Data[sel.Key], nil
}
func (a *assetStore) getSecretKey(ctx context.Context, namespace string, sel v1.SecretKeySelector) (string, error) {
obj, exists, err := a.objStore.Get(&v1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: sel.Name,
Namespace: namespace,
},
})
if err != nil {
return "", errors.Wrapf(err, "unexpected store error when getting secret %q", sel.Name)
}
if !exists {
secret, err := a.sClient.Secrets(namespace).Get(ctx, sel.Name, metav1.GetOptions{})
if err != nil {
return "", errors.Wrapf(err, "unable to get secret %q", sel.Name)
}
if err = a.objStore.Add(secret); err != nil {
return "", errors.Wrapf(err, "unexpected store error when adding secret %q", sel.Name)
}
obj = secret
}
secret := obj.(*v1.Secret)
if _, found := secret.Data[sel.Key]; !found {
return "", errors.Errorf("key %q in secret %q not found", sel.Key, sel.Name)
}
return string(secret.Data[sel.Key]), nil
}

View file

@ -1,612 +0,0 @@
// Copyright 2020 The prometheus-operator Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package alertmanager
import (
"context"
"fmt"
"testing"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes/fake"
monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
)
func TestAddBearerToken(t *testing.T) {
c := fake.NewSimpleClientset(
&v1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: "secret",
Namespace: "ns1",
},
Data: map[string][]byte{
"key1": []byte("val1"),
},
},
)
for i, tc := range []struct {
ns string
selectedName string
selectedKey string
err bool
expected string
}{
{
ns: "ns1",
selectedName: "secret",
selectedKey: "key1",
expected: "val1",
},
// Wrong namespace.
{
ns: "ns2",
selectedName: "secret",
selectedKey: "key1",
err: true,
},
// Wrong name.
{
ns: "ns1",
selectedName: "secreet",
selectedKey: "key1",
err: true,
},
// Wrong key.
{
ns: "ns1",
selectedName: "secret",
selectedKey: "key2",
err: true,
},
} {
t.Run("", func(t *testing.T) {
store := newAssetStore(c.CoreV1(), c.CoreV1())
sel := v1.SecretKeySelector{
LocalObjectReference: v1.LocalObjectReference{
Name: tc.selectedName,
},
Key: tc.selectedKey,
}
key := fmt.Sprintf("basicauth/%d", i)
err := store.addBearerToken(context.Background(), tc.ns, sel, key)
if tc.err {
if err == nil {
t.Fatal("expecting error, got no error")
}
return
}
if err != nil {
t.Fatalf("expecting no error, got %q", err)
}
s, found := store.bearerTokenAssets[key]
if !found {
t.Fatalf("expecting to find key %q but got nothing", key)
}
if string(s) != tc.expected {
t.Fatalf("expecting %q, got %q", tc.expected, s)
}
})
}
}
func TestAddBasicAuth(t *testing.T) {
c := fake.NewSimpleClientset(
&v1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: "secret",
Namespace: "ns1",
},
Data: map[string][]byte{
"key1": []byte("val1"),
"key2": []byte("val2"),
},
},
)
for i, tc := range []struct {
ns string
selectedUserName string
selectedUserKey string
selectedPasswordName string
selectedPasswordKey string
err bool
expectedUser string
expectedPassword string
}{
{
ns: "ns1",
selectedUserName: "secret",
selectedUserKey: "key1",
selectedPasswordName: "secret",
selectedPasswordKey: "key2",
expectedUser: "val1",
expectedPassword: "val2",
},
// Wrong namespace.
{
ns: "ns2",
selectedUserName: "secret",
selectedUserKey: "key1",
selectedPasswordName: "secret",
selectedPasswordKey: "key2",
err: true,
},
// Wrong name for username selector.
{
ns: "ns1",
selectedUserName: "secreet",
selectedUserKey: "key1",
selectedPasswordName: "secret",
selectedPasswordKey: "key2",
err: true,
},
// Wrong key for username selector.
{
ns: "ns1",
selectedUserName: "secret",
selectedUserKey: "key3",
selectedPasswordName: "secret",
selectedPasswordKey: "key2",
err: true,
},
// Wrong name for password selector.
{
ns: "ns1",
selectedUserName: "secret",
selectedUserKey: "key1",
selectedPasswordName: "secreet",
selectedPasswordKey: "key2",
err: true,
},
// Wrong key for password selector.
{
ns: "ns1",
selectedUserName: "secret",
selectedUserKey: "key1",
selectedPasswordName: "secret",
selectedPasswordKey: "key3",
err: true,
},
} {
t.Run("", func(t *testing.T) {
store := newAssetStore(c.CoreV1(), c.CoreV1())
basicAuth := &monitoringv1.BasicAuth{
Username: v1.SecretKeySelector{
LocalObjectReference: v1.LocalObjectReference{
Name: tc.selectedUserName,
},
Key: tc.selectedUserKey,
},
Password: v1.SecretKeySelector{
LocalObjectReference: v1.LocalObjectReference{
Name: tc.selectedPasswordName,
},
Key: tc.selectedPasswordKey,
},
}
key := fmt.Sprintf("basicauth/%d", i)
err := store.addBasicAuth(context.Background(), tc.ns, basicAuth, key)
if tc.err {
if err == nil {
t.Fatal("expecting error, got no error")
}
return
}
if err != nil {
t.Fatalf("expecting no error, got %q", err)
}
s, found := store.basicAuthAssets[key]
if !found {
t.Fatalf("expecting to find key %q but got nothing", key)
}
if s.username != tc.expectedUser {
t.Fatalf("expecting username %q, got %q", tc.expectedUser, s)
}
if s.password != tc.expectedPassword {
t.Fatalf("expecting password %q, got %q", tc.expectedPassword, s)
}
})
}
}
func TestAddTLSConfig(t *testing.T) {
c := fake.NewSimpleClientset(
&v1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: "cm",
Namespace: "ns1",
},
Data: map[string]string{
"key1": "val1",
"key2": "val2",
"key3": "val3",
},
},
&v1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: "secret",
Namespace: "ns1",
},
Data: map[string][]byte{
"key4": []byte("val4"),
"key5": []byte("val5"),
"key6": []byte("val6"),
},
},
)
for _, tc := range []struct {
ns string
tlsConfig *monitoringv1.SafeTLSConfig
err bool
expectedCA string
expectedCert string
expectedKey string
}{
{
// CA, cert and key in secret.
ns: "ns1",
tlsConfig: &monitoringv1.SafeTLSConfig{
CA: monitoringv1.SecretOrConfigMap{
Secret: &v1.SecretKeySelector{
LocalObjectReference: v1.LocalObjectReference{
Name: "secret",
},
Key: "key4",
},
},
Cert: monitoringv1.SecretOrConfigMap{
Secret: &v1.SecretKeySelector{
LocalObjectReference: v1.LocalObjectReference{
Name: "secret",
},
Key: "key5",
},
},
KeySecret: &v1.SecretKeySelector{
LocalObjectReference: v1.LocalObjectReference{
Name: "secret",
},
Key: "key6",
},
},
expectedCA: "val4",
expectedCert: "val5",
expectedKey: "val6",
},
{
// CA in configmap, cert and key in secret.
ns: "ns1",
tlsConfig: &monitoringv1.SafeTLSConfig{
CA: monitoringv1.SecretOrConfigMap{
ConfigMap: &v1.ConfigMapKeySelector{
LocalObjectReference: v1.LocalObjectReference{
Name: "cm",
},
Key: "key1",
},
},
Cert: monitoringv1.SecretOrConfigMap{
Secret: &v1.SecretKeySelector{
LocalObjectReference: v1.LocalObjectReference{
Name: "secret",
},
Key: "key5",
},
},
KeySecret: &v1.SecretKeySelector{
LocalObjectReference: v1.LocalObjectReference{
Name: "secret",
},
Key: "key6",
},
},
expectedCA: "val1",
expectedCert: "val5",
expectedKey: "val6",
},
{
// CA and cert in configmap, key in secret.
ns: "ns1",
tlsConfig: &monitoringv1.SafeTLSConfig{
CA: monitoringv1.SecretOrConfigMap{
ConfigMap: &v1.ConfigMapKeySelector{
LocalObjectReference: v1.LocalObjectReference{
Name: "cm",
},
Key: "key1",
},
},
Cert: monitoringv1.SecretOrConfigMap{
ConfigMap: &v1.ConfigMapKeySelector{
LocalObjectReference: v1.LocalObjectReference{
Name: "cm",
},
Key: "key2",
},
},
KeySecret: &v1.SecretKeySelector{
LocalObjectReference: v1.LocalObjectReference{
Name: "secret",
},
Key: "key6",
},
},
expectedCA: "val1",
expectedCert: "val2",
expectedKey: "val6",
},
{
// Wrong namespace.
ns: "ns2",
tlsConfig: &monitoringv1.SafeTLSConfig{
CA: monitoringv1.SecretOrConfigMap{
ConfigMap: &v1.ConfigMapKeySelector{
LocalObjectReference: v1.LocalObjectReference{
Name: "cm",
},
Key: "key1",
},
},
Cert: monitoringv1.SecretOrConfigMap{
ConfigMap: &v1.ConfigMapKeySelector{
LocalObjectReference: v1.LocalObjectReference{
Name: "cm",
},
Key: "key2",
},
},
KeySecret: &v1.SecretKeySelector{
LocalObjectReference: v1.LocalObjectReference{
Name: "secret",
},
Key: "key6",
},
},
err: true,
},
{
// Wrong configmap selector for CA.
ns: "ns1",
tlsConfig: &monitoringv1.SafeTLSConfig{
CA: monitoringv1.SecretOrConfigMap{
ConfigMap: &v1.ConfigMapKeySelector{
LocalObjectReference: v1.LocalObjectReference{
Name: "cm",
},
Key: "key4",
},
},
Cert: monitoringv1.SecretOrConfigMap{
ConfigMap: &v1.ConfigMapKeySelector{
LocalObjectReference: v1.LocalObjectReference{
Name: "cm",
},
Key: "key2",
},
},
KeySecret: &v1.SecretKeySelector{
LocalObjectReference: v1.LocalObjectReference{
Name: "secret",
},
Key: "key6",
},
},
err: true,
},
{
// Wrong secret selector for CA.
ns: "ns1",
tlsConfig: &monitoringv1.SafeTLSConfig{
CA: monitoringv1.SecretOrConfigMap{
Secret: &v1.SecretKeySelector{
LocalObjectReference: v1.LocalObjectReference{
Name: "secret",
},
Key: "key1",
},
},
Cert: monitoringv1.SecretOrConfigMap{
ConfigMap: &v1.ConfigMapKeySelector{
LocalObjectReference: v1.LocalObjectReference{
Name: "cm",
},
Key: "key2",
},
},
KeySecret: &v1.SecretKeySelector{
LocalObjectReference: v1.LocalObjectReference{
Name: "secret",
},
Key: "key6",
},
},
err: true,
},
{
// Wrong configmap selector for cert.
ns: "ns1",
tlsConfig: &monitoringv1.SafeTLSConfig{
CA: monitoringv1.SecretOrConfigMap{
ConfigMap: &v1.ConfigMapKeySelector{
LocalObjectReference: v1.LocalObjectReference{
Name: "cm",
},
Key: "key1",
},
},
Cert: monitoringv1.SecretOrConfigMap{
ConfigMap: &v1.ConfigMapKeySelector{
LocalObjectReference: v1.LocalObjectReference{
Name: "cm",
},
Key: "key4",
},
},
KeySecret: &v1.SecretKeySelector{
LocalObjectReference: v1.LocalObjectReference{
Name: "secret",
},
Key: "key6",
},
},
err: true,
},
{
// Wrong secret selector for cert.
ns: "ns1",
tlsConfig: &monitoringv1.SafeTLSConfig{
CA: monitoringv1.SecretOrConfigMap{
ConfigMap: &v1.ConfigMapKeySelector{
LocalObjectReference: v1.LocalObjectReference{
Name: "cm",
},
Key: "key1",
},
},
Cert: monitoringv1.SecretOrConfigMap{
Secret: &v1.SecretKeySelector{
LocalObjectReference: v1.LocalObjectReference{
Name: "secret",
},
Key: "key2",
},
},
KeySecret: &v1.SecretKeySelector{
LocalObjectReference: v1.LocalObjectReference{
Name: "secret",
},
Key: "key6",
},
},
err: true,
},
{
// Wrong key selector.
ns: "ns1",
tlsConfig: &monitoringv1.SafeTLSConfig{
CA: monitoringv1.SecretOrConfigMap{
Secret: &v1.SecretKeySelector{
LocalObjectReference: v1.LocalObjectReference{
Name: "secret",
},
Key: "key4",
},
},
Cert: monitoringv1.SecretOrConfigMap{
Secret: &v1.SecretKeySelector{
LocalObjectReference: v1.LocalObjectReference{
Name: "secret",
},
Key: "key5",
},
},
KeySecret: &v1.SecretKeySelector{
LocalObjectReference: v1.LocalObjectReference{
Name: "secret",
},
Key: "key7",
},
},
err: true,
},
} {
t.Run("", func(t *testing.T) {
store := newAssetStore(c.CoreV1(), c.CoreV1())
err := store.addTLSConfig(context.Background(), tc.ns, tc.tlsConfig)
if tc.err {
if err == nil {
t.Fatal("expecting error, got no error")
}
return
}
if err != nil {
t.Fatalf("expecting no error, got %q", err)
}
key := tlsAssetKeyFromSelector(tc.ns, tc.tlsConfig.CA)
ca, found := store.tlsAssets[key]
if !found {
t.Fatalf("expecting to find key %q but got nothing", key)
}
if string(ca) != tc.expectedCA {
t.Fatalf("expecting CA %q, got %q", tc.expectedCA, ca)
}
key = tlsAssetKeyFromSelector(tc.ns, tc.tlsConfig.Cert)
cert, found := store.tlsAssets[key]
if !found {
t.Fatalf("expecting to find key %q but got nothing", key)
}
if string(cert) != tc.expectedCert {
t.Fatalf("expecting cert %q, got %q", tc.expectedCert, ca)
}
key = tlsAssetKeyFromSecretSelector(tc.ns, tc.tlsConfig.KeySecret)
k, found := store.tlsAssets[key]
if !found {
t.Fatalf("expecting to find key %q but got nothing", key)
}
if string(k) != tc.expectedKey {
t.Fatalf("expecting cert key %q, got %q", tc.expectedCert, ca)
}
})
}
}

View file

@ -23,6 +23,7 @@ import (
monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
monitoringv1alpha1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1alpha1"
"github.com/prometheus-operator/prometheus-operator/pkg/assets"
monitoringclient "github.com/prometheus-operator/prometheus-operator/pkg/client/versioned"
"github.com/prometheus-operator/prometheus-operator/pkg/informers"
"github.com/prometheus-operator/prometheus-operator/pkg/k8sutil"
@ -91,21 +92,6 @@ type Config struct {
AlertManagerSelector string
}
// BasicAuthCredentials represents a username password pair to be used with
// basic http authentication, see https://tools.ietf.org/html/rfc7617.
type BasicAuthCredentials struct {
username string
password string
}
// BearerToken represents a bearer token, see
// https://tools.ietf.org/html/rfc6750.
type BearerToken string
// TLSAsset represents any tls related opaque string, e.g. ca files, client
// certificates.
type TLSAsset string
// New creates a new controller.
func New(ctx context.Context, c operator.Config, logger log.Logger, r prometheus.Registerer) (*Operator, error) {
cfg, err := k8sutil.NewClusterConfig(c.Host, c.TLSInsecure, &c.TLSConfig)
@ -653,7 +639,7 @@ func (c *Operator) sync(ctx context.Context, key string) error {
level.Info(c.logger).Log("msg", "sync alertmanager", "key", key)
assetStore := newAssetStore(c.kclient.CoreV1(), c.kclient.CoreV1())
assetStore := assets.NewStore(c.kclient.CoreV1(), c.kclient.CoreV1())
if err := c.provisionAlertmanagerConfiguration(context.TODO(), am, assetStore); err != nil {
return errors.Wrap(err, "provision alertmanager configuration")
@ -715,7 +701,7 @@ func (c *Operator) sync(ctx context.Context, key string) error {
return nil
}
func (c *Operator) provisionAlertmanagerConfiguration(ctx context.Context, am *monitoringv1.Alertmanager, store *assetStore) error {
func (c *Operator) provisionAlertmanagerConfiguration(ctx context.Context, am *monitoringv1.Alertmanager, store *assets.Store) error {
secretName := defaultConfigSecretName(am.Name)
if am.Spec.ConfigSecret != "" {
@ -762,7 +748,7 @@ receivers:
return errors.Wrap(err, "selecting AlertmanagerConfigs failed")
}
conf, err := newConfigGenerator(c.logger, c.kclient, store).generateConfig(ctx, *baseConfig, amConfigs)
conf, err := newConfigGenerator(c.logger, store).generateConfig(ctx, *baseConfig, amConfigs)
if err != nil {
return errors.Wrap(err, "generating Alertmanager config yaml failed")
}
@ -822,7 +808,7 @@ func (c *Operator) createOrUpdateGeneratedConfigSecret(ctx context.Context, am *
return nil
}
func (c *Operator) selectAlertManagerConfigs(ctx context.Context, am *monitoringv1.Alertmanager, store *assetStore) (map[string]*monitoringv1alpha1.AlertmanagerConfig, error) {
func (c *Operator) selectAlertManagerConfigs(ctx context.Context, am *monitoringv1.Alertmanager, store *assets.Store) (map[string]*monitoringv1alpha1.AlertmanagerConfig, error) {
namespaces := []string{}
// Selectors (<namespace>/<name>) might overlap. Deduplicate them along the keyFunc.
amConfigs := make(map[string]*monitoringv1alpha1.AlertmanagerConfig)
@ -892,7 +878,7 @@ func (c *Operator) selectAlertManagerConfigs(ctx context.Context, am *monitoring
// checkAlertmanagerConfig verifies that an AlertmanagerConfig object is valid
// and has no missing references to other objects.
func checkAlertmanagerConfig(ctx context.Context, amc *monitoringv1alpha1.AlertmanagerConfig, store *assetStore) error {
func checkAlertmanagerConfig(ctx context.Context, amc *monitoringv1alpha1.AlertmanagerConfig, store *assets.Store) error {
receiverNames := make(map[string]struct{})
for i, receiver := range amc.Spec.Receivers {
@ -907,18 +893,18 @@ func checkAlertmanagerConfig(ctx context.Context, amc *monitoringv1alpha1.Alertm
pdcKey := fmt.Sprintf("%s/pagerduty/%d", amcKey, j)
if pdConfig.RoutingKey != nil {
if _, err := store.getSecretKey(ctx, amc.GetNamespace(), *pdConfig.RoutingKey); err != nil {
if _, err := store.GetSecretKey(ctx, amc.GetNamespace(), *pdConfig.RoutingKey); err != nil {
return err
}
}
if pdConfig.ServiceKey != nil {
if _, err := store.getSecretKey(ctx, amc.GetNamespace(), *pdConfig.ServiceKey); err != nil {
if _, err := store.GetSecretKey(ctx, amc.GetNamespace(), *pdConfig.ServiceKey); err != nil {
return err
}
}
if err := store.configureHTTPConfigInStore(ctx, pdConfig.HTTPConfig, amc.GetNamespace(), pdcKey); err != nil {
if err := configureHTTPConfigInStore(ctx, pdConfig.HTTPConfig, amc.GetNamespace(), pdcKey, store); err != nil {
return err
}
}
@ -927,7 +913,7 @@ func checkAlertmanagerConfig(ctx context.Context, amc *monitoringv1alpha1.Alertm
ogcKey := fmt.Sprintf("%s/opsgenie/%d", amcKey, j)
if ogConfig.APIKey != nil {
if _, err := store.getSecretKey(ctx, amc.GetNamespace(), *ogConfig.APIKey); err != nil {
if _, err := store.GetSecretKey(ctx, amc.GetNamespace(), *ogConfig.APIKey); err != nil {
return err
}
}
@ -936,7 +922,7 @@ func checkAlertmanagerConfig(ctx context.Context, amc *monitoringv1alpha1.Alertm
return err
}
if err := store.configureHTTPConfigInStore(ctx, ogConfig.HTTPConfig, amc.GetNamespace(), ogcKey); err != nil {
if err := configureHTTPConfigInStore(ctx, ogConfig.HTTPConfig, amc.GetNamespace(), ogcKey, store); err != nil {
return err
}
}
@ -949,12 +935,12 @@ func checkAlertmanagerConfig(ctx context.Context, amc *monitoringv1alpha1.Alertm
}
if whConfig.URLSecret != nil {
if _, err := store.getSecretKey(ctx, amc.GetNamespace(), *whConfig.URLSecret); err != nil {
if _, err := store.GetSecretKey(ctx, amc.GetNamespace(), *whConfig.URLSecret); err != nil {
return err
}
}
if err := store.configureHTTPConfigInStore(ctx, whConfig.HTTPConfig, amc.GetNamespace(), whcKey); err != nil {
if err := configureHTTPConfigInStore(ctx, whConfig.HTTPConfig, amc.GetNamespace(), whcKey, store); err != nil {
return err
}
}
@ -981,6 +967,29 @@ func checkAlertmanagerRoutes(route *monitoringv1alpha1.Route, receivers map[stri
return nil
}
// configureHTTPConfigInStore configure the asset store for HTTPConfigs.
func configureHTTPConfigInStore(ctx context.Context, httpConfig *monitoringv1alpha1.HTTPConfig, namespace string, key string, store *assets.Store) error {
if httpConfig == nil {
return nil
}
var err error
if httpConfig.BearerTokenSecret != nil {
if err = store.AddBearerToken(ctx, namespace, *httpConfig.BearerTokenSecret, key); err != nil {
return err
}
}
if err = store.AddBasicAuth(ctx, namespace, httpConfig.BasicAuth, key); err != nil {
return err
}
if err = store.AddSafeTLSConfig(ctx, namespace, httpConfig.TLSConfig); err != nil {
return err
}
return nil
}
// listMatchingNamespaces lists all the namespaces that match the provided
// selector.
func (c *Operator) listMatchingNamespaces(selector labels.Selector) ([]string, error) {
@ -994,7 +1003,7 @@ func (c *Operator) listMatchingNamespaces(selector labels.Selector) ([]string, e
return ns, nil
}
func (c *Operator) createOrUpdateTLSAssetSecret(am *monitoringv1.Alertmanager, store *assetStore) error {
func (c *Operator) createOrUpdateTLSAssetSecret(am *monitoringv1.Alertmanager, store *assets.Store) error {
boolTrue := true
sClient := c.kclient.CoreV1().Secrets(am.Namespace)
@ -1013,10 +1022,10 @@ func (c *Operator) createOrUpdateTLSAssetSecret(am *monitoringv1.Alertmanager, s
},
},
},
Data: make(map[string][]byte, len(store.tlsAssets)),
Data: make(map[string][]byte, len(store.TLSAssets)),
}
for key, asset := range store.tlsAssets {
for key, asset := range store.TLSAssets {
tlsAssetsSecret.Data[key.String()] = []byte(asset)
}

View file

@ -23,6 +23,7 @@ import (
"k8s.io/client-go/kubernetes/fake"
monitoringv1alpha1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1alpha1"
"github.com/prometheus-operator/prometheus-operator/pkg/assets"
)
func TestCheckAlertmanagerConfig(t *testing.T) {
@ -294,7 +295,7 @@ func TestCheckAlertmanagerConfig(t *testing.T) {
},
} {
t.Run(tc.amConfig.Name, func(t *testing.T) {
store := newAssetStore(c.CoreV1(), c.CoreV1())
store := assets.NewStore(c.CoreV1(), c.CoreV1())
err := checkAlertmanagerConfig(context.Background(), tc.amConfig, store)
if tc.ok {
if err != nil {

View file

@ -12,9 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
// TODO: This is duplicated in pkg/alertmanager.
package prometheus
package assets
import (
"context"
@ -32,72 +30,31 @@ import (
"k8s.io/client-go/tools/cache"
)
// tlsAssetKey is a key for a TLS asset.
type tlsAssetKey struct {
from string
ns string
name string
key string
}
// tlsAssetKeyFromSecretSelector returns a tlsAssetKey struct from a secret key selector.
func tlsAssetKeyFromSecretSelector(ns string, sel *v1.SecretKeySelector) tlsAssetKey {
return tlsAssetKeyFromSelector(
ns,
monitoringv1.SecretOrConfigMap{
Secret: sel,
},
)
}
// tlsAssetKeyFromSelector returns a tlsAssetKey struct from a secret or configmap key selector.
func tlsAssetKeyFromSelector(ns string, sel monitoringv1.SecretOrConfigMap) tlsAssetKey {
if sel.Secret != nil {
return tlsAssetKey{
from: "secret",
ns: ns,
name: sel.Secret.Name,
key: sel.Secret.Key,
}
}
return tlsAssetKey{
from: "configmap",
ns: ns,
name: sel.ConfigMap.Name,
key: sel.ConfigMap.Key,
}
}
// String implements the fmt.Stringer interface.
func (k tlsAssetKey) String() string {
return fmt.Sprintf("%s_%s_%s_%s", k.from, k.ns, k.name, k.key)
}
// assetStore is a store that fetches and caches TLS materials, bearer tokens
// Store is a store that fetches and caches TLS materials, bearer tokens
// and auth credentials from configmaps and secrets.
// Data can be referenced directly from a Prometheus object or indirectly (for
// instance via ServiceMonitor). In practice a new store is created and used by
// each reconciliation loop.
//
// assetStore doesn't support concurrent access.
type assetStore struct {
// Store doesn't support concurrent access.
type Store struct {
cmClient corev1client.ConfigMapsGetter
sClient corev1client.SecretsGetter
objStore cache.Store
tlsAssets map[tlsAssetKey]TLSAsset
bearerTokenAssets map[string]BearerToken
basicAuthAssets map[string]BasicAuthCredentials
TLSAssets map[TLSAssetKey]TLSAsset
BearerTokenAssets map[string]BearerToken
BasicAuthAssets map[string]BasicAuthCredentials
}
// newAssetStore returns an empty assetStore.
func newAssetStore(cmClient corev1client.ConfigMapsGetter, sClient corev1client.SecretsGetter) *assetStore {
return &assetStore{
// NewStore returns an empty assetStore.
func NewStore(cmClient corev1client.ConfigMapsGetter, sClient corev1client.SecretsGetter) *Store {
return &Store{
cmClient: cmClient,
sClient: sClient,
tlsAssets: make(map[tlsAssetKey]TLSAsset),
bearerTokenAssets: make(map[string]BearerToken),
basicAuthAssets: make(map[string]BasicAuthCredentials),
TLSAssets: make(map[TLSAssetKey]TLSAsset),
BearerTokenAssets: make(map[string]BearerToken),
BasicAuthAssets: make(map[string]BasicAuthCredentials),
objStore: cache.NewStore(assetKeyFunc),
}
}
@ -113,7 +70,7 @@ func assetKeyFunc(obj interface{}) (string, error) {
}
// addTLSAssets processes the given SafeTLSConfig and adds the referenced CA, certificate and key to the store.
func (a *assetStore) addTLSAssets(ctx context.Context, ns string, tlsConfig monitoringv1.SafeTLSConfig) error {
func (s *Store) addTLSAssets(ctx context.Context, ns string, tlsConfig monitoringv1.SafeTLSConfig) error {
var (
err error
ca string
@ -121,18 +78,18 @@ func (a *assetStore) addTLSAssets(ctx context.Context, ns string, tlsConfig moni
key string
)
ca, err = a.getKey(ctx, ns, tlsConfig.CA)
ca, err = s.GetKey(ctx, ns, tlsConfig.CA)
if err != nil {
return errors.Wrap(err, "failed to get CA")
}
cert, err = a.getKey(ctx, ns, tlsConfig.Cert)
cert, err = s.GetKey(ctx, ns, tlsConfig.Cert)
if err != nil {
return errors.Wrap(err, "failed to get cert")
}
if tlsConfig.KeySecret != nil {
key, err = a.getSecretKey(ctx, ns, *tlsConfig.KeySecret)
key, err = s.GetSecretKey(ctx, ns, *tlsConfig.KeySecret)
if err != nil {
return errors.Wrap(err, "failed to get key")
}
@ -147,7 +104,7 @@ func (a *assetStore) addTLSAssets(ctx context.Context, ns string, tlsConfig moni
if err != nil {
return errors.Wrap(err, "failed to parse CA certificate")
}
a.tlsAssets[tlsAssetKeyFromSelector(ns, tlsConfig.CA)] = TLSAsset(ca)
s.TLSAssets[TLSAssetKeyFromSelector(ns, tlsConfig.CA)] = TLSAsset(ca)
}
if cert != "" && key != "" {
@ -155,25 +112,15 @@ func (a *assetStore) addTLSAssets(ctx context.Context, ns string, tlsConfig moni
if err != nil {
return errors.Wrap(err, "failed to load X509 key pair")
}
a.tlsAssets[tlsAssetKeyFromSelector(ns, tlsConfig.Cert)] = TLSAsset(cert)
a.tlsAssets[tlsAssetKeyFromSelector(ns, monitoringv1.SecretOrConfigMap{Secret: tlsConfig.KeySecret})] = TLSAsset(key)
s.TLSAssets[TLSAssetKeyFromSelector(ns, tlsConfig.Cert)] = TLSAsset(cert)
s.TLSAssets[TLSAssetKeyFromSelector(ns, monitoringv1.SecretOrConfigMap{Secret: tlsConfig.KeySecret})] = TLSAsset(key)
}
return nil
}
// addSafeTLSConfig validates the given SafeTLSConfig and adds it to the store.
func (a *assetStore) addSafeTLSConfig(ctx context.Context, ns string, tlsConfig monitoringv1.SafeTLSConfig) error {
err := tlsConfig.Validate()
if err != nil {
return errors.Wrap(err, "failed to validate TLS configuration")
}
return a.addTLSAssets(ctx, ns, tlsConfig)
}
// addTLSConfig validates the given TLSConfig and adds it to the store.
func (a *assetStore) addTLSConfig(ctx context.Context, ns string, tlsConfig *monitoringv1.TLSConfig) error {
// AddSafeTLSConfig validates the given SafeTLSConfig and adds it to the store.
func (s *Store) AddSafeTLSConfig(ctx context.Context, ns string, tlsConfig *monitoringv1.SafeTLSConfig) error {
if tlsConfig == nil {
return nil
}
@ -183,62 +130,78 @@ func (a *assetStore) addTLSConfig(ctx context.Context, ns string, tlsConfig *mon
return errors.Wrap(err, "failed to validate TLS configuration")
}
return a.addTLSAssets(ctx, ns, tlsConfig.SafeTLSConfig)
return s.addTLSAssets(ctx, ns, *tlsConfig)
}
// addBasicAuth processes the given *BasicAuth and adds the referenced credentials to the store.
func (a *assetStore) addBasicAuth(ctx context.Context, ns string, ba *monitoringv1.BasicAuth, key string) error {
// AddTLSConfig validates the given TLSConfig and adds it to the store.
func (s *Store) AddTLSConfig(ctx context.Context, ns string, tlsConfig *monitoringv1.TLSConfig) error {
if tlsConfig == nil {
return nil
}
err := tlsConfig.Validate()
if err != nil {
return errors.Wrap(err, "failed to validate TLS configuration")
}
return s.addTLSAssets(ctx, ns, tlsConfig.SafeTLSConfig)
}
// AddBasicAuth processes the given *BasicAuth and adds the referenced credentials to the store.
func (s *Store) AddBasicAuth(ctx context.Context, ns string, ba *monitoringv1.BasicAuth, key string) error {
if ba == nil {
return nil
}
username, err := a.getSecretKey(ctx, ns, ba.Username)
username, err := s.GetSecretKey(ctx, ns, ba.Username)
if err != nil {
return errors.Wrap(err, "failed to get basic auth username")
}
password, err := a.getSecretKey(ctx, ns, ba.Password)
password, err := s.GetSecretKey(ctx, ns, ba.Password)
if err != nil {
return errors.Wrap(err, "failed to get basic auth password")
}
a.basicAuthAssets[key] = BasicAuthCredentials{
username: username,
password: password,
s.BasicAuthAssets[key] = BasicAuthCredentials{
Username: username,
Password: password,
}
return nil
}
// addBearerToken processes the given SecretKeySelector and adds the referenced data to the store.
func (a *assetStore) addBearerToken(ctx context.Context, ns string, sel v1.SecretKeySelector, key string) error {
// AddBearerToken processes the given SecretKeySelector and adds the referenced data to the store.
func (s *Store) AddBearerToken(ctx context.Context, ns string, sel v1.SecretKeySelector, key string) error {
if sel.Name == "" {
return nil
}
bearerToken, err := a.getSecretKey(ctx, ns, sel)
bearerToken, err := s.GetSecretKey(ctx, ns, sel)
if err != nil {
return errors.Wrap(err, "failed to get bearer token")
}
a.bearerTokenAssets[key] = BearerToken(bearerToken)
s.BearerTokenAssets[key] = BearerToken(bearerToken)
return nil
}
func (a *assetStore) getKey(ctx context.Context, namespace string, sel monitoringv1.SecretOrConfigMap) (string, error) {
// GetKey processes the given SecretOrConfigMap selector and returns the referenced data.
func (s *Store) GetKey(ctx context.Context, namespace string, sel monitoringv1.SecretOrConfigMap) (string, error) {
switch {
case sel.Secret != nil:
return a.getSecretKey(ctx, namespace, *sel.Secret)
return s.GetSecretKey(ctx, namespace, *sel.Secret)
case sel.ConfigMap != nil:
return a.getConfigMapKey(ctx, namespace, *sel.ConfigMap)
return s.GetConfigMapKey(ctx, namespace, *sel.ConfigMap)
default:
return "", nil
}
}
func (a *assetStore) getConfigMapKey(ctx context.Context, namespace string, sel v1.ConfigMapKeySelector) (string, error) {
obj, exists, err := a.objStore.Get(&v1.ConfigMap{
// GetConfigMapKey processes the given ConfigMapKeySelector and returns the referenced data.
func (s *Store) GetConfigMapKey(ctx context.Context, namespace string, sel v1.ConfigMapKeySelector) (string, error) {
obj, exists, err := s.objStore.Get(&v1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: sel.Name,
Namespace: namespace,
@ -249,11 +212,11 @@ func (a *assetStore) getConfigMapKey(ctx context.Context, namespace string, sel
}
if !exists {
cm, err := a.cmClient.ConfigMaps(namespace).Get(ctx, sel.Name, metav1.GetOptions{})
cm, err := s.cmClient.ConfigMaps(namespace).Get(ctx, sel.Name, metav1.GetOptions{})
if err != nil {
return "", errors.Wrapf(err, "unable to get configmap %q", sel.Name)
}
if err = a.objStore.Add(cm); err != nil {
if err = s.objStore.Add(cm); err != nil {
return "", errors.Wrapf(err, "unexpected store error when adding configmap %q", sel.Name)
}
obj = cm
@ -267,8 +230,9 @@ func (a *assetStore) getConfigMapKey(ctx context.Context, namespace string, sel
return cm.Data[sel.Key], nil
}
func (a *assetStore) getSecretKey(ctx context.Context, namespace string, sel v1.SecretKeySelector) (string, error) {
obj, exists, err := a.objStore.Get(&v1.Secret{
// GetSecretKey processes the given SecretKeySelector and returns the referenced data.
func (s *Store) GetSecretKey(ctx context.Context, namespace string, sel v1.SecretKeySelector) (string, error) {
obj, exists, err := s.objStore.Get(&v1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: sel.Name,
Namespace: namespace,
@ -279,11 +243,11 @@ func (a *assetStore) getSecretKey(ctx context.Context, namespace string, sel v1.
}
if !exists {
secret, err := a.sClient.Secrets(namespace).Get(ctx, sel.Name, metav1.GetOptions{})
secret, err := s.sClient.Secrets(namespace).Get(ctx, sel.Name, metav1.GetOptions{})
if err != nil {
return "", errors.Wrapf(err, "unable to get secret %q", sel.Name)
}
if err = a.objStore.Add(secret); err != nil {
if err = s.objStore.Add(secret); err != nil {
return "", errors.Wrapf(err, "unexpected store error when adding secret %q", sel.Name)
}
obj = secret

View file

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package prometheus
package assets
import (
"context"
@ -118,7 +118,7 @@ func TestAddBearerToken(t *testing.T) {
},
} {
t.Run("", func(t *testing.T) {
store := newAssetStore(c.CoreV1(), c.CoreV1())
store := NewStore(c.CoreV1(), c.CoreV1())
sel := v1.SecretKeySelector{
LocalObjectReference: v1.LocalObjectReference{
@ -128,7 +128,7 @@ func TestAddBearerToken(t *testing.T) {
}
key := fmt.Sprintf("basicauth/%d", i)
err := store.addBearerToken(context.Background(), tc.ns, sel, key)
err := store.AddBearerToken(context.Background(), tc.ns, sel, key)
if tc.err {
if err == nil {
@ -141,7 +141,7 @@ func TestAddBearerToken(t *testing.T) {
t.Fatalf("expecting no error, got %q", err)
}
s, found := store.bearerTokenAssets[key]
s, found := store.BearerTokenAssets[key]
if !found {
t.Fatalf("expecting to find key %q but got nothing", key)
@ -241,7 +241,7 @@ func TestAddBasicAuth(t *testing.T) {
},
} {
t.Run("", func(t *testing.T) {
store := newAssetStore(c.CoreV1(), c.CoreV1())
store := NewStore(c.CoreV1(), c.CoreV1())
basicAuth := &monitoringv1.BasicAuth{
Username: v1.SecretKeySelector{
@ -259,7 +259,7 @@ func TestAddBasicAuth(t *testing.T) {
}
key := fmt.Sprintf("basicauth/%d", i)
err := store.addBasicAuth(context.Background(), tc.ns, basicAuth, key)
err := store.AddBasicAuth(context.Background(), tc.ns, basicAuth, key)
if tc.err {
if err == nil {
@ -272,16 +272,16 @@ func TestAddBasicAuth(t *testing.T) {
t.Fatalf("expecting no error, got %q", err)
}
s, found := store.basicAuthAssets[key]
s, found := store.BasicAuthAssets[key]
if !found {
t.Fatalf("expecting to find key %q but got nothing", key)
}
if s.username != tc.expectedUser {
if s.Username != tc.expectedUser {
t.Fatalf("expecting username %q, got %q", tc.expectedUser, s)
}
if s.password != tc.expectedPassword {
if s.Password != tc.expectedPassword {
t.Fatalf("expecting password %q, got %q", tc.expectedPassword, s)
}
})
@ -736,9 +736,9 @@ func TestAddTLSConfig(t *testing.T) {
},
} {
t.Run("", func(t *testing.T) {
store := newAssetStore(c.CoreV1(), c.CoreV1())
store := NewStore(c.CoreV1(), c.CoreV1())
err := store.addSafeTLSConfig(context.Background(), tc.ns, tc.tlsConfig.SafeTLSConfig)
err := store.AddSafeTLSConfig(context.Background(), tc.ns, &tc.tlsConfig.SafeTLSConfig)
if tc.err {
if err == nil {
@ -751,9 +751,9 @@ func TestAddTLSConfig(t *testing.T) {
t.Fatalf("expecting no error, got %q", err)
}
key := tlsAssetKeyFromSelector(tc.ns, tc.tlsConfig.CA)
key := TLSAssetKeyFromSelector(tc.ns, tc.tlsConfig.CA)
ca, found := store.tlsAssets[key]
ca, found := store.TLSAssets[key]
if !found {
t.Fatalf("expecting to find key %q but got nothing", key)
}
@ -761,9 +761,9 @@ func TestAddTLSConfig(t *testing.T) {
t.Fatalf("expecting CA %q, got %q", tc.expectedCA, ca)
}
key = tlsAssetKeyFromSelector(tc.ns, tc.tlsConfig.Cert)
key = TLSAssetKeyFromSelector(tc.ns, tc.tlsConfig.Cert)
cert, found := store.tlsAssets[key]
cert, found := store.TLSAssets[key]
if !found {
t.Fatalf("expecting to find key %q but got nothing", key)
}
@ -771,9 +771,9 @@ func TestAddTLSConfig(t *testing.T) {
t.Fatalf("expecting cert %q, got %q", tc.expectedCert, cert)
}
key = tlsAssetKeyFromSecretSelector(tc.ns, tc.tlsConfig.KeySecret)
key = TLSAssetKeyFromSecretSelector(tc.ns, tc.tlsConfig.KeySecret)
k, found := store.tlsAssets[key]
k, found := store.TLSAssets[key]
if !found {
t.Fatalf("expecting to find key %q but got nothing", key)
}

30
pkg/assets/types.go Normal file
View file

@ -0,0 +1,30 @@
// Copyright 2020 The prometheus-operator Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package assets
// BasicAuthCredentials represents a username password pair to be used with
// basic http authentication, see https://tools.ietf.org/html/rfc7617.
type BasicAuthCredentials struct {
Username string
Password string
}
// BearerToken represents a bearer token, see
// https://tools.ietf.org/html/rfc6750.
type BearerToken string
// TLSAsset represents any TLS related opaque string, e.g. CA files, client
// certificates.
type TLSAsset string

63
pkg/assets/utils.go Normal file
View file

@ -0,0 +1,63 @@
// Copyright 2020 The prometheus-operator Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package assets
import (
"fmt"
monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
v1 "k8s.io/api/core/v1"
)
// TLSAssetKey is a key for a TLS asset.
type TLSAssetKey struct {
from string
ns string
name string
key string
}
// TLSAssetKeyFromSecretSelector returns a TLSAssetKey struct from a secret key selector.
func TLSAssetKeyFromSecretSelector(ns string, sel *v1.SecretKeySelector) TLSAssetKey {
return TLSAssetKeyFromSelector(
ns,
monitoringv1.SecretOrConfigMap{
Secret: sel,
},
)
}
// TLSAssetKeyFromSelector returns a TLSAssetKey struct from a secret or configmap key selector.
func TLSAssetKeyFromSelector(ns string, sel monitoringv1.SecretOrConfigMap) TLSAssetKey {
if sel.Secret != nil {
return TLSAssetKey{
from: "secret",
ns: ns,
name: sel.Secret.Name,
key: sel.Secret.Key,
}
}
return TLSAssetKey{
from: "configmap",
ns: ns,
name: sel.ConfigMap.Name,
key: sel.ConfigMap.Key,
}
}
// String implements the fmt.Stringer interface.
func (k TLSAssetKey) String() string {
return fmt.Sprintf("%s_%s_%s_%s", k.from, k.ns, k.name, k.key)
}

View file

@ -24,6 +24,7 @@ import (
"time"
monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
"github.com/prometheus-operator/prometheus-operator/pkg/assets"
monitoringclient "github.com/prometheus-operator/prometheus-operator/pkg/client/versioned"
"github.com/prometheus-operator/prometheus-operator/pkg/informers"
"github.com/prometheus-operator/prometheus-operator/pkg/k8sutil"
@ -88,21 +89,6 @@ type Operator struct {
configGenerator *configGenerator
}
// BasicAuthCredentials represents a username password pair to be used with
// basic http authentication, see https://tools.ietf.org/html/rfc7617.
type BasicAuthCredentials struct {
username string
password string
}
// BearerToken represents a bearer token, see
// https://tools.ietf.org/html/rfc6750.
type BearerToken string
// TLSAsset represents any TLS related opaque string, e.g. CA files, client
// certificates.
type TLSAsset string
// New creates a new controller.
func New(ctx context.Context, conf operator.Config, logger log.Logger, r prometheus.Registerer) (*Operator, error) {
cfg, err := k8sutil.NewClusterConfig(conf.Host, conf.TLSInsecure, &conf.TLSConfig)
@ -1162,7 +1148,7 @@ func (c *Operator) sync(ctx context.Context, key string) error {
return err
}
assetStore := newAssetStore(c.kclient.CoreV1(), c.kclient.CoreV1())
assetStore := assets.NewStore(c.kclient.CoreV1(), c.kclient.CoreV1())
if err := c.createOrUpdateConfigurationSecret(ctx, p, ruleConfigMapNames, assetStore); err != nil {
return errors.Wrap(err, "creating config failed")
@ -1383,7 +1369,7 @@ func gzipConfig(buf *bytes.Buffer, conf []byte) error {
return nil
}
func (c *Operator) createOrUpdateConfigurationSecret(ctx context.Context, p *monitoringv1.Prometheus, ruleConfigMapNames []string, store *assetStore) error {
func (c *Operator) createOrUpdateConfigurationSecret(ctx context.Context, p *monitoringv1.Prometheus, ruleConfigMapNames []string, store *assets.Store) error {
// If no service or pod monitor selectors are configured, the user wants to
// manage configuration themselves. Do create an empty Secret if it doesn't
// exist.
@ -1431,22 +1417,22 @@ func (c *Operator) createOrUpdateConfigurationSecret(ctx context.Context, p *mon
}
for i, remote := range p.Spec.RemoteRead {
if err := store.addBasicAuth(ctx, p.GetNamespace(), remote.BasicAuth, fmt.Sprintf("remoteRead/%d", i)); err != nil {
if err := store.AddBasicAuth(ctx, p.GetNamespace(), remote.BasicAuth, fmt.Sprintf("remoteRead/%d", i)); err != nil {
return errors.Wrapf(err, "remote read %d", i)
}
}
for i, remote := range p.Spec.RemoteWrite {
if err := store.addBasicAuth(ctx, p.GetNamespace(), remote.BasicAuth, fmt.Sprintf("remoteWrite/%d", i)); err != nil {
if err := store.AddBasicAuth(ctx, p.GetNamespace(), remote.BasicAuth, fmt.Sprintf("remoteWrite/%d", i)); err != nil {
return errors.Wrapf(err, "remote write %d", i)
}
if err := store.addTLSConfig(ctx, p.GetNamespace(), remote.TLSConfig); err != nil {
if err := store.AddTLSConfig(ctx, p.GetNamespace(), remote.TLSConfig); err != nil {
return errors.Wrapf(err, "remote write %d", i)
}
}
if p.Spec.APIServerConfig != nil {
if err := store.addBasicAuth(ctx, p.GetNamespace(), p.Spec.APIServerConfig.BasicAuth, "apiserver"); err != nil {
if err := store.AddBasicAuth(ctx, p.GetNamespace(), p.Spec.APIServerConfig.BasicAuth, "apiserver"); err != nil {
return errors.Wrap(err, "apiserver config")
}
}
@ -1470,8 +1456,8 @@ func (c *Operator) createOrUpdateConfigurationSecret(ctx context.Context, p *mon
smons,
pmons,
bmons,
store.basicAuthAssets,
store.bearerTokenAssets,
store.BasicAuthAssets,
store.BearerTokenAssets,
additionalScrapeConfigs,
additionalAlertRelabelConfigs,
additionalAlertManagerConfigs,
@ -1519,7 +1505,7 @@ func (c *Operator) createOrUpdateConfigurationSecret(ctx context.Context, p *mon
return err
}
func (c *Operator) createOrUpdateTLSAssetSecret(ctx context.Context, p *monitoringv1.Prometheus, store *assetStore) error {
func (c *Operator) createOrUpdateTLSAssetSecret(ctx context.Context, p *monitoringv1.Prometheus, store *assets.Store) error {
boolTrue := true
sClient := c.kclient.CoreV1().Secrets(p.Namespace)
@ -1541,7 +1527,7 @@ func (c *Operator) createOrUpdateTLSAssetSecret(ctx context.Context, p *monitori
Data: map[string][]byte{},
}
for key, asset := range store.tlsAssets {
for key, asset := range store.TLSAssets {
tlsAssetsSecret.Data[key.String()] = []byte(asset)
}
@ -1570,7 +1556,7 @@ func (c *Operator) createOrUpdateTLSAssetSecret(ctx context.Context, p *monitori
return nil
}
func (c *Operator) selectServiceMonitors(ctx context.Context, p *monitoringv1.Prometheus, store *assetStore) (map[string]*monitoringv1.ServiceMonitor, error) {
func (c *Operator) selectServiceMonitors(ctx context.Context, p *monitoringv1.Prometheus, store *assets.Store) (map[string]*monitoringv1.ServiceMonitor, error) {
namespaces := []string{}
// Selectors (<namespace>/<name>) might overlap. Deduplicate them along the keyFunc.
serviceMonitors := make(map[string]*monitoringv1.ServiceMonitor)
@ -1622,16 +1608,16 @@ func (c *Operator) selectServiceMonitors(ctx context.Context, p *monitoringv1.Pr
smKey := fmt.Sprintf("serviceMonitor/%s/%s/%d", sm.GetNamespace(), sm.GetName(), i)
if err = store.addBearerToken(ctx, sm.GetNamespace(), endpoint.BearerTokenSecret, smKey); err != nil {
if err = store.AddBearerToken(ctx, sm.GetNamespace(), endpoint.BearerTokenSecret, smKey); err != nil {
break
}
if err = store.addBasicAuth(ctx, sm.GetNamespace(), endpoint.BasicAuth, smKey); err != nil {
if err = store.AddBasicAuth(ctx, sm.GetNamespace(), endpoint.BasicAuth, smKey); err != nil {
break
}
if endpoint.TLSConfig != nil {
if err = store.addTLSConfig(ctx, sm.GetNamespace(), endpoint.TLSConfig); err != nil {
if err = store.AddTLSConfig(ctx, sm.GetNamespace(), endpoint.TLSConfig); err != nil {
break
}
}
@ -1666,7 +1652,7 @@ func (c *Operator) selectServiceMonitors(ctx context.Context, p *monitoringv1.Pr
return res, nil
}
func (c *Operator) selectPodMonitors(ctx context.Context, p *monitoringv1.Prometheus, store *assetStore) (map[string]*monitoringv1.PodMonitor, error) {
func (c *Operator) selectPodMonitors(ctx context.Context, p *monitoringv1.Prometheus, store *assets.Store) (map[string]*monitoringv1.PodMonitor, error) {
namespaces := []string{}
// Selectors (<namespace>/<name>) might overlap. Deduplicate them along the keyFunc.
podMonitors := make(map[string]*monitoringv1.PodMonitor)
@ -1710,16 +1696,16 @@ func (c *Operator) selectPodMonitors(ctx context.Context, p *monitoringv1.Promet
for i, endpoint := range pm.Spec.PodMetricsEndpoints {
pmKey := fmt.Sprintf("podMonitor/%s/%s/%d", pm.GetNamespace(), pm.GetName(), i)
if err = store.addBearerToken(ctx, pm.GetNamespace(), endpoint.BearerTokenSecret, pmKey); err != nil {
if err = store.AddBearerToken(ctx, pm.GetNamespace(), endpoint.BearerTokenSecret, pmKey); err != nil {
break
}
if err = store.addBasicAuth(ctx, pm.GetNamespace(), endpoint.BasicAuth, pmKey); err != nil {
if err = store.AddBasicAuth(ctx, pm.GetNamespace(), endpoint.BasicAuth, pmKey); err != nil {
break
}
if endpoint.TLSConfig != nil {
if err = store.addSafeTLSConfig(ctx, pm.GetNamespace(), endpoint.TLSConfig.SafeTLSConfig); err != nil {
if err = store.AddSafeTLSConfig(ctx, pm.GetNamespace(), &endpoint.TLSConfig.SafeTLSConfig); err != nil {
break
}
}

View file

@ -29,6 +29,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
v1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
"github.com/prometheus-operator/prometheus-operator/pkg/assets"
"github.com/prometheus-operator/prometheus-operator/pkg/operator"
)
@ -75,7 +76,7 @@ func stringMapToMapSlice(m map[string]string) yaml.MapSlice {
func addSafeTLStoYaml(cfg yaml.MapSlice, namespace string, tls v1.SafeTLSConfig) yaml.MapSlice {
pathForSelector := func(sel v1.SecretOrConfigMap) string {
return path.Join(tlsAssetsDir, tlsAssetKeyFromSelector(namespace, sel).String())
return path.Join(tlsAssetsDir, assets.TLSAssetKeyFromSelector(namespace, sel).String())
}
tlsConfig := yaml.MapSlice{
{Key: "insecure_skip_verify", Value: tls.InsecureSkipVerify},
@ -157,8 +158,8 @@ func (cg *configGenerator) generateConfig(
sMons map[string]*v1.ServiceMonitor,
pMons map[string]*v1.PodMonitor,
probes map[string]*v1.Probe,
basicAuthSecrets map[string]BasicAuthCredentials,
bearerTokens map[string]BearerToken,
basicAuthSecrets map[string]assets.BasicAuthCredentials,
bearerTokens map[string]assets.BearerToken,
additionalScrapeConfigs []byte,
additionalAlertRelabelConfigs []byte,
additionalAlertManagerConfigs []byte,
@ -411,8 +412,8 @@ func (cg *configGenerator) generatePodMonitorConfig(
m *v1.PodMonitor,
ep v1.PodMetricsEndpoint,
i int, apiserverConfig *v1.APIServerConfig,
basicAuthSecrets map[string]BasicAuthCredentials,
bearerTokens map[string]BearerToken,
basicAuthSecrets map[string]assets.BasicAuthCredentials,
bearerTokens map[string]assets.BearerToken,
ignoreHonorLabels bool,
overrideHonorTimestamps bool,
ignoreNamespaceSelectors bool,
@ -478,8 +479,8 @@ func (cg *configGenerator) generatePodMonitorConfig(
if s, ok := basicAuthSecrets[fmt.Sprintf("podMonitor/%s/%s/%d", m.Namespace, m.Name, i)]; ok {
cfg = append(cfg, yaml.MapItem{
Key: "basic_auth", Value: yaml.MapSlice{
{Key: "username", Value: s.username},
{Key: "password", Value: s.password},
{Key: "username", Value: s.Username},
{Key: "password", Value: s.Password},
},
})
}
@ -659,7 +660,7 @@ func (cg *configGenerator) generateProbeConfig(
version semver.Version,
m *v1.Probe,
apiserverConfig *v1.APIServerConfig,
basicAuthSecrets map[string]BasicAuthCredentials,
basicAuthSecrets map[string]assets.BasicAuthCredentials,
ignoreHonorLabels bool,
overrideHonorTimestamps bool,
ignoreNamespaceSelectors bool,
@ -854,8 +855,8 @@ func (cg *configGenerator) generateServiceMonitorConfig(
ep v1.Endpoint,
i int,
apiserverConfig *v1.APIServerConfig,
basicAuthSecrets map[string]BasicAuthCredentials,
bearerTokens map[string]BearerToken,
basicAuthSecrets map[string]assets.BasicAuthCredentials,
bearerTokens map[string]assets.BearerToken,
overrideHonorLabels bool,
overrideHonorTimestamps bool,
ignoreNamespaceSelectors bool,
@ -923,8 +924,8 @@ func (cg *configGenerator) generateServiceMonitorConfig(
if s, ok := basicAuthSecrets[fmt.Sprintf("serviceMonitor/%s/%s/%d", m.Namespace, m.Name, i)]; ok {
cfg = append(cfg, yaml.MapItem{
Key: "basic_auth", Value: yaml.MapSlice{
{Key: "username", Value: s.username},
{Key: "password", Value: s.password},
{Key: "username", Value: s.Username},
{Key: "password", Value: s.Password},
},
})
}
@ -1227,7 +1228,7 @@ func getNamespacesFromNamespaceSelector(nsel *v1.NamespaceSelector, namespace st
return nsel.MatchNames
}
func (cg *configGenerator) generateK8SSDConfig(namespaces []string, apiserverConfig *v1.APIServerConfig, basicAuthSecrets map[string]BasicAuthCredentials, role string) yaml.MapItem {
func (cg *configGenerator) generateK8SSDConfig(namespaces []string, apiserverConfig *v1.APIServerConfig, basicAuthSecrets map[string]assets.BasicAuthCredentials, role string) yaml.MapItem {
k8sSDConfig := yaml.MapSlice{
{
Key: "role",
@ -1256,8 +1257,8 @@ func (cg *configGenerator) generateK8SSDConfig(namespaces []string, apiserverCon
if s, ok := basicAuthSecrets["apiserver"]; ok {
k8sSDConfig = append(k8sSDConfig, yaml.MapItem{
Key: "basic_auth", Value: yaml.MapSlice{
{Key: "username", Value: s.username},
{Key: "password", Value: s.password},
{Key: "username", Value: s.Username},
{Key: "password", Value: s.Password},
},
})
}
@ -1284,7 +1285,7 @@ func (cg *configGenerator) generateK8SSDConfig(namespaces []string, apiserverCon
}
}
func (cg *configGenerator) generateAlertmanagerConfig(version semver.Version, am v1.AlertmanagerEndpoints, apiserverConfig *v1.APIServerConfig, basicAuthSecrets map[string]BasicAuthCredentials) yaml.MapSlice {
func (cg *configGenerator) generateAlertmanagerConfig(version semver.Version, am v1.AlertmanagerEndpoints, apiserverConfig *v1.APIServerConfig, basicAuthSecrets map[string]assets.BasicAuthCredentials) yaml.MapSlice {
if am.Scheme == "" {
am.Scheme = "http"
}
@ -1365,7 +1366,7 @@ func (cg *configGenerator) generateAlertmanagerConfig(version semver.Version, am
return cfg
}
func (cg *configGenerator) generateRemoteReadConfig(version semver.Version, specs []v1.RemoteReadSpec, basicAuthSecrets map[string]BasicAuthCredentials) yaml.MapItem {
func (cg *configGenerator) generateRemoteReadConfig(version semver.Version, specs []v1.RemoteReadSpec, basicAuthSecrets map[string]assets.BasicAuthCredentials) yaml.MapItem {
cfgs := []yaml.MapSlice{}
@ -1396,8 +1397,8 @@ func (cg *configGenerator) generateRemoteReadConfig(version semver.Version, spec
if s, ok := basicAuthSecrets[fmt.Sprintf("remoteRead/%d", i)]; ok {
cfg = append(cfg, yaml.MapItem{
Key: "basic_auth", Value: yaml.MapSlice{
{Key: "username", Value: s.username},
{Key: "password", Value: s.password},
{Key: "username", Value: s.Username},
{Key: "password", Value: s.Password},
},
})
}
@ -1429,7 +1430,7 @@ func (cg *configGenerator) generateRemoteReadConfig(version semver.Version, spec
}
}
func (cg *configGenerator) generateRemoteWriteConfig(version semver.Version, p *v1.Prometheus, basicAuthSecrets map[string]BasicAuthCredentials) yaml.MapItem {
func (cg *configGenerator) generateRemoteWriteConfig(version semver.Version, p *v1.Prometheus, basicAuthSecrets map[string]assets.BasicAuthCredentials) yaml.MapItem {
cfgs := []yaml.MapSlice{}
@ -1491,8 +1492,8 @@ func (cg *configGenerator) generateRemoteWriteConfig(version semver.Version, p *
if s, ok := basicAuthSecrets[fmt.Sprintf("remoteWrite/%d", i)]; ok {
cfg = append(cfg, yaml.MapItem{
Key: "basic_auth", Value: yaml.MapSlice{
{Key: "username", Value: s.username},
{Key: "password", Value: s.password},
{Key: "username", Value: s.Username},
{Key: "password", Value: s.Password},
},
})
}

View file

@ -22,6 +22,7 @@ import (
"github.com/go-openapi/swag"
"github.com/kylelemons/godebug/pretty"
monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
"github.com/prometheus-operator/prometheus-operator/pkg/assets"
"github.com/prometheus-operator/prometheus-operator/pkg/operator"
yaml "gopkg.in/yaml.v2"
v1 "k8s.io/api/core/v1"
@ -204,8 +205,8 @@ alerting:
map[string]*monitoringv1.ServiceMonitor{},
nil,
nil,
map[string]BasicAuthCredentials{},
map[string]BearerToken{},
map[string]assets.BasicAuthCredentials{},
map[string]assets.BearerToken{},
nil,
nil,
nil,
@ -424,7 +425,7 @@ func TestProbeStaticTargetsConfigGeneration(t *testing.T) {
},
},
},
map[string]BasicAuthCredentials{},
map[string]assets.BasicAuthCredentials{},
nil,
nil,
nil,
@ -528,7 +529,7 @@ func TestProbeStaticTargetsConfigGenerationWithLabelEnforce(t *testing.T) {
},
},
},
map[string]BasicAuthCredentials{},
map[string]assets.BasicAuthCredentials{},
nil,
nil,
nil,
@ -634,7 +635,7 @@ func TestProbeStaticTargetsConfigGenerationWithJobName(t *testing.T) {
},
},
},
map[string]BasicAuthCredentials{},
map[string]assets.BasicAuthCredentials{},
nil,
nil,
nil,
@ -747,7 +748,7 @@ func TestProbeIngressSDConfigGeneration(t *testing.T) {
},
},
},
map[string]BasicAuthCredentials{},
map[string]assets.BasicAuthCredentials{},
nil,
nil,
nil,
@ -874,7 +875,7 @@ func TestProbeIngressSDConfigGenerationWithLabelEnforce(t *testing.T) {
},
},
},
map[string]BasicAuthCredentials{},
map[string]assets.BasicAuthCredentials{},
nil,
nil,
nil,
@ -966,7 +967,7 @@ func TestK8SSDConfigGeneration(t *testing.T) {
testcases := []struct {
apiserverConfig *monitoringv1.APIServerConfig
basicAuthSecrets map[string]BasicAuthCredentials
basicAuthSecrets map[string]assets.BasicAuthCredentials
expected string
}{
{
@ -987,7 +988,7 @@ func TestK8SSDConfigGeneration(t *testing.T) {
BearerTokenFile: "bearer_token_file",
TLSConfig: nil,
},
map[string]BasicAuthCredentials{
map[string]assets.BasicAuthCredentials{
"apiserver": {
"foo",
"bar",
@ -1051,8 +1052,8 @@ func TestAlertmanagerBearerToken(t *testing.T) {
nil,
nil,
nil,
map[string]BasicAuthCredentials{},
map[string]BearerToken{},
map[string]assets.BasicAuthCredentials{},
map[string]assets.BearerToken{},
nil,
nil,
nil,
@ -1130,8 +1131,8 @@ func TestAlertmanagerAPIVersion(t *testing.T) {
nil,
nil,
nil,
map[string]BasicAuthCredentials{},
map[string]BearerToken{},
map[string]assets.BasicAuthCredentials{},
map[string]assets.BearerToken{},
nil,
nil,
nil,
@ -1210,8 +1211,8 @@ func TestAlertmanagerTimeoutConfig(t *testing.T) {
nil,
nil,
nil,
map[string]BasicAuthCredentials{},
map[string]BearerToken{},
map[string]assets.BasicAuthCredentials{},
map[string]assets.BearerToken{},
nil,
nil,
nil,
@ -1288,8 +1289,8 @@ func TestAdditionalAlertRelabelConfigs(t *testing.T) {
nil,
nil,
nil,
map[string]BasicAuthCredentials{},
map[string]BearerToken{},
map[string]assets.BasicAuthCredentials{},
map[string]assets.BearerToken{},
nil,
[]byte(`- action: drop
source_labels: [__meta_kubernetes_node_name]
@ -1401,8 +1402,8 @@ func TestNoEnforcedNamespaceLabelServiceMonitor(t *testing.T) {
},
nil,
nil,
map[string]BasicAuthCredentials{},
map[string]BearerToken{},
map[string]assets.BasicAuthCredentials{},
map[string]assets.BearerToken{},
nil,
nil,
nil,
@ -1546,8 +1547,8 @@ func TestEnforcedNamespaceLabelPodMonitor(t *testing.T) {
},
},
nil,
map[string]BasicAuthCredentials{},
map[string]BearerToken{},
map[string]assets.BasicAuthCredentials{},
map[string]assets.BearerToken{},
nil,
nil,
nil,
@ -1679,8 +1680,8 @@ func TestEnforcedNamespaceLabelServiceMonitor(t *testing.T) {
},
nil,
nil,
map[string]BasicAuthCredentials{},
map[string]BearerToken{},
map[string]assets.BasicAuthCredentials{},
map[string]assets.BearerToken{},
nil,
nil,
nil,
@ -1792,8 +1793,8 @@ func TestAdditionalAlertmanagers(t *testing.T) {
nil,
nil,
nil,
map[string]BasicAuthCredentials{},
map[string]BearerToken{},
map[string]assets.BasicAuthCredentials{},
map[string]assets.BearerToken{},
nil,
nil,
[]byte(`- static_configs:
@ -1888,8 +1889,8 @@ func TestSettingHonorTimestampsInServiceMonitor(t *testing.T) {
},
nil,
nil,
map[string]BasicAuthCredentials{},
map[string]BearerToken{},
map[string]assets.BasicAuthCredentials{},
map[string]assets.BearerToken{},
nil,
nil,
nil,
@ -2018,8 +2019,8 @@ func TestSettingHonorTimestampsInPodMonitor(t *testing.T) {
},
},
nil,
map[string]BasicAuthCredentials{},
map[string]BearerToken{},
map[string]assets.BasicAuthCredentials{},
map[string]assets.BearerToken{},
nil,
nil,
nil,
@ -2130,8 +2131,8 @@ func TestHonorTimestampsOverriding(t *testing.T) {
},
nil,
nil,
map[string]BasicAuthCredentials{},
map[string]BearerToken{},
map[string]assets.BasicAuthCredentials{},
map[string]assets.BearerToken{},
nil,
nil,
nil,
@ -2259,8 +2260,8 @@ func TestSettingHonorLabels(t *testing.T) {
},
nil,
nil,
map[string]BasicAuthCredentials{},
map[string]BearerToken{},
map[string]assets.BasicAuthCredentials{},
map[string]assets.BearerToken{},
nil,
nil,
nil,
@ -2388,8 +2389,8 @@ func TestHonorLabelsOverriding(t *testing.T) {
},
nil,
nil,
map[string]BasicAuthCredentials{},
map[string]BearerToken{},
map[string]assets.BasicAuthCredentials{},
map[string]assets.BearerToken{},
nil,
nil,
nil,
@ -2516,8 +2517,8 @@ func TestTargetLabels(t *testing.T) {
},
nil,
nil,
map[string]BasicAuthCredentials{},
map[string]BearerToken{},
map[string]assets.BasicAuthCredentials{},
map[string]assets.BearerToken{},
nil,
nil,
nil,
@ -2643,8 +2644,8 @@ func TestPodTargetLabels(t *testing.T) {
},
nil,
nil,
map[string]BasicAuthCredentials{},
map[string]BearerToken{},
map[string]assets.BasicAuthCredentials{},
map[string]assets.BearerToken{},
nil,
nil,
nil,
@ -2770,8 +2771,8 @@ func TestPodTargetLabelsFromPodMonitor(t *testing.T) {
},
},
nil,
map[string]BasicAuthCredentials{},
map[string]BearerToken{},
map[string]assets.BasicAuthCredentials{},
map[string]assets.BearerToken{},
nil,
nil,
nil,
@ -2870,8 +2871,8 @@ func TestEmptyEndointPorts(t *testing.T) {
},
nil,
nil,
map[string]BasicAuthCredentials{},
map[string]BearerToken{},
map[string]assets.BasicAuthCredentials{},
map[string]assets.BearerToken{},
nil,
nil,
nil,
@ -3004,8 +3005,8 @@ func generateTestConfig(version string) ([]byte, error) {
makeServiceMonitors(),
makePodMonitors(),
nil,
map[string]BasicAuthCredentials{},
map[string]BearerToken{},
map[string]assets.BasicAuthCredentials{},
map[string]assets.BearerToken{},
nil,
nil,
nil,
@ -3608,8 +3609,8 @@ alerting:
},
nil,
nil,
map[string]BasicAuthCredentials{},
map[string]BearerToken{},
map[string]assets.BasicAuthCredentials{},
map[string]assets.BearerToken{},
nil,
nil,
nil,
@ -3855,8 +3856,8 @@ alerting:
},
nil,
nil,
map[string]BasicAuthCredentials{},
map[string]BearerToken{},
map[string]assets.BasicAuthCredentials{},
map[string]assets.BearerToken{},
nil,
nil,
nil,