Skip to content

Commit b86eb72

Browse files
Further removed unnecessary stuff
1 parent c1a28ce commit b86eb72

File tree

5 files changed

+197
-62
lines changed

5 files changed

+197
-62
lines changed

azure/scope/azure_secret_cloud.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"path/filepath"
1111
"strings"
1212
"sync"
13+
"time"
1314

1415
"github.com/Azure/azure-sdk-for-go/sdk/azcore"
1516
"github.com/Azure/azure-sdk-for-go/sdk/azcore/arm"
@@ -120,10 +121,14 @@ func updateGlobalTransportLocked(certData []byte) error {
120121
// No custom certificate, use system defaults
121122
globalCertPool = nil
122123
globalTransport = &http.Transport{
123-
Proxy: http.ProxyFromEnvironment,
124+
Proxy: http.ProxyFromEnvironment,
125+
TLSHandshakeTimeout: 10 * time.Second,
126+
ResponseHeaderTimeout: 30 * time.Second,
127+
ExpectContinueTimeout: 1 * time.Second,
124128
}
125129
globalHTTPClient = &http.Client{
126130
Transport: globalTransport,
131+
Timeout: 60 * time.Second,
127132
}
128133
azurepkg.GlobalHTTPClient = globalHTTPClient
129134
return nil
@@ -147,12 +152,16 @@ func updateGlobalTransportLocked(certData []byte) error {
147152
RootCAs: globalCertPool,
148153
InsecureSkipVerify: false,
149154
},
150-
Proxy: http.ProxyFromEnvironment,
155+
Proxy: http.ProxyFromEnvironment,
156+
TLSHandshakeTimeout: 10 * time.Second,
157+
ResponseHeaderTimeout: 30 * time.Second,
158+
ExpectContinueTimeout: 1 * time.Second,
151159
}
152160

153161
// Create global HTTP client
154162
globalHTTPClient = &http.Client{
155163
Transport: globalTransport,
164+
Timeout: 60 * time.Second,
156165
}
157166

158167
// Store in azure package globals for backward compatibility

azure/services/managedclusters/managedclusters.go

Lines changed: 25 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -142,43 +142,54 @@ func postCreateOrUpdateResourceHook(ctx context.Context, scope ManagedClusterSco
142142
The user needs to ensure to provide service principal with admin AAD privileges.
143143
*/
144144
func reconcileKubeconfig(ctx context.Context, scope ManagedClusterScope, namespace string) (adminKubeConfigData []byte, userKubeConfigData []byte, err error) {
145+
fmt.Printf("=== DEBUG: reconcileKubeconfig() called for cluster: %s ===\n", scope.ClusterName())
146+
fmt.Printf("DEBUG: Namespace: %s\n", namespace)
147+
fmt.Printf("DEBUG: IsAADEnabled: %v\n", scope.IsAADEnabled())
148+
fmt.Printf("DEBUG: AreLocalAccountsDisabled: %v\n", scope.AreLocalAccountsDisabled())
149+
145150
if scope.IsAADEnabled() {
151+
fmt.Printf("DEBUG: AAD is enabled, getting user kubeconfig data\n")
146152
if userKubeConfigData, err = getUserKubeconfigData(ctx, scope, namespace); err != nil {
153+
fmt.Printf("DEBUG: ERROR - Failed to get user kubeconfig: %v\n", err)
147154
return nil, nil, errors.Wrap(err, "error while trying to get user kubeconfig")
148155
}
156+
fmt.Printf("DEBUG: Got user kubeconfig data: %d bytes\n", len(userKubeConfigData))
149157
}
150158

151159
if scope.AreLocalAccountsDisabled() {
160+
fmt.Printf("DEBUG: Local accounts disabled, using user kubeconfig with token path\n")
152161
userKubeconfigWithToken, err := getUserKubeConfigWithToken(ctx, userKubeConfigData, scope)
153162
if err != nil {
163+
fmt.Printf("DEBUG: ERROR - Failed to get user kubeconfig with token: %v\n", err)
154164
return nil, nil, errors.Wrap(err, "error while trying to get user kubeconfig with token")
155165
}
166+
fmt.Printf("DEBUG: Successfully got user kubeconfig with token: %d bytes\n", len(userKubeconfigWithToken))
156167
return userKubeconfigWithToken, userKubeConfigData, nil
157168
}
158169

170+
fmt.Printf("DEBUG: Using admin kubeconfig path (local accounts enabled)\n")
159171
asoSecret := &corev1.Secret{}
172+
secretName := adminKubeconfigSecretName(scope.ClusterName())
173+
fmt.Printf("DEBUG: Looking for ASO admin kubeconfig secret: %s/%s\n", namespace, secretName)
174+
160175
err = scope.GetClient().Get(
161176
ctx,
162177
client.ObjectKey{
163178
Namespace: namespace,
164-
Name: adminKubeconfigSecretName(scope.ClusterName()),
179+
Name: secretName,
165180
},
166181
asoSecret,
167182
)
168183
if err != nil {
184+
fmt.Printf("DEBUG: ERROR - Failed to get ASO admin kubeconfig secret: %v\n", err)
169185
return nil, nil, errors.Wrap(err, "failed to get ASO admin kubeconfig secret")
170186
}
171-
adminKubeConfigData = asoSecret.Data[secret.KubeconfigDataName]
172187

173-
// PATCH POINT: Inject custom CA certificate data into admin kubeconfig
174-
// This allows patching CA certificates for admin kubeconfig retrieved from ASO
175-
if adminKubeConfigData != nil && len(adminKubeConfigData) > 0 {
176-
if patchedAdminConfig, err := patchKubeconfigWithCustomCA(adminKubeConfigData, scope.ClusterName()); err == nil {
177-
adminKubeConfigData = patchedAdminConfig
178-
}
179-
// Note: We could log the error but not fail the reconciliation if patching fails
180-
}
188+
adminKubeConfigData = asoSecret.Data[secret.KubeconfigDataName]
189+
fmt.Printf("DEBUG: Retrieved admin kubeconfig from ASO secret: %d bytes\n", len(adminKubeConfigData))
181190

191+
fmt.Printf("DEBUG: reconcileKubeconfig() completed - admin: %d bytes, user: %d bytes\n",
192+
len(adminKubeConfigData), len(userKubeConfigData))
182193
return adminKubeConfigData, userKubeConfigData, nil
183194
}
184195

@@ -215,60 +226,16 @@ func getUserKubeConfigWithToken(ctx context.Context, userKubeConfigData []byte,
215226
auth.Exec = nil
216227
}
217228

218-
// PATCH POINT: Inject custom CA certificate data here
219-
// This is where you could add logic to replace the certificate-authority-data
220-
// with your custom CA certificate
221-
if customCACert := getCustomCACertificate(); customCACert != nil {
222-
for _, cluster := range config.Clusters {
223-
cluster.CertificateAuthorityData = customCACert
224-
}
225-
}
226-
227229
kubeconfig, err := clientcmd.Write(*config)
228230
if err != nil {
229231
return nil, errors.Wrap(err, "error while trying to marshal new user kubeconfig with token")
230232
}
231233
return kubeconfig, nil
232234
}
233235

234-
// getCustomCACertificate returns custom CA certificate data if available
235-
// This function leverages the same certificate that is used for Azure authentication
236-
// by checking the global AzSecretCertPool that gets populated during Azure client initialization
237-
func getCustomCACertificate() []byte {
238-
// Check if we have a certificate in the global AzSecretCertPool
239-
// This is the same certificate pool used for Azure authentication
240-
if azure.IsAzSecretCertConfigured() && azure.AzSecretCertPool != nil {
241-
// Return the raw certificate data stored in AzSecretCertData
242-
// This contains the original PEM data that was used to populate the certificate pool
243-
if len(azure.AzSecretCertData) > 0 {
244-
return azure.AzSecretCertData
245-
}
246-
}
247-
248-
return nil
249-
}
250-
251-
// patchKubeconfigWithCustomCA patches kubeconfig data with custom CA certificate
252-
func patchKubeconfigWithCustomCA(kubeconfigData []byte, clusterName string) ([]byte, error) {
253-
customCACert := getCustomCACertificate()
254-
if customCACert == nil {
255-
return kubeconfigData, nil // No custom CA, return original
256-
}
257-
258-
config, err := clientcmd.Load(kubeconfigData)
259-
if err != nil {
260-
return nil, errors.Wrap(err, "failed to load kubeconfig for CA patching")
261-
}
262-
263-
// Replace CA data in all clusters
264-
for _, cluster := range config.Clusters {
265-
cluster.CertificateAuthorityData = customCACert
266-
}
267-
268-
patchedKubeconfig, err := clientcmd.Write(*config)
269-
if err != nil {
270-
return nil, errors.Wrap(err, "failed to write patched kubeconfig")
236+
func min(a, b int) int {
237+
if a < b {
238+
return a
271239
}
272-
273-
return patchedKubeconfig, nil
240+
return b
274241
}

controllers/azureasomanagedcontrolplane_controller.go

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -325,10 +325,41 @@ func (r *AzureASOManagedControlPlaneReconciler) reconcileKubeconfig(ctx context.
325325

326326
// PATCH POINT: Inject custom CA certificate data here
327327
// This allows patching CA certificates for AAD-enabled clusters with local accounts disabled
328+
fmt.Printf("=== DEBUG: ASO Controller CA injection for cluster: %s ===\n", cluster.Name)
328329
if customCACert := getCustomCACertificateForCluster(cluster.Name); customCACert != nil {
329-
for _, clusterInfo := range kubeconfig.Clusters {
330-
clusterInfo.CertificateAuthorityData = customCACert
330+
fmt.Printf("DEBUG: ASO - Custom CA certificate found (%d bytes), proceeding with COMBINATION\n", len(customCACert))
331+
patchedCount := 0
332+
for clusterName, clusterInfo := range kubeconfig.Clusters {
333+
fmt.Printf("DEBUG: ASO - Processing cluster '%s'\n", clusterName)
334+
fmt.Printf("DEBUG: ASO - Original CA data length: %d bytes\n", len(clusterInfo.CertificateAuthorityData))
335+
336+
if clusterInfo.CertificateAuthorityData != nil && len(clusterInfo.CertificateAuthorityData) > 0 {
337+
fmt.Printf("DEBUG: ASO - Combining original CA with custom CA\n")
338+
// Combine: original + newline + custom CA
339+
combinedCA := make([]byte, 0, len(clusterInfo.CertificateAuthorityData)+1+len(customCACert))
340+
combinedCA = append(combinedCA, clusterInfo.CertificateAuthorityData...)
341+
342+
// Add newline separator if original doesn't end with newline
343+
if clusterInfo.CertificateAuthorityData[len(clusterInfo.CertificateAuthorityData)-1] != '\n' {
344+
combinedCA = append(combinedCA, '\n')
345+
}
346+
347+
combinedCA = append(combinedCA, customCACert...)
348+
clusterInfo.CertificateAuthorityData = combinedCA
349+
350+
fmt.Printf("DEBUG: ASO - Combined CA data length: %d bytes (original: %d + custom: %d)\n",
351+
len(combinedCA), len(clusterInfo.CertificateAuthorityData)-len(customCACert)-1, len(customCACert))
352+
} else {
353+
fmt.Printf("DEBUG: ASO - No original CA data, using only custom CA\n")
354+
// No original CA, just use custom
355+
clusterInfo.CertificateAuthorityData = customCACert
356+
fmt.Printf("DEBUG: ASO - Set CA data length: %d bytes\n", len(clusterInfo.CertificateAuthorityData))
357+
}
358+
patchedCount++
331359
}
360+
fmt.Printf("DEBUG: ASO - Combined CA certificates in %d clusters total\n", patchedCount)
361+
} else {
362+
fmt.Printf("DEBUG: ASO - No custom CA certificate found, keeping original kubeconfig\n")
332363
}
333364

334365
kubeconfigData, err = clientcmd.Write(*kubeconfig)
@@ -366,19 +397,46 @@ func (r *AzureASOManagedControlPlaneReconciler) reconcileKubeconfig(ctx context.
366397
// This function leverages the same certificate that is used for Azure authentication
367398
// by checking the global AzSecretCertPool that gets populated during Azure client initialization
368399
func getCustomCACertificateForCluster(clusterName string) []byte {
400+
fmt.Printf("=== DEBUG: ASO getCustomCACertificateForCluster() called for cluster: %s ===\n", clusterName)
401+
402+
// Debug the condition checks
403+
isConfigured := azure.IsAzSecretCertConfigured()
404+
poolNotNil := azure.AzSecretCertPool != nil
405+
dataLength := len(azure.AzSecretCertData)
406+
407+
fmt.Printf("DEBUG: ASO - azure.IsAzSecretCertConfigured() = %v\n", isConfigured)
408+
fmt.Printf("DEBUG: ASO - azure.AzSecretCertPool != nil = %v\n", poolNotNil)
409+
fmt.Printf("DEBUG: ASO - len(azure.AzSecretCertData) = %d\n", dataLength)
410+
369411
// Check if we have a certificate in the global AzSecretCertPool
370412
// This is the same certificate pool used for Azure authentication
371413
if azure.IsAzSecretCertConfigured() && azure.AzSecretCertPool != nil {
414+
fmt.Printf("DEBUG: ASO - Passed first condition check (IsConfigured && PoolNotNil)\n")
372415
// Return the raw certificate data stored in AzSecretCertData
373416
// This contains the original PEM data that was used to populate the certificate pool
374417
if len(azure.AzSecretCertData) > 0 {
418+
fmt.Printf("DEBUG: ASO - Found certificate data, returning %d bytes\n", len(azure.AzSecretCertData))
419+
fmt.Printf("DEBUG: ASO - Certificate data preview (first 100 chars): %s...\n",
420+
string(azure.AzSecretCertData[:min(100, len(azure.AzSecretCertData))]))
375421
return azure.AzSecretCertData
422+
} else {
423+
fmt.Printf("DEBUG: ASO - Certificate data is empty, returning nil\n")
376424
}
425+
} else {
426+
fmt.Printf("DEBUG: ASO - Failed condition check - IsConfigured: %v, PoolNotNil: %v\n", isConfigured, poolNotNil)
377427
}
378428

429+
fmt.Printf("DEBUG: ASO - getCustomCACertificateForCluster() returning nil\n")
379430
return nil
380431
}
381432

433+
func min(a, b int) int {
434+
if a < b {
435+
return a
436+
}
437+
return b
438+
}
439+
382440
func (r *AzureASOManagedControlPlaneReconciler) reconcilePaused(ctx context.Context, asoManagedControlPlane *infrav1alpha.AzureASOManagedControlPlane) (ctrl.Result, error) {
383441
ctx, log, done := tele.StartSpanWithLogger(ctx, "controllers.AzureASOManagedControlPlaneReconciler.reconcilePaused")
384442
defer done()

controllers/azuremanagedcontrolplane_reconciler.go

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,62 @@ func (r *azureManagedControlPlaneService) reconcileKubeconfig(ctx context.Contex
130130
if len(kubeConfigData) == 0 {
131131
continue
132132
}
133+
134+
// PATCH POINT: Inject custom CA certificate data into kubeconfig before storing in secret
135+
fmt.Printf("=== DEBUG: AMCP reconcileKubeconfig() - Processing kubeconfig %d (admin=0, user=1) ===\n", i)
136+
fmt.Printf("DEBUG: AMCP - Original kubeconfig size: %d bytes\n", len(kubeConfigData))
137+
138+
if customCACert := getCustomCACertificateForAMCP(r.scope.ClusterName()); customCACert != nil {
139+
fmt.Printf("DEBUG: AMCP - Custom CA certificate found (%d bytes), proceeding with COMBINATION\n", len(customCACert))
140+
141+
// Parse kubeconfig
142+
kubeconfig, err := clientcmd.Load(kubeConfigData)
143+
if err != nil {
144+
fmt.Printf("DEBUG: AMCP - ERROR: Failed to parse kubeconfig: %v\n", err)
145+
} else {
146+
patchedCount := 0
147+
for clusterName, clusterInfo := range kubeconfig.Clusters {
148+
fmt.Printf("DEBUG: AMCP - Processing cluster '%s'\n", clusterName)
149+
fmt.Printf("DEBUG: AMCP - Original CA data length: %d bytes\n", len(clusterInfo.CertificateAuthorityData))
150+
151+
if clusterInfo.CertificateAuthorityData != nil && len(clusterInfo.CertificateAuthorityData) > 0 {
152+
fmt.Printf("DEBUG: AMCP - Combining original CA with custom CA\n")
153+
// Combine: original + newline + custom CA
154+
combinedCA := make([]byte, 0, len(clusterInfo.CertificateAuthorityData)+1+len(customCACert))
155+
combinedCA = append(combinedCA, clusterInfo.CertificateAuthorityData...)
156+
157+
// Add newline separator if original doesn't end with newline
158+
if clusterInfo.CertificateAuthorityData[len(clusterInfo.CertificateAuthorityData)-1] != '\n' {
159+
combinedCA = append(combinedCA, '\n')
160+
}
161+
162+
combinedCA = append(combinedCA, customCACert...)
163+
clusterInfo.CertificateAuthorityData = combinedCA
164+
165+
fmt.Printf("DEBUG: AMCP - Combined CA data length: %d bytes (original: %d + custom: %d)\n",
166+
len(combinedCA), len(clusterInfo.CertificateAuthorityData)-len(customCACert)-1, len(customCACert))
167+
} else {
168+
fmt.Printf("DEBUG: AMCP - No original CA data, using only custom CA\n")
169+
// No original CA, just use custom
170+
clusterInfo.CertificateAuthorityData = customCACert
171+
fmt.Printf("DEBUG: AMCP - Set CA data length: %d bytes\n", len(clusterInfo.CertificateAuthorityData))
172+
}
173+
patchedCount++
174+
}
175+
fmt.Printf("DEBUG: AMCP - Combined CA certificates in %d clusters total\n", patchedCount)
176+
177+
// Write back the modified kubeconfig
178+
if patchedKubeconfig, err := clientcmd.Write(*kubeconfig); err != nil {
179+
fmt.Printf("DEBUG: AMCP - ERROR: Failed to write patched kubeconfig: %v\n", err)
180+
} else {
181+
kubeConfigData = patchedKubeconfig
182+
fmt.Printf("DEBUG: AMCP - Successfully wrote combined kubeconfig (%d bytes)\n", len(kubeConfigData))
183+
}
184+
}
185+
} else {
186+
fmt.Printf("DEBUG: AMCP - No custom CA certificate found, keeping original kubeconfig\n")
187+
}
188+
133189
kubeConfigSecret := r.scope.MakeEmptyKubeConfigSecret()
134190
if i == 1 {
135191
// 2nd kubeconfig is the user kubeconfig
@@ -152,6 +208,8 @@ func (r *azureManagedControlPlaneService) reconcileKubeconfig(ctx context.Contex
152208
}); err != nil {
153209
return errors.Wrap(err, "failed to reconcile kubeconfig secret for cluster")
154210
}
211+
212+
fmt.Printf("DEBUG: AMCP - Successfully stored kubeconfig secret '%s' with CA injection\n", kubeConfigSecret.Name)
155213
}
156214

157215
// store cluster-info for the cluster with the admin kubeconfig.
@@ -179,3 +237,40 @@ func (r *azureManagedControlPlaneService) reconcileKubeconfig(ctx context.Contex
179237

180238
return nil
181239
}
240+
241+
// getCustomCACertificateForAMCP returns custom CA certificate data for Azure Managed Control Plane clusters
242+
// This function leverages the same certificate that is used for Azure authentication
243+
// by checking the global AzSecretCertPool that gets populated during Azure client initialization
244+
func getCustomCACertificateForAMCP(clusterName string) []byte {
245+
fmt.Printf("=== DEBUG: AMCP getCustomCACertificateForAMCP() called for cluster: %s ===\n", clusterName)
246+
247+
// Debug the condition checks
248+
isConfigured := azure.IsAzSecretCertConfigured()
249+
poolNotNil := azure.AzSecretCertPool != nil
250+
dataLength := len(azure.AzSecretCertData)
251+
252+
fmt.Printf("DEBUG: AMCP - azure.IsAzSecretCertConfigured() = %v\n", isConfigured)
253+
fmt.Printf("DEBUG: AMCP - azure.AzSecretCertPool != nil = %v\n", poolNotNil)
254+
fmt.Printf("DEBUG: AMCP - len(azure.AzSecretCertData) = %d\n", dataLength)
255+
256+
// Check if we have a certificate in the global AzSecretCertPool
257+
// This is the same certificate pool used for Azure authentication
258+
if azure.IsAzSecretCertConfigured() && azure.AzSecretCertPool != nil {
259+
fmt.Printf("DEBUG: AMCP - Passed first condition check (IsConfigured && PoolNotNil)\n")
260+
// Return the raw certificate data stored in AzSecretCertData
261+
// This contains the original PEM data that was used to populate the certificate pool
262+
if len(azure.AzSecretCertData) > 0 {
263+
fmt.Printf("DEBUG: AMCP - Found certificate data, returning %d bytes\n", len(azure.AzSecretCertData))
264+
fmt.Printf("DEBUG: AMCP - Certificate data preview (first 100 chars): %s...\n",
265+
string(azure.AzSecretCertData[:min(100, len(azure.AzSecretCertData))]))
266+
return azure.AzSecretCertData
267+
} else {
268+
fmt.Printf("DEBUG: AMCP - Certificate data is empty, returning nil\n")
269+
}
270+
} else {
271+
fmt.Printf("DEBUG: AMCP - Failed condition check - IsConfigured: %v, PoolNotNil: %v\n", isConfigured, poolNotNil)
272+
}
273+
274+
fmt.Printf("DEBUG: AMCP - getCustomCACertificateForAMCP() returning nil\n")
275+
return nil
276+
}

main.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,12 @@ func main() {
328328

329329
restConfig := ctrl.GetConfigOrDie()
330330
restConfig.UserAgent = "cluster-api-provider-azure-manager"
331+
332+
// Configure longer timeouts for cluster connections, especially for custom Azure environments
333+
restConfig.Timeout = 30 * time.Second
334+
restConfig.QPS = 20
335+
restConfig.Burst = 30
336+
331337
mgr, err := ctrl.NewManager(restConfig, ctrl.Options{
332338
Scheme: scheme,
333339
LeaderElection: enableLeaderElection,

0 commit comments

Comments
 (0)