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

Merge pull request from simonpasquier/add-tlsconfig-tests

chore: add ResourceSelector tests for TLS configuration
This commit is contained in:
Simon Pasquier 2023-12-06 15:02:05 +01:00 committed by GitHub
commit 9fe4c212cb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 312 additions and 178 deletions

52
Documentation/api.md generated
View file

@ -12722,32 +12722,6 @@ Kubernetes core/v1.ConfigMapKeySelector
</tr>
</tbody>
</table>
<h3 id="monitoring.coreos.com/v1.SecretOrConfigMapValidationError">SecretOrConfigMapValidationError
</h3>
<div>
<p>SecretOrConfigMapValidationError is returned by SecretOrConfigMap.Validate()
on semantically invalid configurations.</p>
</div>
<table>
<thead>
<tr>
<th>Field</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<code>err</code><br/>
<em>
string
</em>
</td>
<td>
</td>
</tr>
</tbody>
</table>
<h3 id="monitoring.coreos.com/v1.ServiceMonitorSpec">ServiceMonitorSpec
</h3>
<p>
@ -13294,32 +13268,6 @@ string
</tr>
</tbody>
</table>
<h3 id="monitoring.coreos.com/v1.TLSConfigValidationError">TLSConfigValidationError
</h3>
<div>
<p>TLSConfigValidationError is returned by TLSConfig.Validate() on semantically
invalid tls configurations.</p>
</div>
<table>
<thead>
<tr>
<th>Field</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<code>err</code><br/>
<em>
string
</em>
</td>
<td>
</td>
</tr>
</tbody>
</table>
<h3 id="monitoring.coreos.com/v1.TSDBSpec">TSDBSpec
</h3>
<p>

2
go.mod
View file

@ -10,7 +10,6 @@ require (
github.com/distribution/reference v0.5.0
github.com/evanphx/json-patch/v5 v5.7.0
github.com/go-kit/log v0.2.1
github.com/go-openapi/swag v0.22.4
github.com/go-test/deep v1.1.0
github.com/gogo/protobuf v1.3.2
github.com/google/go-cmp v0.6.0
@ -48,6 +47,7 @@ require (
github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
github.com/docker/distribution v2.8.3+incompatible // indirect
github.com/go-openapi/swag v0.22.4 // indirect
github.com/golang-jwt/jwt/v5 v5.0.0 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/google/gnostic-models v0.6.8 // indirect

View file

@ -594,26 +594,34 @@ type SecretOrConfigMap struct {
ConfigMap *v1.ConfigMapKeySelector `json:"configMap,omitempty"`
}
// SecretOrConfigMapValidationError is returned by SecretOrConfigMap.Validate()
// on semantically invalid configurations.
// +k8s:openapi-gen=false
type SecretOrConfigMapValidationError struct {
err string
}
func (e *SecretOrConfigMapValidationError) Error() string {
return e.err
}
// Validate semantically validates the given TLSConfig.
// Validate semantically validates the given SecretOrConfigMap.
func (c *SecretOrConfigMap) Validate() error {
if c == nil {
return nil
}
if c.Secret != nil && c.ConfigMap != nil {
return &SecretOrConfigMapValidationError{"SecretOrConfigMap can not specify both Secret and ConfigMap"}
return fmt.Errorf("cannot specify both Secret and ConfigMap")
}
return nil
}
func (c *SecretOrConfigMap) String() string {
if c == nil {
return "<nil>"
}
switch {
case c.Secret != nil:
return fmt.Sprintf("<secret=%s,key=%s>", c.Secret.LocalObjectReference.Name, c.Secret.Key)
case c.ConfigMap != nil:
return fmt.Sprintf("<configmap=%s,key=%s>", c.ConfigMap.LocalObjectReference.Name, c.ConfigMap.Key)
}
return "<empty>"
}
// SafeTLSConfig specifies safe TLS configuration parameters.
// +k8s:openapi-gen=true
type SafeTLSConfig struct {
@ -633,22 +641,22 @@ type SafeTLSConfig struct {
func (c *SafeTLSConfig) Validate() error {
if c.CA != (SecretOrConfigMap{}) {
if err := c.CA.Validate(); err != nil {
return err
return fmt.Errorf("ca %s: %w", c.CA.String(), err)
}
}
if c.Cert != (SecretOrConfigMap{}) {
if err := c.Cert.Validate(); err != nil {
return err
return fmt.Errorf("cert %s: %w", c.Cert.String(), err)
}
}
if c.Cert != (SecretOrConfigMap{}) && c.KeySecret == nil {
return &TLSConfigValidationError{"client cert specified without client key"}
return fmt.Errorf("client cert specified without client key")
}
if c.KeySecret != nil && c.Cert == (SecretOrConfigMap{}) {
return &TLSConfigValidationError{"client key specified without client cert"}
return fmt.Errorf("client key specified without client cert")
}
return nil
@ -666,50 +674,39 @@ type TLSConfig struct {
KeyFile string `json:"keyFile,omitempty"`
}
// TLSConfigValidationError is returned by TLSConfig.Validate() on semantically
// invalid tls configurations.
// +k8s:openapi-gen=false
type TLSConfigValidationError struct {
err string
}
func (e *TLSConfigValidationError) Error() string {
return e.err
}
// Validate semantically validates the given TLSConfig.
func (c *TLSConfig) Validate() error {
if c.CA != (SecretOrConfigMap{}) {
if c.CAFile != "" {
return &TLSConfigValidationError{"tls config can not both specify CAFile and CA"}
return fmt.Errorf("cannot specify both caFile and ca")
}
if err := c.CA.Validate(); err != nil {
return &TLSConfigValidationError{"tls config CA is invalid"}
return fmt.Errorf("SecretOrConfigMap ca: %w", err)
}
}
if c.Cert != (SecretOrConfigMap{}) {
if c.CertFile != "" {
return &TLSConfigValidationError{"tls config can not both specify CertFile and Cert"}
return fmt.Errorf("cannot specify both certFile and cert")
}
if err := c.Cert.Validate(); err != nil {
return &TLSConfigValidationError{"tls config Cert is invalid"}
return fmt.Errorf("SecretOrConfigMap cert: %w", err)
}
}
if c.KeyFile != "" && c.KeySecret != nil {
return &TLSConfigValidationError{"tls config can not both specify KeyFile and KeySecret"}
return fmt.Errorf("cannot specify both keyFile and keySecret")
}
hasCert := c.CertFile != "" || c.Cert != (SecretOrConfigMap{})
hasKey := c.KeyFile != "" || c.KeySecret != nil
if hasCert && !hasKey {
return &TLSConfigValidationError{"tls config can not specify client cert without client key"}
return fmt.Errorf("cannot specify client cert without client key")
}
if hasKey && !hasCert {
return &TLSConfigValidationError{"tls config can not specify client key without client cert"}
return fmt.Errorf("cannot specify client key without client cert")
}
return nil

View file

@ -39,11 +39,13 @@ func TestValidateSecretOrConfigMap(t *testing.T) {
func TestValidateSafeTLSConfig(t *testing.T) {
for _, tc := range []struct {
name string
config *SafeTLSConfig
err bool
err bool
}{
{
// CA, Cert, and KeySecret.
name: "ca, cert and keySecret",
config: &SafeTLSConfig{
CA: SecretOrConfigMap{Secret: &v1.SecretKeySelector{}},
Cert: SecretOrConfigMap{Secret: &v1.SecretKeySelector{}},
@ -52,7 +54,7 @@ func TestValidateSafeTLSConfig(t *testing.T) {
err: false,
},
{
// Without CA cert.
name: "cert and keySecret",
config: &SafeTLSConfig{
Cert: SecretOrConfigMap{Secret: &v1.SecretKeySelector{}},
KeySecret: &v1.SecretKeySelector{},
@ -60,7 +62,7 @@ func TestValidateSafeTLSConfig(t *testing.T) {
err: false,
},
{
// Without Cert.
name: "ca and keySecret",
config: &SafeTLSConfig{
CA: SecretOrConfigMap{Secret: &v1.SecretKeySelector{}},
KeySecret: &v1.SecretKeySelector{},
@ -68,21 +70,29 @@ func TestValidateSafeTLSConfig(t *testing.T) {
err: true,
},
{
// Without KeySecret.
name: "ca and cert",
config: &SafeTLSConfig{
CA: SecretOrConfigMap{Secret: &v1.SecretKeySelector{}},
Cert: SecretOrConfigMap{Secret: &v1.SecretKeySelector{}},
CA: SecretOrConfigMap{
Secret: &v1.SecretKeySelector{},
},
Cert: SecretOrConfigMap{
Secret: &v1.SecretKeySelector{},
},
},
err: true,
},
} {
t.Run("", func(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
err := tc.config.Validate()
if tc.err && err == nil {
t.Fatalf("expected validation of %+v to fail, but got no error", tc.config)
if tc.err {
if err == nil {
t.Fatal("expected error but got none")
}
return
}
if !tc.err && err != nil {
t.Fatalf("expected validation of %+v not to fail, err: %s", tc.config, err)
if err != nil {
t.Fatalf("expected no error but got: %s", err)
}
})
}
@ -90,11 +100,13 @@ func TestValidateSafeTLSConfig(t *testing.T) {
func TestValidateTLSConfig(t *testing.T) {
for _, tc := range []struct {
name string
config *TLSConfig
err bool
err bool
}{
{
// CAFile, CertFile, and KeyFile.
name: "caFile, certFile and keyFile",
config: &TLSConfig{
CAFile: "cafile",
CertFile: "certfile",
@ -103,7 +115,7 @@ func TestValidateTLSConfig(t *testing.T) {
err: false,
},
{
// Without CAFile.
name: "certFile and keyFile",
config: &TLSConfig{
CertFile: "certfile",
KeyFile: "keyfile",
@ -111,7 +123,7 @@ func TestValidateTLSConfig(t *testing.T) {
err: false,
},
{
// Without CertFile.
name: "caFile and keyFile",
config: &TLSConfig{
CAFile: "cafile",
KeyFile: "keyfile",
@ -119,7 +131,7 @@ func TestValidateTLSConfig(t *testing.T) {
err: true,
},
{
// Without KeyFile.
name: "caFile and certFile",
config: &TLSConfig{
CAFile: "cafile",
CertFile: "certfile",
@ -127,7 +139,7 @@ func TestValidateTLSConfig(t *testing.T) {
err: true,
},
{
// CertSecret and KeyFile.
name: "caFile, cert and keyFile",
config: &TLSConfig{
CAFile: "cafile",
KeyFile: "keyfile",
@ -138,7 +150,7 @@ func TestValidateTLSConfig(t *testing.T) {
err: false,
},
{
// CertFile and KeySecret.
name: "caFile, certFile and keySecret",
config: &TLSConfig{
CAFile: "cafile",
CertFile: "certfile",
@ -149,7 +161,7 @@ func TestValidateTLSConfig(t *testing.T) {
err: false,
},
{
// CA, Cert, and KeySecret.
name: "ca, cert and keySecret",
config: &TLSConfig{
SafeTLSConfig: SafeTLSConfig{
CA: SecretOrConfigMap{Secret: &v1.SecretKeySelector{}},
@ -160,7 +172,7 @@ func TestValidateTLSConfig(t *testing.T) {
err: false,
},
{
// Without CA and CAFile.
name: "cert and keySecret",
config: &TLSConfig{
SafeTLSConfig: SafeTLSConfig{
Cert: SecretOrConfigMap{Secret: &v1.SecretKeySelector{}},
@ -170,7 +182,7 @@ func TestValidateTLSConfig(t *testing.T) {
err: false,
},
{
// Without Cert and CertFile.
name: "ca and keySecret",
config: &TLSConfig{
SafeTLSConfig: SafeTLSConfig{
CA: SecretOrConfigMap{Secret: &v1.SecretKeySelector{}},
@ -180,7 +192,7 @@ func TestValidateTLSConfig(t *testing.T) {
err: true,
},
{
// Without KeySecret and KeyFile.
name: "ca and cert",
config: &TLSConfig{
SafeTLSConfig: SafeTLSConfig{
CA: SecretOrConfigMap{Secret: &v1.SecretKeySelector{}},
@ -190,13 +202,17 @@ func TestValidateTLSConfig(t *testing.T) {
err: true,
},
} {
t.Run("", func(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
err := tc.config.Validate()
if tc.err && err == nil {
t.Fatalf("expected validation of %+v to fail, but got no error", tc.config)
if tc.err {
if err == nil {
t.Fatal("expected error but got none")
}
return
}
if !tc.err && err != nil {
t.Fatalf("expected validation of %+v not to fail, err: %s", tc.config, err)
if err != nil {
t.Fatalf("expected no error but got: %s", err)
}
})
}
@ -265,10 +281,11 @@ func TestValidateAuthorization(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
err := tc.config.Validate()
if tc.err && err == nil {
t.Fatalf("expected validation of %+v to fail, but got no error", tc.config)
t.Fatal("expected error but got none")
}
if !tc.err && err != nil {
t.Fatalf("expected validation of %+v not to fail, err: %s", tc.config, err)
t.Fatalf("expected no error but got: %s", err)
}
})
}

View file

@ -2531,21 +2531,6 @@ func (in *SecretOrConfigMap) DeepCopy() *SecretOrConfigMap {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *SecretOrConfigMapValidationError) DeepCopyInto(out *SecretOrConfigMapValidationError) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretOrConfigMapValidationError.
func (in *SecretOrConfigMapValidationError) DeepCopy() *SecretOrConfigMapValidationError {
if in == nil {
return nil
}
out := new(SecretOrConfigMapValidationError)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ServiceMonitor) DeepCopyInto(out *ServiceMonitor) {
*out = *in
@ -2743,21 +2728,6 @@ func (in *TLSConfig) DeepCopy() *TLSConfig {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *TLSConfigValidationError) DeepCopyInto(out *TLSConfigValidationError) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TLSConfigValidationError.
func (in *TLSConfigValidationError) DeepCopy() *TLSConfigValidationError {
if in == nil {
return nil
}
out := new(TLSConfigValidationError)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *TSDBSpec) DeepCopyInto(out *TSDBSpec) {
*out = *in

View file

@ -86,29 +86,29 @@ func (s *Store) addTLSAssets(ctx context.Context, ns string, tlsConfig monitorin
ca, err = s.GetKey(ctx, ns, tlsConfig.CA)
if err != nil {
return fmt.Errorf("failed to get CA: %w", err)
return fmt.Errorf("failed to get ca %q: %w", tlsConfig.CA.String(), err)
}
cert, err = s.GetKey(ctx, ns, tlsConfig.Cert)
if err != nil {
return fmt.Errorf("failed to get cert: %w", err)
return fmt.Errorf("failed to get cert %q: %w", tlsConfig.Cert.String(), err)
}
if tlsConfig.KeySecret != nil {
key, err = s.GetSecretKey(ctx, ns, *tlsConfig.KeySecret)
if err != nil {
return fmt.Errorf("failed to get key: %w", err)
return fmt.Errorf("failed to get key %s/%s: %w", tlsConfig.KeySecret.LocalObjectReference.Name, tlsConfig.KeySecret.Key, err)
}
}
if ca != "" {
block, _ := pem.Decode([]byte(ca))
if block == nil {
return errors.New("failed to decode CA certificate")
return fmt.Errorf("ca %s: failed to decode PEM block", tlsConfig.CA.String())
}
_, err = x509.ParseCertificate(block.Bytes)
if err != nil {
return fmt.Errorf("failed to parse CA certificate: %w", err)
return fmt.Errorf("ca %s: failed to parse certificate: %w", tlsConfig.CA.String(), err)
}
s.TLSAssets[TLSAssetKeyFromSelector(ns, tlsConfig.CA)] = TLSAsset(ca)
}
@ -116,7 +116,11 @@ func (s *Store) addTLSAssets(ctx context.Context, ns string, tlsConfig monitorin
if cert != "" && key != "" {
_, err = tls.X509KeyPair([]byte(cert), []byte(key))
if err != nil {
return fmt.Errorf("failed to load X509 key pair: %w", err)
return fmt.Errorf(
"cert %s, key <%s/%s>: %w",
tlsConfig.Cert.String(),
tlsConfig.KeySecret.LocalObjectReference.Name, tlsConfig.KeySecret.Key,
err)
}
s.TLSAssets[TLSAssetKeyFromSelector(ns, tlsConfig.Cert)] = TLSAsset(cert)
s.TLSAssets[TLSAssetKeyFromSelector(ns, monitoringv1.SecretOrConfigMap{Secret: tlsConfig.KeySecret})] = TLSAsset(key)

View file

@ -320,12 +320,15 @@ func addTLStoYaml(cfg yaml.MapSlice, namespace string, tls *monitoringv1.TLSConf
}
tlsConfig := addSafeTLStoYaml(yaml.MapSlice{}, namespace, tls.SafeTLSConfig)[0].Value.(yaml.MapSlice)
if tls.CAFile != "" {
tlsConfig = append(tlsConfig, yaml.MapItem{Key: "ca_file", Value: tls.CAFile})
}
if tls.CertFile != "" {
tlsConfig = append(tlsConfig, yaml.MapItem{Key: "cert_file", Value: tls.CertFile})
}
if tls.KeyFile != "" {
tlsConfig = append(tlsConfig, yaml.MapItem{Key: "key_file", Value: tls.KeyFile})
}

View file

@ -22,7 +22,6 @@ import (
"github.com/go-kit/log"
"github.com/go-kit/log/level"
"github.com/go-openapi/swag"
"github.com/stretchr/testify/require"
"gopkg.in/yaml.v2"
"gotest.tools/v3/golden"
@ -833,7 +832,6 @@ func TestK8SSDConfigGeneration(t *testing.T) {
BasicAuth: &monitoringv1.BasicAuth{},
BearerToken: "bearer_token",
BearerTokenFile: "bearer_token_file",
TLSConfig: nil,
},
&assets.Store{
BasicAuthAssets: map[string]assets.BasicAuthCredentials{
@ -1200,7 +1198,7 @@ func TestAlertmanagerEnableHttp2(t *testing.T) {
Namespace: "default",
Port: intstr.FromString("web"),
APIVersion: "v2",
EnableHttp2: swag.Bool(tc.enableHTTP2),
EnableHttp2: ptr.To(tc.enableHTTP2),
},
},
}
@ -1816,7 +1814,7 @@ func TestSettingHonorTimestampsInServiceMonitor(t *testing.T) {
TargetLabels: []string{"example", "env"},
Endpoints: []monitoringv1.Endpoint{
{
HonorTimestamps: swag.Bool(false),
HonorTimestamps: ptr.To(false),
Port: "web",
Interval: "30s",
},
@ -1861,7 +1859,7 @@ func TestSettingHonorTimestampsInPodMonitor(t *testing.T) {
PodTargetLabels: []string{"example", "env"},
PodMetricsEndpoints: []monitoringv1.PodMetricsEndpoint{
{
HonorTimestamps: swag.Bool(false),
HonorTimestamps: ptr.To(false),
Port: "web",
Interval: "30s",
},
@ -1904,7 +1902,7 @@ func TestSettingTrackTimestampsStalenessInServiceMonitor(t *testing.T) {
TargetLabels: []string{"example", "env"},
Endpoints: []monitoringv1.Endpoint{
{
TrackTimestampsStaleness: swag.Bool(false),
TrackTimestampsStaleness: ptr.To(false),
Port: "web",
Interval: "30s",
},
@ -1949,7 +1947,7 @@ func TestSettingTrackTimestampsStalenessInPodMonitor(t *testing.T) {
PodTargetLabels: []string{"example", "env"},
PodMetricsEndpoints: []monitoringv1.PodMetricsEndpoint{
{
TrackTimestampsStaleness: swag.Bool(false),
TrackTimestampsStaleness: ptr.To(false),
Port: "web",
Interval: "30s",
},
@ -1993,7 +1991,7 @@ func TestHonorTimestampsOverriding(t *testing.T) {
TargetLabels: []string{"example", "env"},
Endpoints: []monitoringv1.Endpoint{
{
HonorTimestamps: swag.Bool(true),
HonorTimestamps: ptr.To(true),
Port: "web",
Interval: "30s",
},
@ -2945,22 +2943,22 @@ func TestHonorTimestamps(t *testing.T) {
Expected: "{}\n",
},
{
UserHonorTimestamps: swag.Bool(false),
UserHonorTimestamps: ptr.To(false),
OverrideHonorTimestamps: true,
Expected: "honor_timestamps: false\n",
},
{
UserHonorTimestamps: swag.Bool(false),
UserHonorTimestamps: ptr.To(false),
OverrideHonorTimestamps: false,
Expected: "honor_timestamps: false\n",
},
{
UserHonorTimestamps: swag.Bool(true),
UserHonorTimestamps: ptr.To(true),
OverrideHonorTimestamps: true,
Expected: "honor_timestamps: false\n",
},
{
UserHonorTimestamps: swag.Bool(true),
UserHonorTimestamps: ptr.To(true),
OverrideHonorTimestamps: false,
Expected: "honor_timestamps: true\n",
},
@ -2995,11 +2993,11 @@ func TestTrackTimestampsStaleness(t *testing.T) {
Expected: "{}\n",
},
{
UserTrackTimestampsStaleness: swag.Bool(false),
UserTrackTimestampsStaleness: ptr.To(false),
Expected: "track_timestamps_staleness: false\n",
},
{
UserTrackTimestampsStaleness: swag.Bool(true),
UserTrackTimestampsStaleness: ptr.To(true),
Expected: "track_timestamps_staleness: true\n",
},
}
@ -4329,7 +4327,7 @@ func TestServiceMonitorEndpointFollowRedirects(t *testing.T) {
{
Port: "web",
Interval: "30s",
FollowRedirects: swag.Bool(tc.followRedirects),
FollowRedirects: ptr.To(tc.followRedirects),
},
},
},
@ -4407,7 +4405,7 @@ func TestPodMonitorEndpointFollowRedirects(t *testing.T) {
{
Port: "web",
Interval: "30s",
FollowRedirects: swag.Bool(tc.followRedirects),
FollowRedirects: ptr.To(tc.followRedirects),
},
},
},
@ -4486,7 +4484,7 @@ func TestServiceMonitorEndpointEnableHttp2(t *testing.T) {
{
Port: "web",
Interval: "30s",
EnableHttp2: swag.Bool(tc.enableHTTP2),
EnableHttp2: ptr.To(tc.enableHTTP2),
},
},
},
@ -4546,7 +4544,7 @@ func TestPodMonitorPhaseFilter(t *testing.T) {
Spec: monitoringv1.PodMonitorSpec{
PodMetricsEndpoints: []monitoringv1.PodMetricsEndpoint{
{
FilterRunning: swag.Bool(false),
FilterRunning: ptr.To(false),
Port: "test",
},
},
@ -4609,7 +4607,7 @@ func TestPodMonitorEndpointEnableHttp2(t *testing.T) {
{
Port: "web",
Interval: "30s",
EnableHttp2: swag.Bool(tc.enableHTTP2),
EnableHttp2: ptr.To(tc.enableHTTP2),
},
},
},

View file

@ -136,10 +136,8 @@ func (rs *ResourceSelector) SelectServiceMonitors(ctx context.Context, listFn Li
break
}
if endpoint.TLSConfig != nil {
if err = rs.store.AddTLSConfig(ctx, sm.GetNamespace(), endpoint.TLSConfig); err != nil {
break
}
if err = rs.store.AddTLSConfig(ctx, sm.GetNamespace(), endpoint.TLSConfig); err != nil {
break
}
if err = rs.store.AddOAuth2(ctx, sm.GetNamespace(), endpoint.OAuth2, smKey); err != nil {

View file

@ -698,6 +698,15 @@ func TestValidateScrapeIntervalAndTimeout(t *testing.T) {
}
func TestSelectServiceMonitors(t *testing.T) {
ca, err := os.ReadFile("../../test/e2e/remote_write_certs/ca.crt")
require.NoError(t, err)
cert, err := os.ReadFile("../../test/e2e/remote_write_certs/client.crt")
require.NoError(t, err)
key, err := os.ReadFile("../../test/e2e/remote_write_certs/client.key")
require.NoError(t, err)
for _, tc := range []struct {
scenario string
updateSpec func(*monitoringv1.ServiceMonitorSpec)
@ -763,12 +772,202 @@ func TestSelectServiceMonitors(t *testing.T) {
},
selected: false,
},
{
scenario: "valid TLS config with CA, cert and key",
updateSpec: func(sm *monitoringv1.ServiceMonitorSpec) {
sm.Endpoints = append(sm.Endpoints, monitoringv1.Endpoint{
TLSConfig: &monitoringv1.TLSConfig{
SafeTLSConfig: monitoringv1.SafeTLSConfig{
CA: monitoringv1.SecretOrConfigMap{
Secret: &v1.SecretKeySelector{
Key: "ca",
LocalObjectReference: v1.LocalObjectReference{
Name: "secret",
},
},
},
Cert: monitoringv1.SecretOrConfigMap{
Secret: &v1.SecretKeySelector{
Key: "cert",
LocalObjectReference: v1.LocalObjectReference{
Name: "secret",
},
},
},
KeySecret: &v1.SecretKeySelector{
Key: "key",
LocalObjectReference: v1.LocalObjectReference{
Name: "secret",
},
},
},
},
})
},
selected: true,
},
{
scenario: "invalid TLS config with both CA and CAFile",
updateSpec: func(sm *monitoringv1.ServiceMonitorSpec) {
sm.Endpoints = append(sm.Endpoints, monitoringv1.Endpoint{
TLSConfig: &monitoringv1.TLSConfig{
CAFile: "/etc/secrets/tls/ca.crt",
SafeTLSConfig: monitoringv1.SafeTLSConfig{
CA: monitoringv1.SecretOrConfigMap{
Secret: &v1.SecretKeySelector{
Key: "ca",
LocalObjectReference: v1.LocalObjectReference{
Name: "secret",
},
},
},
},
},
})
},
selected: false,
},
{
scenario: "invalid TLS config with both CA Secret and Configmap",
updateSpec: func(sm *monitoringv1.ServiceMonitorSpec) {
sm.Endpoints = append(sm.Endpoints, monitoringv1.Endpoint{
TLSConfig: &monitoringv1.TLSConfig{
SafeTLSConfig: monitoringv1.SafeTLSConfig{
CA: monitoringv1.SecretOrConfigMap{
Secret: &v1.SecretKeySelector{
Key: "ca",
LocalObjectReference: v1.LocalObjectReference{
Name: "secret",
},
},
ConfigMap: &v1.ConfigMapKeySelector{
Key: "ca",
LocalObjectReference: v1.LocalObjectReference{
Name: "configmap",
},
},
},
},
},
})
},
selected: false,
},
{
scenario: "invalid TLS config with invalid CA data",
updateSpec: func(sm *monitoringv1.ServiceMonitorSpec) {
sm.Endpoints = append(sm.Endpoints, monitoringv1.Endpoint{
TLSConfig: &monitoringv1.TLSConfig{
SafeTLSConfig: monitoringv1.SafeTLSConfig{
CA: monitoringv1.SecretOrConfigMap{
Secret: &v1.SecretKeySelector{
Key: "invalid_ca",
LocalObjectReference: v1.LocalObjectReference{
Name: "secret",
},
},
},
},
},
})
},
selected: false,
},
{
scenario: "invalid TLS config with cert and missing key",
updateSpec: func(sm *monitoringv1.ServiceMonitorSpec) {
sm.Endpoints = append(sm.Endpoints, monitoringv1.Endpoint{
TLSConfig: &monitoringv1.TLSConfig{
SafeTLSConfig: monitoringv1.SafeTLSConfig{
Cert: monitoringv1.SecretOrConfigMap{
Secret: &v1.SecretKeySelector{
Key: "cert",
LocalObjectReference: v1.LocalObjectReference{
Name: "secret",
},
},
},
},
},
})
},
selected: false,
},
{
scenario: "invalid TLS config with key and missing cert",
updateSpec: func(sm *monitoringv1.ServiceMonitorSpec) {
sm.Endpoints = append(sm.Endpoints, monitoringv1.Endpoint{
TLSConfig: &monitoringv1.TLSConfig{
SafeTLSConfig: monitoringv1.SafeTLSConfig{
KeySecret: &v1.SecretKeySelector{
Key: "key",
LocalObjectReference: v1.LocalObjectReference{
Name: "secret",
},
},
},
},
})
},
selected: false,
},
{
scenario: "invalid TLS config with key and invalid cert",
updateSpec: func(sm *monitoringv1.ServiceMonitorSpec) {
sm.Endpoints = append(sm.Endpoints, monitoringv1.Endpoint{
TLSConfig: &monitoringv1.TLSConfig{
SafeTLSConfig: monitoringv1.SafeTLSConfig{
Cert: monitoringv1.SecretOrConfigMap{
Secret: &v1.SecretKeySelector{
Key: "invalid_ca",
LocalObjectReference: v1.LocalObjectReference{
Name: "secret",
},
},
},
KeySecret: &v1.SecretKeySelector{
Key: "key",
LocalObjectReference: v1.LocalObjectReference{
Name: "secret",
},
},
},
},
})
},
selected: false,
},
} {
t.Run(tc.scenario, func(t *testing.T) {
cs := fake.NewSimpleClientset(
&v1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: "secret",
Namespace: "test",
},
Data: map[string][]byte{
"ca": ca,
"invalid_ca": []byte("garbage"),
"cert": cert,
"key": key,
},
},
&v1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: "configmap",
Namespace: "test",
},
Data: map[string]string{
"ca": string(ca),
"cert": string(cert),
},
},
)
rs := NewResourceSelector(
newLogger(),
&monitoringv1.Prometheus{},
nil,
assets.NewStore(cs.CoreV1(), cs.CoreV1()),
nil,
operator.NewMetrics(prometheus.NewPedanticRegistry()),
)