Skip to content

Commit 7f19b89

Browse files
zhujian7claude
andauthored
⚠️ Update CSR interfaces to support enhanced context and error handling (#333)
* Update CSRSign interface to support cluster and addon context Changes CSRSignerFunc signature to include ManagedCluster and ManagedClusterAddOn parameters and return error, enabling CSR signers to make context-aware decisions based on cluster and addon information. Migration guide: - Old: CSRSign: func(csr *certificatesv1.CertificateSigningRequest) []byte - New: CSRSign: func(cluster *clusterv1.ManagedCluster, addon *addonapiv1alpha1.ManagedClusterAddOn, csr *certificatesv1.CertificateSigningRequest) ([]byte, error) Update your CSRSign implementations to: 1. Add cluster and addon parameters (can be ignored if not needed) 2. Return ([]byte, error) instead of just []byte 3. Handle errors properly in your signing logic 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]> Signed-off-by: zhujian <[email protected]> * Update CSRConfigurations interface to return error Changes CSRConfigurationsFunc signature to return ([]RegistrationConfig, error) instead of just []RegistrationConfig, enabling better error handling in CSR configuration generation. Migration guide: - Old: CSRConfigurations: func(cluster *clusterv1.ManagedCluster) []addonapiv1alpha1.RegistrationConfig - New: CSRConfigurations: func(cluster *clusterv1.ManagedCluster) ([]addonapiv1alpha1.RegistrationConfig, error) Update your CSRConfigurations implementations to: 1. Return ([]RegistrationConfig, error) instead of just []RegistrationConfig 2. Return nil error for successful cases 3. Return appropriate errors when configuration generation fails 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]> Signed-off-by: zhujian <[email protected]> * Update CSRConfigurations to include addon parameter and improve error handling Enhances CSRConfigurationsFunc to accept ManagedClusterAddOn parameter alongside ManagedCluster, enabling addon-specific CSR configuration decisions. Also improves error message formatting in CSR signing. Migration guide: - Old: CSRConfigurations: func(cluster *clusterv1.ManagedCluster) ([]RegistrationConfig, error) - New: CSRConfigurations: func(cluster *clusterv1.ManagedCluster, addon *addonapiv1alpha1.ManagedClusterAddOn) ([]RegistrationConfig, error) Update your CSRConfigurations implementations to: 1. Accept both cluster and addon parameters 2. Use addon parameter for addon-specific configuration logic when needed 3. Ignore addon parameter if not needed for your use case 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]> Signed-off-by: zhujian <[email protected]> --------- Signed-off-by: zhujian <[email protected]> Co-authored-by: Claude <[email protected]>
1 parent d42007a commit 7f19b89

File tree

9 files changed

+55
-37
lines changed

9 files changed

+55
-37
lines changed

pkg/addonmanager/controllers/certificate/csrsign.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,15 +116,15 @@ func (c *csrSignController) sync(ctx context.Context, syncCtx factory.SyncContex
116116
}
117117

118118
// Get ManagedCluster
119-
_, err = c.managedClusterLister.Get(clusterName)
119+
cluster, err := c.managedClusterLister.Get(clusterName)
120120
if errors.IsNotFound(err) {
121121
return nil
122122
}
123123
if err != nil {
124124
return err
125125
}
126126

127-
_, err = c.managedClusterAddonLister.ManagedClusterAddOns(clusterName).Get(addonName)
127+
addon, err := c.managedClusterAddonLister.ManagedClusterAddOns(clusterName).Get(addonName)
128128
if errors.IsNotFound(err) {
129129
return nil
130130
}
@@ -136,7 +136,10 @@ func (c *csrSignController) sync(ctx context.Context, syncCtx factory.SyncContex
136136
return nil
137137
}
138138

139-
csr.Status.Certificate = registrationOption.CSRSign(csr)
139+
csr.Status.Certificate, err = registrationOption.CSRSign(cluster, addon, csr)
140+
if err != nil {
141+
return fmt.Errorf("failed to sign addon csr %q: %v", csr.Name, err)
142+
}
140143
if len(csr.Status.Certificate) == 0 {
141144
return fmt.Errorf("invalid client certificate generated for addon csr %q", csr.Name)
142145
}

pkg/addonmanager/controllers/certificate/csrsign_test.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,9 @@ func (t *testSignAgent) GetAgentAddonOptions() agent.AgentAddonOptions {
3434
return agent.AgentAddonOptions{
3535
AddonName: t.name,
3636
Registration: &agent.RegistrationOption{
37-
CSRSign: func(csr *certv1.CertificateSigningRequest) []byte {
38-
return t.cert
37+
CSRSign: func(cluster *clusterv1.ManagedCluster, addon *addonapiv1alpha1.ManagedClusterAddOn,
38+
csr *certv1.CertificateSigningRequest) ([]byte, error) {
39+
return t.cert, nil
3940
},
4041
},
4142
}

pkg/addonmanager/controllers/registration/controller.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,10 @@ func (c *addonRegistrationController) sync(ctx context.Context, syncCtx factory.
163163
return err
164164
}
165165

166-
configs := registrationOption.CSRConfigurations(managedCluster)
166+
configs, err := registrationOption.CSRConfigurations(managedCluster, managedClusterAddonCopy)
167+
if err != nil {
168+
return fmt.Errorf("get csr configurations failed: %v", err)
169+
}
167170
managedClusterAddonCopy.Status.Registrations = configs
168171

169172
var agentInstallNamespace string

pkg/addonmanager/controllers/registration/controller_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ func (t *testAgent) GetAgentAddonOptions() agent.AgentAddonOptions {
4242
agentOption := agent.AgentAddonOptions{
4343
AddonName: t.name,
4444
Registration: &agent.RegistrationOption{
45-
CSRConfigurations: func(cluster *clusterv1.ManagedCluster) []addonapiv1alpha1.RegistrationConfig {
46-
return t.registrations
45+
CSRConfigurations: func(cluster *clusterv1.ManagedCluster, addon *addonapiv1alpha1.ManagedClusterAddOn) ([]addonapiv1alpha1.RegistrationConfig, error) {
46+
return t.registrations, nil
4747
},
4848
PermissionConfig: func(cluster *clusterv1.ManagedCluster, addon *addonapiv1alpha1.ManagedClusterAddOn) error {
4949
return nil

pkg/agent/inteface.go

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -98,12 +98,19 @@ type AgentAddonOptions struct {
9898
ConfigCheckEnabled bool
9999
}
100100

101-
type CSRSignerFunc func(csr *certificatesv1.CertificateSigningRequest) []byte
101+
type CSRConfigurationsFunc func(cluster *clusterv1.ManagedCluster,
102+
addon *addonapiv1alpha1.ManagedClusterAddOn) ([]addonapiv1alpha1.RegistrationConfig, error)
102103

103-
type CSRApproveFunc func(cluster *clusterv1.ManagedCluster, addon *addonapiv1alpha1.ManagedClusterAddOn, csr *certificatesv1.CertificateSigningRequest) bool
104+
type CSRSignerFunc func(cluster *clusterv1.ManagedCluster,
105+
addon *addonapiv1alpha1.ManagedClusterAddOn, csr *certificatesv1.CertificateSigningRequest) ([]byte, error)
106+
107+
type CSRApproveFunc func(cluster *clusterv1.ManagedCluster,
108+
addon *addonapiv1alpha1.ManagedClusterAddOn, csr *certificatesv1.CertificateSigningRequest) bool
104109

105110
type PermissionConfigFunc func(cluster *clusterv1.ManagedCluster, addon *addonapiv1alpha1.ManagedClusterAddOn) error
106111

112+
type AgentInstallNamespaceFunc func(addon *addonapiv1alpha1.ManagedClusterAddOn) (string, error)
113+
107114
// RegistrationOption defines how agent is registered to the hub cluster. It needs to define:
108115
// 1. csr with what subject/signer should be created
109116
// 2. how csr is approved
@@ -113,7 +120,7 @@ type RegistrationOption struct {
113120
// CSRConfigurations returns a list of csr configuration for the adddon agent in a managed cluster.
114121
// A csr will be created from the managed cluster for addon agent with each CSRConfiguration.
115122
// +required
116-
CSRConfigurations func(cluster *clusterv1.ManagedCluster) []addonapiv1alpha1.RegistrationConfig
123+
CSRConfigurations CSRConfigurationsFunc
117124

118125
// Namespace is the namespace where registraiton credential will be put on the managed cluster. It
119126
// will be overridden by installNamespace on ManagedClusterAddon spec if set
@@ -125,7 +132,7 @@ type RegistrationOption struct {
125132
// Note: Set this very carefully. If this is set, the addon agent must be deployed in the same namespace, which
126133
// means when implementing Manifests function in AgentAddon interface, the namespace of the addon agent manifest
127134
// must be set to the same value returned by this function.
128-
AgentInstallNamespace func(addon *addonapiv1alpha1.ManagedClusterAddOn) (string, error)
135+
AgentInstallNamespace AgentInstallNamespaceFunc
129136

130137
// CSRApproveCheck checks whether the addon agent registration should be approved by the hub.
131138
// Addon hub controller can implement this func to auto-approve all the CSRs. A better CSR check is
@@ -231,8 +238,9 @@ const (
231238
HealthProberTypeWorkloadAvailability HealthProberType = "WorkloadAvailability"
232239
)
233240

234-
func KubeClientSignerConfigurations(addonName, agentName string) func(cluster *clusterv1.ManagedCluster) []addonapiv1alpha1.RegistrationConfig {
235-
return func(cluster *clusterv1.ManagedCluster) []addonapiv1alpha1.RegistrationConfig {
241+
func KubeClientSignerConfigurations(addonName, agentName string) CSRConfigurationsFunc {
242+
return func(cluster *clusterv1.ManagedCluster,
243+
addon *addonapiv1alpha1.ManagedClusterAddOn) ([]addonapiv1alpha1.RegistrationConfig, error) {
236244
return []addonapiv1alpha1.RegistrationConfig{
237245
{
238246
SignerName: certificatesv1.KubeAPIServerClientSignerName,
@@ -241,7 +249,7 @@ func KubeClientSignerConfigurations(addonName, agentName string) func(cluster *c
241249
Groups: DefaultGroups(cluster.Name, addonName),
242250
},
243251
},
244-
}
252+
}, nil
245253
}
246254
}
247255

pkg/utils/csr_helper_test.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,10 @@ func TestDefaultSigner(t *testing.T) {
6464

6565
signer := DefaultSignerWithExpiry(key, ca, 24*time.Hour)
6666

67-
cert := signer(newCSR("test", "cluster1"))
67+
cert, err := signer(nil, nil, newCSR("test", "cluster1"))
68+
if err != nil {
69+
t.Errorf("Failed to sign the csr, %v", err)
70+
}
6871
if cert == nil {
6972
t.Errorf("Expect cert to be signed")
7073
}

pkg/utils/csr_helpers.go

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,38 +30,34 @@ var serialNumberLimit = new(big.Int).Lsh(big.NewInt(1), 128)
3030

3131
// DefaultSignerWithExpiry generates a signer func for addon agent to sign the csr using caKey and caData with expiry date.
3232
func DefaultSignerWithExpiry(caKey, caData []byte, duration time.Duration) agent.CSRSignerFunc {
33-
return func(csr *certificatesv1.CertificateSigningRequest) []byte {
33+
return func(cluster *clusterv1.ManagedCluster, addon *addonapiv1alpha1.ManagedClusterAddOn,
34+
csr *certificatesv1.CertificateSigningRequest) ([]byte, error) {
3435
blockTlsCrt, _ := pem.Decode(caData)
3536
if blockTlsCrt == nil {
36-
klog.Errorf("Failed to decode cert")
37-
return nil
37+
return nil, fmt.Errorf("failed to decode cert")
3838
}
3939
certs, err := x509.ParseCertificates(blockTlsCrt.Bytes)
4040
if err != nil {
41-
klog.Errorf("Failed to parse cert: %v", err)
42-
return nil
41+
return nil, fmt.Errorf("failed to parse cert: %v", err)
4342
}
4443

4544
blockTlsKey, _ := pem.Decode(caKey)
4645
if blockTlsKey == nil {
47-
klog.Errorf("Failed to decode key")
48-
return nil
46+
return nil, fmt.Errorf("failed to decode key")
4947
}
5048

5149
// For now only PKCS#1 is supported which assures the private key algorithm is RSA.
5250
// TODO: Compatibility w/ PKCS#8 key e.g. EC algorithm
5351
key, err := x509.ParsePKCS1PrivateKey(blockTlsKey.Bytes)
5452
if err != nil {
55-
klog.Errorf("Failed to parse key: %v", err)
56-
return nil
53+
return nil, fmt.Errorf("failed to parse key: %v", err)
5754
}
5855

5956
data, err := signCSR(csr, certs[0], key, duration)
6057
if err != nil {
61-
klog.Errorf("Failed to sign csr: %v", err)
62-
return nil
58+
return nil, fmt.Errorf("failed to sign csr: %v", err)
6359
}
64-
return data
60+
return data, nil
6561
}
6662
}
6763

test/integration/cloudevents/suite_test.go

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,14 @@ package cloudevents
33
import (
44
"context"
55
"fmt"
6-
"open-cluster-management.io/sdk-go/pkg/cloudevents/clients/options"
76
"os"
87
"path"
98
"path/filepath"
109
"testing"
1110
"time"
1211

12+
"open-cluster-management.io/sdk-go/pkg/cloudevents/clients/options"
13+
1314
mochimqtt "github.com/mochi-mqtt/server/v2"
1415
"github.com/mochi-mqtt/server/v2/hooks/auth"
1516
"github.com/mochi-mqtt/server/v2/listeners"
@@ -231,14 +232,15 @@ func (t *testAddon) GetAgentAddonOptions() agent.AgentAddonOptions {
231232

232233
if len(t.registrations) > 0 {
233234
option.Registration = &agent.RegistrationOption{
234-
CSRConfigurations: func(cluster *clusterv1.ManagedCluster) []addonapiv1alpha1.RegistrationConfig {
235-
return t.registrations[cluster.Name]
235+
CSRConfigurations: func(cluster *clusterv1.ManagedCluster, addon *addonapiv1alpha1.ManagedClusterAddOn) ([]addonapiv1alpha1.RegistrationConfig, error) {
236+
return t.registrations[cluster.Name], nil
236237
},
237238
CSRApproveCheck: func(cluster *clusterv1.ManagedCluster, addon *addonapiv1alpha1.ManagedClusterAddOn, csr *certificatesv1.CertificateSigningRequest) bool {
238239
return t.approveCSR
239240
},
240-
CSRSign: func(csr *certificatesv1.CertificateSigningRequest) []byte {
241-
return t.cert
241+
CSRSign: func(cluster *clusterv1.ManagedCluster, addon *addonapiv1alpha1.ManagedClusterAddOn,
242+
csr *certificatesv1.CertificateSigningRequest) ([]byte, error) {
243+
return t.cert, nil
242244
},
243245
}
244246
}

test/integration/kube/suite_test.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -165,14 +165,16 @@ func (t *testAddon) GetAgentAddonOptions() agent.AgentAddonOptions {
165165

166166
if len(t.registrations) > 0 {
167167
option.Registration = &agent.RegistrationOption{
168-
CSRConfigurations: func(cluster *clusterv1.ManagedCluster) []addonapiv1alpha1.RegistrationConfig {
169-
return t.registrations[cluster.Name]
168+
CSRConfigurations: func(cluster *clusterv1.ManagedCluster,
169+
addon *addonapiv1alpha1.ManagedClusterAddOn) ([]addonapiv1alpha1.RegistrationConfig, error) {
170+
return t.registrations[cluster.Name], nil
170171
},
171172
CSRApproveCheck: func(cluster *clusterv1.ManagedCluster, addon *addonapiv1alpha1.ManagedClusterAddOn, csr *certificatesv1.CertificateSigningRequest) bool {
172173
return t.approveCSR
173174
},
174-
CSRSign: func(csr *certificatesv1.CertificateSigningRequest) []byte {
175-
return t.cert
175+
CSRSign: func(cluster *clusterv1.ManagedCluster, addon *addonapiv1alpha1.ManagedClusterAddOn,
176+
csr *certificatesv1.CertificateSigningRequest) ([]byte, error) {
177+
return t.cert, nil
176178
},
177179
}
178180
}

0 commit comments

Comments
 (0)