@@ -20,7 +20,11 @@ import (
2020 "context"
2121 "crypto/x509"
2222 "fmt"
23+ "io"
24+ "net/http"
25+ "os"
2326 "reflect"
27+ "time"
2428
2529 "github.com/go-logr/logr"
2630 infrastructurev1beta2 "github.com/oracle/cluster-api-provider-oci/api/v1beta2"
@@ -41,6 +45,15 @@ import (
4145 "sigs.k8s.io/cluster-api/util/patch"
4246 "sigs.k8s.io/controller-runtime/pkg/client"
4347 "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
4457)
4558
4659// GetClusterIdentityFromRef returns the OCIClusterIdentity referenced by the OCICluster.
@@ -97,6 +110,7 @@ func getOCIClientCertPool(ctx context.Context, c client.Client, namespace string
97110
98111// GetOrBuildClientFromIdentity creates ClientProvider from OCIClusterIdentity object
99112func 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 )
100114 if identity .Spec .Type == infrastructurev1beta2 .UserPrincipal {
101115 secretRef := identity .Spec .PrincipalSecret
102116 key := types.NamespacedName {
@@ -155,6 +169,42 @@ func GetOrBuildClientFromIdentity(ctx context.Context, c client.Client, identity
155169 OciAuthConfigProvider : provider ,
156170 ClientOverrides : clientOverrides })
157171
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+
158208 if err != nil {
159209 return nil , err
160210 }
@@ -406,6 +456,35 @@ func DeleteOrphanedMachinePoolMachines(ctx context.Context, params MachineParams
406456
407457 return nil
408458}
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+ }
409488
410489// MachineParams specifies the params required to create or delete machinepool machines.
411490// Infra machine pool specifed below refers to OCIManagedMachinePool/OCIMachinePool/OCIVirtualMachinePool
0 commit comments