@@ -20,7 +20,11 @@ import (
20
20
"context"
21
21
"crypto/x509"
22
22
"fmt"
23
+ "io"
24
+ "net/http"
25
+ "os"
23
26
"reflect"
27
+ "time"
24
28
25
29
"github.com/go-logr/logr"
26
30
infrastructurev1beta2 "github.com/oracle/cluster-api-provider-oci/api/v1beta2"
@@ -41,6 +45,15 @@ import (
41
45
"sigs.k8s.io/cluster-api/util/patch"
42
46
"sigs.k8s.io/controller-runtime/pkg/client"
43
47
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
48
+ "sigs.k8s.io/controller-runtime/pkg/log"
49
+ )
50
+
51
+ const (
52
+ instanceMetadataRegionInfoURLV2 = "http://169.254.169.254/opc/v2/instance/regionInfo/regionIdentifier"
53
+ )
54
+
55
+ var (
56
+ currentRegion * string
44
57
)
45
58
46
59
// GetClusterIdentityFromRef returns the OCIClusterIdentity referenced by the OCICluster.
@@ -97,6 +110,7 @@ func getOCIClientCertPool(ctx context.Context, c client.Client, namespace string
97
110
98
111
// GetOrBuildClientFromIdentity creates ClientProvider from OCIClusterIdentity object
99
112
func GetOrBuildClientFromIdentity (ctx context.Context , c client.Client , identity * infrastructurev1beta2.OCIClusterIdentity , defaultRegion string , clientOverrides * infrastructurev1beta2.ClientOverrides , namespace string ) (* scope.ClientProvider , error ) {
113
+ logger := log .FromContext (ctx )
100
114
if identity .Spec .Type == infrastructurev1beta2 .UserPrincipal {
101
115
secretRef := identity .Spec .PrincipalSecret
102
116
key := types.NamespacedName {
@@ -155,6 +169,42 @@ func GetOrBuildClientFromIdentity(ctx context.Context, c client.Client, identity
155
169
OciAuthConfigProvider : provider ,
156
170
ClientOverrides : clientOverrides })
157
171
172
+ if err != nil {
173
+ return nil , err
174
+ }
175
+ return clientProvider , nil
176
+ } else if identity .Spec .Type == infrastructurev1beta2 .WorkloadPrincipal {
177
+ _ , containsVersion := os .LookupEnv (auth .ResourcePrincipalVersionEnvVar )
178
+ if ! containsVersion {
179
+ os .Setenv (auth .ResourcePrincipalVersionEnvVar , auth .ResourcePrincipalVersion2_2 )
180
+ }
181
+ _ , containsRegion := os .LookupEnv (auth .ResourcePrincipalRegionEnvVar )
182
+ if ! containsRegion {
183
+ // initialize the current region from region metadata
184
+ if currentRegion == nil {
185
+ regionByte , err := getRegionInfoFromInstanceMetadataServiceProd ()
186
+ if err != nil {
187
+ return nil , err
188
+ }
189
+ currentRegion = common .String (string (regionByte ))
190
+ }
191
+ logger .Info (fmt .Sprintf ("Looked up region %s from instance metadata" , * currentRegion ))
192
+ os .Setenv (auth .ResourcePrincipalRegionEnvVar , * currentRegion )
193
+ }
194
+
195
+ provider , err := auth .OkeWorkloadIdentityConfigurationProvider ()
196
+ if err != nil {
197
+ return nil , err
198
+ }
199
+ pool , err := getOCIClientCertPool (ctx , c , namespace , clientOverrides )
200
+ if err != nil {
201
+ return nil , err
202
+ }
203
+ clientProvider , err := scope .NewClientProvider (scope.ClientProviderParams {
204
+ CertOverride : pool ,
205
+ OciAuthConfigProvider : provider ,
206
+ ClientOverrides : clientOverrides })
207
+
158
208
if err != nil {
159
209
return nil , err
160
210
}
@@ -406,6 +456,35 @@ func DeleteOrphanedMachinePoolMachines(ctx context.Context, params MachineParams
406
456
407
457
return nil
408
458
}
459
+ func getRegionInfoFromInstanceMetadataServiceProd () ([]byte , error ) {
460
+ request , err := http .NewRequest (http .MethodGet , instanceMetadataRegionInfoURLV2 , nil )
461
+ request .Header .Add ("Authorization" , "Bearer Oracle" )
462
+
463
+ client := & http.Client {
464
+ Timeout : time .Second * 10 ,
465
+ }
466
+ resp , err := client .Do (request )
467
+ if err != nil {
468
+ return nil , errors .Wrap (err , "failed to call instance metadata service" )
469
+ }
470
+
471
+ statusCode := resp .StatusCode
472
+
473
+ defer resp .Body .Close ()
474
+
475
+ content , err := io .ReadAll (resp .Body )
476
+ if err != nil {
477
+ return nil , errors .Wrap (err , "failed to get region information from response body" )
478
+ }
479
+
480
+ if statusCode != http .StatusOK {
481
+ err = fmt .Errorf ("HTTP Get failed: URL: %s, Status: %s, Message: %s" ,
482
+ instanceMetadataRegionInfoURLV2 , resp .Status , string (content ))
483
+ return nil , err
484
+ }
485
+
486
+ return content , nil
487
+ }
409
488
410
489
// MachineParams specifies the params required to create or delete machinepool machines.
411
490
// Infra machine pool specifed below refers to OCIManagedMachinePool/OCIMachinePool/OCIVirtualMachinePool
0 commit comments