Skip to content

Commit 791c39c

Browse files
Merge pull request #1005 from openshift-cherrypick-robot/cherry-pick-1004-to-release-4.14
[release-4.14] OCPBUGS-29755: azurepathfix: fix stack hub, government and workload identity setup
2 parents e39fe6a + e8cc9bd commit 791c39c

File tree

5 files changed

+210
-39
lines changed

5 files changed

+210
-39
lines changed

cmd/move-blobs/main.go

Lines changed: 62 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ func main() {
3131
opts.environment = "AZUREPUBLICCLOUD"
3232
}
3333

34+
if err := createASHEnvironmentFile(opts); err != nil {
35+
panic(err)
36+
}
37+
3438
cloudConfig, err := getCloudConfig(opts.environment)
3539
if err != nil {
3640
panic(err)
@@ -218,6 +222,34 @@ type configOpts struct {
218222
federatedTokenFile string
219223
accountKey string
220224
environment string
225+
// environmentFilePath and environmentFileContents are specific
226+
// for Azure Stack Hub
227+
environmentFilePath string
228+
environmentFileContents string
229+
}
230+
231+
func createASHEnvironmentFile(opts *configOpts) error {
232+
if len(opts.environmentFilePath) == 0 || len(opts.environmentFileContents) == 0 {
233+
klog.Info("Azure Stack Hub environment variables not present in current environment, skipping setup...")
234+
return nil
235+
}
236+
f, err := os.Create(opts.environmentFilePath)
237+
if err != nil {
238+
return err
239+
}
240+
241+
_, err = f.WriteString(opts.environmentFileContents)
242+
if err != nil {
243+
f.Close()
244+
os.Remove(f.Name())
245+
return err
246+
}
247+
248+
err = f.Close()
249+
if err != nil {
250+
return err
251+
}
252+
return nil
221253
}
222254

223255
func getCloudConfig(environment string) (cloud.Configuration, error) {
@@ -238,14 +270,16 @@ func getCloudConfig(environment string) (cloud.Configuration, error) {
238270

239271
func getConfigOpts() *configOpts {
240272
return &configOpts{
241-
storageAccountName: strings.TrimSpace(os.Getenv("AZURE_STORAGE_ACCOUNT_NAME")),
242-
containerName: strings.TrimSpace(os.Getenv("AZURE_CONTAINER_NAME")),
243-
clientID: strings.TrimSpace(os.Getenv("AZURE_CLIENT_ID")),
244-
tenantID: strings.TrimSpace(os.Getenv("AZURE_TENANT_ID")),
245-
clientSecret: strings.TrimSpace(os.Getenv("AZURE_CLIENT_SECRET")),
246-
federatedTokenFile: strings.TrimSpace(os.Getenv("AZURE_FEDERATED_TOKEN_FILE")),
247-
accountKey: strings.TrimSpace(os.Getenv("AZURE_ACCOUNTKEY")),
248-
environment: strings.TrimSpace(os.Getenv("AZURE_ENVIRONMENT")),
273+
storageAccountName: strings.TrimSpace(os.Getenv("AZURE_STORAGE_ACCOUNT_NAME")),
274+
containerName: strings.TrimSpace(os.Getenv("AZURE_CONTAINER_NAME")),
275+
clientID: strings.TrimSpace(os.Getenv("AZURE_CLIENT_ID")),
276+
tenantID: strings.TrimSpace(os.Getenv("AZURE_TENANT_ID")),
277+
clientSecret: strings.TrimSpace(os.Getenv("AZURE_CLIENT_SECRET")),
278+
federatedTokenFile: strings.TrimSpace(os.Getenv("AZURE_FEDERATED_TOKEN_FILE")),
279+
accountKey: strings.TrimSpace(os.Getenv("AZURE_ACCOUNTKEY")),
280+
environment: strings.TrimSpace(os.Getenv("AZURE_ENVIRONMENT")),
281+
environmentFilePath: strings.TrimSpace(os.Getenv("AZURE_ENVIRONMENT_FILEPATH")),
282+
environmentFileContents: strings.TrimSpace(os.Getenv("AZURE_ENVIRONMENT_FILECONTENTS")),
249283
}
250284
}
251285

@@ -254,18 +288,27 @@ func getConfigOpts() *configOpts {
254288
// this function is basically copy of what the operator itself does,
255289
// as a way to ensure that it will work in the same way as the operator.
256290
func getClient(cloudConfig cloud.Configuration, opts *configOpts) (*container.Client, error) {
291+
env, err := azure.EnvironmentFromName(opts.environment)
292+
if err != nil {
293+
return nil, err
294+
}
257295
containerURL := fmt.Sprintf(
258-
"https://%s.blob.core.windows.net/%s",
296+
"https://%s.blob.%s/%s",
259297
opts.storageAccountName,
298+
env.StorageEndpointSuffix,
260299
opts.containerName,
261300
)
262301
var client *container.Client
302+
clientOpts := azcore.ClientOptions{
303+
Cloud: cloudConfig,
304+
}
305+
263306
if len(opts.accountKey) > 0 {
264307
cred, err := container.NewSharedKeyCredential(opts.storageAccountName, opts.accountKey)
265308
if err != nil {
266309
return nil, err
267310
}
268-
client, err = container.NewClientWithSharedKeyCredential(containerURL, cred, nil)
311+
client, err = container.NewClientWithSharedKeyCredential(containerURL, cred, &container.ClientOptions{ClientOptions: clientOpts})
269312
if err != nil {
270313
return nil, err
271314
}
@@ -279,7 +322,7 @@ func getClient(cloudConfig cloud.Configuration, opts *configOpts) (*container.Cl
279322
if err != nil {
280323
return nil, err
281324
}
282-
client, err = container.NewClient(containerURL, cred, nil)
325+
client, err = container.NewClient(containerURL, cred, &container.ClientOptions{ClientOptions: clientOpts})
283326
if err != nil {
284327
return nil, err
285328
}
@@ -296,16 +339,21 @@ func getClient(cloudConfig cloud.Configuration, opts *configOpts) (*container.Cl
296339
if err != nil {
297340
return nil, err
298341
}
299-
client, err = container.NewClient(containerURL, cred, nil)
342+
client, err = container.NewClient(containerURL, cred, &container.ClientOptions{ClientOptions: clientOpts})
300343
if err != nil {
301344
return nil, err
302345
}
303346
} else {
304-
cred, err := azidentity.NewDefaultAzureCredential(nil)
347+
options := azidentity.DefaultAzureCredentialOptions{
348+
ClientOptions: azcore.ClientOptions{
349+
Cloud: cloudConfig,
350+
},
351+
}
352+
cred, err := azidentity.NewDefaultAzureCredential(&options)
305353
if err != nil {
306354
return nil, err
307355
}
308-
client, err = container.NewClient(containerURL, cred, nil)
356+
client, err = container.NewClient(containerURL, cred, &container.ClientOptions{ClientOptions: clientOpts})
309357
if err != nil {
310358
return nil, err
311359
}

cmd/move-blobs/main_test.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package main
33
import (
44
"context"
55
"fmt"
6+
"io"
67
"math/rand"
78
"os"
89
"strings"
@@ -74,6 +75,7 @@ func TestMoveBlobs(t *testing.T) {
7475
defer client.DeleteBlob(ctx, opts.containerName, "/"+blobName, nil)
7576
}
7677

78+
opts.environment = "AZUREPUBLICCLOUD"
7779
cloudConfig, err := getCloudConfig(opts.environment)
7880
if err != nil {
7981
t.Fatal(err)
@@ -243,3 +245,30 @@ func TestValidation(t *testing.T) {
243245
})
244246
}
245247
}
248+
249+
func TestStackHubEnvironmentFile(t *testing.T) {
250+
path := strings.TrimSpace(os.Getenv("AZURE_ENVIRONMENT_FILEPATH"))
251+
contents := strings.TrimSpace(os.Getenv("AZURE_ENVIRONMENT_FILECONTENTS"))
252+
if len(path) == 0 || len(contents) == 0 {
253+
t.Fatal("both AZURE_ENVIRONMENT_FILEPATH and AZURE_ENVIRONMENT_FILECONTENTS must be set")
254+
}
255+
opts := getConfigOpts()
256+
err := createASHEnvironmentFile(opts)
257+
if err != nil {
258+
t.Fatal(err)
259+
}
260+
defer os.Remove(path)
261+
f, err := os.Open(path)
262+
if err != nil {
263+
t.Fatalf("error opening file %q: %v", path, err)
264+
}
265+
b, err := io.ReadAll(f)
266+
if err != nil {
267+
t.Fatalf("error reading file %q: %v", path, err)
268+
}
269+
if string(b) != contents {
270+
t.Logf("AZURE_ENVIRONMENT_FILECONTENTS: %s", contents)
271+
t.Logf("%s: %s", path, string(b))
272+
t.Fatalf("file contents differed from AZURE_ENVIRONMENT_FILECONTENTS")
273+
}
274+
}

pkg/operator/azurepathfixcontroller.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package operator
33
import (
44
"context"
55
"fmt"
6+
"strings"
67
"time"
78

89
batchv1 "k8s.io/api/batch/v1"
@@ -45,6 +46,7 @@ type AzurePathFixController struct {
4546
podLister corev1listers.PodNamespaceLister
4647
infrastructureLister configlisters.InfrastructureLister
4748
proxyLister configlisters.ProxyLister
49+
openshiftConfigLister corev1listers.ConfigMapNamespaceLister
4850
kubeconfig *restclient.Config
4951

5052
cachesToSync []cache.InformerSynced
@@ -60,6 +62,7 @@ func NewAzurePathFixController(
6062
infrastructureInformer configv1informers.InfrastructureInformer,
6163
secretInformer corev1informers.SecretInformer,
6264
proxyInformer configv1informers.ProxyInformer,
65+
openshiftConfigInformer corev1informers.ConfigMapInformer,
6366
podInformer corev1informers.PodInformer,
6467
) (*AzurePathFixController, error) {
6568
c := &AzurePathFixController{
@@ -71,6 +74,7 @@ func NewAzurePathFixController(
7174
secretLister: secretInformer.Lister().Secrets(defaults.ImageRegistryOperatorNamespace),
7275
podLister: podInformer.Lister().Pods(defaults.ImageRegistryOperatorNamespace),
7376
proxyLister: proxyInformer.Lister(),
77+
openshiftConfigLister: openshiftConfigInformer.Lister().ConfigMaps(defaults.OpenShiftConfigNamespace),
7478
kubeconfig: kubeconfig,
7579
queue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "AzurePathFixController"),
7680
}
@@ -105,6 +109,11 @@ func NewAzurePathFixController(
105109
}
106110
c.cachesToSync = append(c.cachesToSync, proxyInformer.Informer().HasSynced)
107111

112+
if _, err := openshiftConfigInformer.Informer().AddEventHandler(c.eventHandler()); err != nil {
113+
return nil, err
114+
}
115+
c.cachesToSync = append(c.cachesToSync, openshiftConfigInformer.Informer().HasSynced)
116+
108117
// bootstrap the job if it doesn't exist
109118
c.queue.Add("instance")
110119

@@ -168,6 +177,7 @@ func (c *AzurePathFixController) sync() error {
168177
if err != nil {
169178
return err
170179
}
180+
171181
azureStorage := imageRegistryConfig.Status.Storage.Azure
172182
if azureStorage == nil || len(azureStorage.AccountName) == 0 {
173183
return fmt.Errorf("storage account not yet provisioned")
@@ -176,12 +186,19 @@ func (c *AzurePathFixController) sync() error {
176186
return fmt.Errorf("storage container not yet provisioned")
177187
}
178188

189+
// the move-blobs cmd does not work on Azure Stack Hub. Users on ASH
190+
// will have to copy the blobs on their own using something like az copy.
191+
if strings.EqualFold(azureStorage.CloudName, "AZURESTACKCLOUD") {
192+
return nil
193+
}
194+
179195
gen := resource.NewGeneratorAzurePathFixJob(
180196
c.jobLister,
181197
c.batchClient,
182198
c.secretLister,
183199
c.infrastructureLister,
184200
c.proxyLister,
201+
c.openshiftConfigLister,
185202
imageRegistryConfig,
186203
c.kubeconfig,
187204
)

pkg/operator/starter.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ func RunOperator(ctx context.Context, kubeconfig *restclient.Config) error {
177177
configInformers.Config().V1().Infrastructures(),
178178
kubeInformers.Core().V1().Secrets(),
179179
configInformers.Config().V1().Proxies(),
180+
kubeInformersForOpenShiftConfig.Core().V1().ConfigMaps(),
180181
kubeInformers.Core().V1().Pods(),
181182
)
182183
if err != nil {

0 commit comments

Comments
 (0)