@@ -4,10 +4,12 @@ import (
44 "embed"
55 "encoding/json"
66 "fmt"
7+ "strings"
78
89 "github.com/asaskevich/govalidator"
910 configv1 "github.com/openshift/api/config/v1"
1011 appsv1 "k8s.io/api/apps/v1"
12+ "k8s.io/apimachinery/pkg/util/validation/field"
1113 "sigs.k8s.io/controller-runtime/pkg/client"
1214
1315 azureconsts "sigs.k8s.io/cloud-provider-azure/pkg/consts"
2830 }
2931)
3032
33+ var (
34+ validAzureCloudNames = map [configv1.AzureCloudEnvironment ]bool {
35+ configv1 .AzurePublicCloud : true ,
36+ configv1 .AzureUSGovernmentCloud : true ,
37+ configv1 .AzureChinaCloud : true ,
38+ configv1 .AzureGermanCloud : true ,
39+ configv1 .AzureStackCloud : true ,
40+ }
41+
42+ validAzureCloudNameValues = func () []string {
43+ v := make ([]string , 0 , len (validAzureCloudNames ))
44+ for n := range validAzureCloudNames {
45+ v = append (v , string (n ))
46+ }
47+ return v
48+ }()
49+ )
50+
3151type imagesReference struct {
3252 CloudControllerManager string `valid:"required"`
3353 CloudControllerManagerOperator string `valid:"required"`
@@ -91,12 +111,60 @@ func NewProviderAssets(config config.OperatorConfig) (common.CloudProviderAssets
91111 return assets , nil
92112}
93113
114+ func IsAzure (infra * configv1.Infrastructure ) bool {
115+ if infra .Status .PlatformStatus != nil &&
116+ infra .Status .PlatformStatus .Type == configv1 .AzurePlatformType {
117+ return true
118+ }
119+ return false
120+ }
121+
94122func CloudConfigTransformer (source string , infra * configv1.Infrastructure , network * configv1.Network ) (string , error ) {
123+ if ! IsAzure (infra ) {
124+ return "" , fmt .Errorf ("invalid platform, expected to be Azure" )
125+ }
126+
95127 var cfg azure.Config
96128 if err := json .Unmarshal ([]byte (source ), & cfg ); err != nil {
97129 return "" , fmt .Errorf ("failed to unmarshal the cloud.conf: %w" , err )
98130 }
99131
132+ // We are copying the behaviour from CCO's transformer we need to:
133+ // 1. Ensure that the Cloud is set in the cloud.conf
134+ // i. If it is set, verify that it is valid and does not conflict with the
135+ // infrastructure config. If it conflicts, we want to error
136+ // ii. If it is not set, default to public cloud (configv1.AzurePublicCloud)
137+ //
138+ // 2. Verify the cloud name set in the infra config is valid, if it is not
139+ // bail with an informative error
140+
141+ // Verify the cloud name set in the infra config is valid
142+ cloud := configv1 .AzurePublicCloud
143+ if azurePlatform := infra .Status .PlatformStatus .Azure ; azurePlatform != nil {
144+ if c := azurePlatform .CloudName ; c != "" {
145+ if ! validAzureCloudNames [c ] {
146+ return "" , field .NotSupported (field .NewPath ("status" , "platformStatus" , "azure" , "cloudName" ), c , validAzureCloudNameValues )
147+ }
148+ cloud = c
149+ }
150+ }
151+
152+ // Ensure Cloud is set in cloud.conf matches what is set in infra
153+ if cfg .Cloud != "" {
154+ if ! strings .EqualFold (string (cloud ), cfg .Cloud ) {
155+ return "" ,
156+ fmt .Errorf (`invalid user-provided cloud.conf: \"cloud\" field in user-provided
157+ cloud.conf conflicts with infrastructure object` )
158+ }
159+ }
160+
161+ // TODO: Remove when you work this out (before merging)
162+ // Why is cfg.Cloud not typed: type AzureCloudEnvironment string
163+
164+ // At this point these should always be the same
165+ // comparrison
166+ cfg .Cloud = string (cloud )
167+
100168 // If the virtual machine type is not set we need to make sure it uses the
101169 // "standard" instance type. See OCPBUGS-25483 and OCPBUGS-20213 for more
102170 // information
0 commit comments