Skip to content

Commit

Permalink
[ACM-10269] Stamp CSR's organization units with the hash of the CA bu…
Browse files Browse the repository at this point in the history
…ndle (stolostron#1464)

* Stamp the observability addon CSR with the hash of the CA

Signed-off-by: Douglas Camata <[email protected]>

* Stamp all CSR with the hash of the CA

Signed-off-by: Douglas Camata <[email protected]>

* Adds certs test helpers

Signed-off-by: Douglas Camata <[email protected]>

* Go mod tidy

Signed-off-by: Douglas Camata <[email protected]>

* Add missing copyright notice

Signed-off-by: Douglas Camata <[email protected]>

---------

Signed-off-by: Douglas Camata <[email protected]>
Signed-off-by: Periklis Tsirakidis <[email protected]>
  • Loading branch information
douglascamata authored and periklis committed Jun 10, 2024
1 parent 375b31f commit fc06fb1
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 16 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ require (
github.com/openshift/client-go v0.0.0-20230120202327-72f107311084
github.com/openshift/cluster-monitoring-operator v0.0.0-20230118025836-20fcb9f6ef4e
github.com/openshift/hypershift v0.1.11
github.com/openshift/library-go v0.0.0-20230120214501-9bc305884fcb
github.com/prometheus-community/prom-label-proxy v0.6.0
github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.58.0
github.com/prometheus-operator/prometheus-operator/pkg/client v0.53.1
Expand Down Expand Up @@ -116,7 +117,6 @@ require (
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f // indirect
github.com/nxadm/tail v1.4.8 // indirect
github.com/oklog/ulid v1.3.1 // indirect
github.com/openshift/library-go v0.0.0-20230120214501-9bc305884fcb // indirect
github.com/opentracing/opentracing-go v1.2.0 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
Expand Down
25 changes: 21 additions & 4 deletions operators/multiclusterobservability/pkg/certificates/cert_agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@
package certificates

import (
"crypto/sha256"
"fmt"

"k8s.io/apimachinery/pkg/runtime"
"sigs.k8s.io/controller-runtime/pkg/client"

"open-cluster-management.io/addon-framework/pkg/agent"
addonapiv1alpha1 "open-cluster-management.io/api/addon/v1alpha1"
Expand All @@ -17,7 +21,9 @@ const (
agentName = "observability"
)

type ObservabilityAgent struct{}
type ObservabilityAgent struct {
client client.Client
}

func (o *ObservabilityAgent) Manifests(
cluster *clusterv1.ManagedCluster,
Expand All @@ -30,7 +36,7 @@ func (o *ObservabilityAgent) GetAgentAddonOptions() agent.AgentAddonOptions {
return agent.AgentAddonOptions{
AddonName: addonName,
Registration: &agent.RegistrationOption{
CSRConfigurations: observabilitySignerConfigurations(),
CSRConfigurations: observabilitySignerConfigurations(o.client),
CSRApproveCheck: approve,
PermissionConfig: func(cluster *clusterv1.ManagedCluster, addon *addonapiv1alpha1.ManagedClusterAddOn) error {
return nil
Expand All @@ -40,7 +46,7 @@ func (o *ObservabilityAgent) GetAgentAddonOptions() agent.AgentAddonOptions {
}
}

func observabilitySignerConfigurations() func(cluster *clusterv1.ManagedCluster) []addonapiv1alpha1.RegistrationConfig {
func observabilitySignerConfigurations(client client.Client) func(cluster *clusterv1.ManagedCluster) []addonapiv1alpha1.RegistrationConfig {
return func(cluster *clusterv1.ManagedCluster) []addonapiv1alpha1.RegistrationConfig {
observabilityConfig := addonapiv1alpha1.RegistrationConfig{
SignerName: "open-cluster-management.io/observability-signer",
Expand All @@ -49,6 +55,17 @@ func observabilitySignerConfigurations() func(cluster *clusterv1.ManagedCluster)
OrganizationUnits: []string{"acm"},
},
}
return append(agent.KubeClientSignerConfigurations(addonName, agentName)(cluster), observabilityConfig)
kubeClientSignerConfigurations := agent.KubeClientSignerConfigurations(addonName, agentName)
registrationConfigs := append(kubeClientSignerConfigurations(cluster), observabilityConfig)

_, _, caCertBytes, err := getCA(client, true)
if err == nil {
caHashStamp := fmt.Sprintf("ca-hash-%x", sha256.Sum256(caCertBytes))
for i := range registrationConfigs {
registrationConfigs[i].Subject.OrganizationUnits = append(registrationConfigs[i].Subject.OrganizationUnits, caHashStamp)
}
}

return registrationConfigs
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,45 @@
package certificates

import (
"crypto/sha256"
"fmt"
"testing"
"time"

"github.com/stretchr/testify/assert"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"open-cluster-management.io/api/addon/v1alpha1"
"sigs.k8s.io/controller-runtime/pkg/client/fake"

clusterv1 "open-cluster-management.io/api/cluster/v1"

"github.com/stolostron/multicluster-observability-operator/operators/multiclusterobservability/pkg/config"
)

func TestCertAgent(t *testing.T) {
agent := &ObservabilityAgent{}
cert, key, err := NewSigningCertKeyPair("testing-mco", 365*24*time.Hour)
if err != nil {
t.Fatal(err)
}

caSecret := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: serverCACerts,
Namespace: config.GetDefaultNamespace(),
},
Data: map[string][]byte{
"tls.crt": cert,
"tls.key": key,
},
}

scheme := runtime.NewScheme()
scheme.AddKnownTypes(corev1.SchemeGroupVersion, &corev1.Secret{})
client := fake.NewClientBuilder().WithScheme(scheme).WithRuntimeObjects(caSecret).Build()

agent := &ObservabilityAgent{client: client}
agent.Manifests(nil, nil)
options := agent.GetAgentAddonOptions()
cluster := &clusterv1.ManagedCluster{
Expand All @@ -22,7 +52,34 @@ func TestCertAgent(t *testing.T) {
},
}
configs := options.Registration.CSRConfigurations(cluster)
if len(configs) != 2 {
t.Fatal("Wrong CSRConfigurations")
expectedCSRs := 2
if len(configs) != expectedCSRs {
t.Fatalf("expected %d CSRs, found %d", expectedCSRs, len(configs))
}

caHashOrgUnit := fmt.Sprintf("ca-hash-%x", sha256.Sum256(cert))

kubeAPISignerExpectedRegConfig := v1alpha1.RegistrationConfig{
SignerName: "kubernetes.io/kube-apiserver-client",
Subject: v1alpha1.Subject{
User: "system:open-cluster-management:cluster:test:addon:observability-controller:agent:observability",
Groups: []string{
"system:open-cluster-management:cluster:test:addon:observability-controller",
"system:open-cluster-management:addon:observability-controller",
"system:authenticated",
},
OrganizationUnits: []string{caHashOrgUnit},
},
}
assert.Contains(t, configs, kubeAPISignerExpectedRegConfig)

obsSignerExpectedRegConfig := v1alpha1.RegistrationConfig{
SignerName: "open-cluster-management.io/observability-signer",
Subject: v1alpha1.Subject{
User: "managed-cluster-observability",
Groups: nil,
OrganizationUnits: []string{"acm", caHashOrgUnit},
},
}
assert.Contains(t, configs, obsSignerExpectedRegConfig)
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@ import (
"reflect"
"time"

operatorconfig "github.com/stolostron/multicluster-observability-operator/operators/pkg/config"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"open-cluster-management.io/addon-framework/pkg/addonmanager"

operatorconfig "github.com/stolostron/multicluster-observability-operator/operators/pkg/config"

"golang.org/x/exp/slices"
appv1 "k8s.io/api/apps/v1"
Expand All @@ -27,8 +29,6 @@ import (
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"

"open-cluster-management.io/addon-framework/pkg/addonmanager"

mcov1beta2 "github.com/stolostron/multicluster-observability-operator/operators/multiclusterobservability/api/v1beta2"
"github.com/stolostron/multicluster-observability-operator/operators/multiclusterobservability/pkg/config"
)
Expand All @@ -55,7 +55,7 @@ func Start(c client.Client, ingressCtlCrdExists bool) {
log.Error(err, "Failed to init addon manager")
os.Exit(1)
}
agent := &ObservabilityAgent{}
agent := &ObservabilityAgent{client: c}
err = addonMgr.AddAgent(agent)
if err != nil {
log.Error(err, "Failed to add agent for addon manager")
Expand Down Expand Up @@ -84,10 +84,8 @@ func Start(c client.Client, ingressCtlCrdExists bool) {
&v1.Secret{},
time.Minute*60,
cache.ResourceEventHandlerFuncs{
AddFunc: onAdd(c),

AddFunc: onAdd(c),
DeleteFunc: onDelete(c),

UpdateFunc: onUpdate(c, ingressCtlCrdExists),
},
)
Expand Down Expand Up @@ -246,7 +244,7 @@ func onUpdate(c client.Client, ingressCtlCrdExists bool) func(oldObj, newObj int
}
case name == hubMetricsCollectorMtlsCert:
// ACM 8509: Special case for hub metrics collector
//Delete the MTLS secret and the placement controller will reconcile to create a new one
// Delete the MTLS secret and the placement controller will reconcile to create a new one
HubMtlsSecret := &v1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: operatorconfig.HubMetricsCollectorMtlsCert,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright (c) Red Hat, Inc.
// Copyright Contributors to the Open Cluster Management project
// Licensed under the Apache License 2.0

package certificates

import (
"bytes"
"time"

"github.com/openshift/library-go/pkg/crypto"
)

func NewSigningCertKeyPair(signerName string, validity time.Duration) (certData, keyData []byte, err error) {
ca, err := crypto.MakeSelfSignedCAConfigForDuration(signerName, validity)
if err != nil {
return nil, nil, err
}

certBytes := &bytes.Buffer{}
keyBytes := &bytes.Buffer{}
if err := ca.WriteCertConfig(certBytes, keyBytes); err != nil {
return nil, nil, err
}

return certBytes.Bytes(), keyBytes.Bytes(), nil
}

0 comments on commit fc06fb1

Please sign in to comment.