Skip to content

Commit f918f3c

Browse files
added new support for AzureSecret Region name and cfg map
1 parent eb14c31 commit f918f3c

File tree

3 files changed

+118
-61
lines changed

3 files changed

+118
-61
lines changed

azure/defaults.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ const (
4646
ChinaCloudName = "AzureChinaCloud"
4747
// USGovernmentCloudName is the name of the Azure US Government cloud.
4848
USGovernmentCloudName = "AzureUSGovernmentCloud"
49-
50-
// Remove AzSecretCloudName as it's now handled dynamically
49+
// AzSecretCloudName is the name of the Azure US Secret cloud.
50+
AzSecretCloudName = "AzureUSSecretCloud"
5151
)
5252

5353
const (

azure/scope/azure_secret_cloud.go

Lines changed: 109 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,32 @@ import (
77
"fmt"
88
"net/http"
99
"os"
10-
"path/filepath"
11-
"strings"
1210
"sync"
1311
"time"
1412

1513
"github.com/Azure/azure-sdk-for-go/sdk/azcore"
1614
"github.com/Azure/azure-sdk-for-go/sdk/azcore/arm"
1715
"github.com/Azure/go-autorest/autorest/azure"
1816
"github.com/pkg/errors"
17+
corev1 "k8s.io/api/core/v1"
18+
apierrors "k8s.io/apimachinery/pkg/api/errors"
1919
"k8s.io/client-go/rest"
2020
azurepkg "sigs.k8s.io/cluster-api-provider-azure/azure"
2121
"sigs.k8s.io/cluster-api-provider-azure/util/tele"
22+
"sigs.k8s.io/controller-runtime/pkg/client"
2223
)
2324

2425
const (
25-
AzureEnvironentFolderEnvName = "AZURE_ENVIRONMENT_FOLDER"
26+
// Deprecated: Use ConfigMaps instead
27+
AzureEnvironentFolderEnvName = "AZURE_ENVIRONMENT_FOLDER_CAPZ"
28+
29+
// ConfigMap names for Azure secret cloud configuration
30+
AzureEnvConfigMapName = "azure-capz-env-config"
31+
AzureCertConfigMapName = "azure-capz-cert-config"
32+
33+
// ConfigMap keys
34+
AzureEnvConfigKey = "azure-capz-env.json"
35+
AzureCertConfigKey = "azure-ca.crt"
2636
)
2737

2838
var (
@@ -37,69 +47,110 @@ var (
3747
)
3848

3949
func init() {
40-
4150
_, log, done := tele.StartSpanWithLogger(context.Background(), "scope.AzureScope.init")
42-
log.Info("AzureSecretCloud initializing")
4351
defer done()
44-
path := os.Getenv(AzureEnvironentFolderEnvName)
45-
log.Info("Path is", path)
46-
if path == "" {
47-
// If no environment folder is set, treat as Public/Gov cloud (no custom cert)
48-
return
52+
53+
log.Info("Azure secret cloud init completed - ConfigMap initialization will be performed during controller setup")
54+
55+
// Check for deprecated environment variable
56+
if path := os.Getenv(AzureEnvironentFolderEnvName); path != "" {
57+
log.Info("DEPRECATED: AZURE_ENVIRONMENT_FOLDER_CAPZ is deprecated, use ConfigMaps instead")
58+
fmt.Printf("CAPZ: WARNING - AZURE_ENVIRONMENT_FOLDER_CAPZ is deprecated. Please use ConfigMaps instead.\n")
4959
}
50-
files, err := os.ReadDir(path)
51-
if err != nil {
52-
log.Error(err, "error reading folder", "path", path)
53-
return
54-
}
55-
56-
var certData []byte
57-
for _, file := range files {
58-
if !file.IsDir() {
59-
filePath := filepath.Join(path, file.Name())
60-
fileExt := filepath.Ext(file.Name())
61-
62-
// Load Azure environment JSON files
63-
if strings.EqualFold(fileExt, ".json") {
64-
// Read and log the file contents for debugging
65-
if jsonData, err := os.ReadFile(filePath); err == nil {
66-
//fmt.Printf("CAPZ: Loading Azure environment JSON file: %s\n", file.Name())
67-
fmt.Printf("CAPZ: JSON file contents: %s\n", string(jsonData))
68-
}
69-
70-
if env, err := azure.EnvironmentFromFile(filePath); err == nil {
71-
azure.SetEnvironment(env.Name, env)
72-
log.Info("loaded Azure environment from file", "EnvName", env.Name)
73-
log.Info("loaded Azure environment from file", "filename", file.Name())
74-
} else {
75-
fmt.Printf("CAPZ: Failed to load Azure environment from file %s: %v\n", file.Name(), err)
76-
log.Error(err, "failed to load Azure environment from file", "filename", file.Name())
77-
}
78-
}
79-
80-
// Load certificate files
81-
if strings.EqualFold(fileExt, ".crt") || strings.EqualFold(fileExt, ".pem") {
82-
if data, err := os.ReadFile(filePath); err == nil && len(data) > 0 {
83-
certData = data
84-
fmt.Printf("CAPZ: Successfully loaded certificate from file: %s (%d bytes)\n", file.Name(), len(data))
85-
log.Info("loaded certificate from file", "filename", file.Name())
86-
} else {
87-
log.Error(err, "failed to load certificate from file", "filename", file.Name())
88-
}
89-
}
60+
}
61+
62+
// InitializeAzureConfigForCluster initializes Azure environment and certificates from ConfigMaps
63+
// in the specified cluster namespace
64+
func InitializeAzureConfigForCluster(ctx context.Context, kubeClient client.Client, namespace, azureEnvironment string) error {
65+
_, log, done := tele.StartSpanWithLogger(ctx, "scope.InitializeAzureConfigForCluster")
66+
defer done()
67+
68+
log.Info("Initializing Azure config for cluster", "namespace", namespace, "azureEnvironment", azureEnvironment)
69+
70+
// Try to read environment ConfigMap from cluster namespace
71+
envConfigMap := &corev1.ConfigMap{}
72+
envKey := client.ObjectKey{Namespace: namespace, Name: AzureEnvConfigMapName}
73+
74+
if err := kubeClient.Get(ctx, envKey, envConfigMap); err != nil {
75+
if apierrors.IsNotFound(err) {
76+
log.Info("Azure environment ConfigMap not found in cluster namespace, using default configuration", "namespace", namespace)
77+
return nil // No custom config, use defaults
9078
}
79+
return errors.Wrap(err, "failed to read Azure environment ConfigMap from cluster namespace")
80+
}
81+
82+
// ConfigMap found, process environment JSON
83+
envJSON, hasEnvJSON := envConfigMap.Data[AzureEnvConfigKey]
84+
if !hasEnvJSON || envJSON == "" {
85+
return errors.New("Azure environment ConfigMap found but JSON data is missing")
86+
}
87+
88+
log.Info("Processing Azure environment JSON from cluster ConfigMap")
89+
if err := processAzureEnvironmentJSON(envJSON); err != nil {
90+
return errors.Wrap(err, "failed to process Azure environment JSON")
9191
}
9292

93-
// Initialize global transport with certificate data if found
94-
if len(certData) > 0 {
95-
if err := initializeGlobalTransportWithCertData(certData); err != nil {
96-
log.Error(err, "failed to initialize global transport with certificate")
93+
// Try to read certificate ConfigMap from cluster namespace
94+
certConfigMap := &corev1.ConfigMap{}
95+
certKey := client.ObjectKey{Namespace: namespace, Name: AzureCertConfigMapName}
96+
97+
if err := kubeClient.Get(ctx, certKey, certConfigMap); err != nil {
98+
if apierrors.IsNotFound(err) {
99+
return errors.New("Azure environment ConfigMap found but certificate ConfigMap is missing - custom Azure environments require certificates")
97100
}
98-
} else {
99-
// If environment folder is set but no certificates found, log error
100-
log.Error(errors.New("no certificate files found in environment folder"), "expected certificate files (.crt or .pem) but none found", "path", path)
101+
return errors.Wrap(err, "failed to read Azure certificate ConfigMap from cluster namespace")
101102
}
102-
// If no certificate found in environment folder, treat as Public/Gov cloud (no custom cert)
103+
104+
// Certificate ConfigMap found, process certificate data
105+
certPEM, hasCertPEM := certConfigMap.Data[AzureCertConfigKey]
106+
if !hasCertPEM || certPEM == "" {
107+
return errors.New("Azure certificate ConfigMap found but certificate data is missing")
108+
}
109+
110+
certData := []byte(certPEM)
111+
log.Info("Successfully loaded certificate from cluster ConfigMap", "bytes", len(certData))
112+
113+
// Initialize global transport with certificate data
114+
if err := initializeGlobalTransportWithCertData(certData); err != nil {
115+
return errors.Wrap(err, "failed to initialize global transport with certificate")
116+
}
117+
118+
log.Info("Azure config initialization completed successfully for cluster", "namespace", namespace)
119+
return nil
120+
}
121+
122+
// processAzureEnvironmentJSON processes the Azure environment JSON configuration
123+
func processAzureEnvironmentJSON(envJSON string) error {
124+
// Create a temporary file for azure.EnvironmentFromFile to read
125+
tmpFile, err := os.CreateTemp("", "azure-env-*.json")
126+
if err != nil {
127+
return errors.Wrap(err, "failed to create temporary file for Azure environment")
128+
}
129+
defer os.Remove(tmpFile.Name())
130+
defer tmpFile.Close()
131+
132+
// Write JSON content to temporary file
133+
if _, err := tmpFile.WriteString(envJSON); err != nil {
134+
return errors.Wrap(err, "failed to write Azure environment JSON to temporary file")
135+
}
136+
137+
// Parse Azure environment from file
138+
env, err := azure.EnvironmentFromFile(tmpFile.Name())
139+
if err != nil {
140+
return errors.Wrap(err, "failed to parse Azure environment JSON")
141+
}
142+
143+
azure.SetEnvironment(env.Name, env)
144+
fmt.Printf("CAPZ: Loaded Azure environment: %s\n", env.Name)
145+
return nil
146+
}
147+
148+
// initializeDefaultTransport initializes the default transport for public clouds
149+
func initializeDefaultTransport() error {
150+
globalTransportMutex.Lock()
151+
defer globalTransportMutex.Unlock()
152+
153+
return updateGlobalTransportLocked(nil)
103154
}
104155

105156
// initializeGlobalTransportWithCertData initializes the global transport with provided certificate data

azure/scope/cluster.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ type ClusterScopeParams struct {
7070
// NewClusterScope creates a new Scope from the supplied parameters.
7171
// This is meant to be called for each reconcile iteration.
7272
func NewClusterScope(ctx context.Context, params ClusterScopeParams) (*ClusterScope, error) {
73-
ctx, _, done := tele.StartSpanWithLogger(ctx, "azure.clusterScope.NewClusterScope")
73+
ctx, log, done := tele.StartSpanWithLogger(ctx, "azure.clusterScope.NewClusterScope")
7474
defer done()
7575

7676
if params.Cluster == nil {
@@ -80,6 +80,12 @@ func NewClusterScope(ctx context.Context, params ClusterScopeParams) (*ClusterSc
8080
return nil, errors.New("failed to generate new scope from nil AzureCluster")
8181
}
8282

83+
// Initialize Azure environment and certificates from ConfigMaps in cluster namespace
84+
if err := InitializeAzureConfigForCluster(ctx, params.Client, params.AzureCluster.Namespace, params.AzureCluster.Spec.AzureEnvironment); err != nil {
85+
// Log but don't fail - continue with default configuration
86+
log.V(1).Info("Failed to initialize custom Azure configuration, using defaults", "error", err.Error())
87+
}
88+
8389
credentialsProvider, err := NewAzureCredentialsProvider(ctx, params.CredentialCache, params.Client, params.AzureCluster.Spec.IdentityRef, params.AzureCluster.Namespace)
8490
if err != nil {
8591
return nil, errors.Wrap(err, "failed to init credentials provider")

0 commit comments

Comments
 (0)