Skip to content

Commit d25a152

Browse files
YashasG98l-technicore
authored andcommitted
Using compartment identity client to get ADs for single stack clusters
1 parent ff6709c commit d25a152

File tree

7 files changed

+266
-34
lines changed

7 files changed

+266
-34
lines changed

go.mod

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,10 @@ require (
4343
github.com/container-storage-interface/spec v1.9.0
4444
github.com/golang/protobuf v1.5.4
4545
github.com/kubernetes-csi/csi-lib-utils v0.17.0
46-
github.com/kubernetes-csi/external-snapshotter/client/v6 v6.3.4
46+
github.com/kubernetes-csi/external-snapshotter/client/v6 v6.3.0
4747
github.com/onsi/ginkgo v1.16.5
4848
github.com/onsi/gomega v1.32.0
49-
github.com/oracle/oci-go-sdk/v65 v65.77.0
49+
github.com/oracle/oci-go-sdk/v65 v65.78.1
5050
github.com/pkg/errors v0.9.1
5151
github.com/prometheus/client_golang v1.17.0
5252
github.com/spf13/cobra v1.8.1 // indirect

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,8 +186,8 @@ github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8
186186
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
187187
github.com/opencontainers/selinux v1.11.0 h1:+5Zbo97w3Lbmb3PeqQtpmTkMwsW5nRI3YaLpt7tQ7oU=
188188
github.com/opencontainers/selinux v1.11.0/go.mod h1:E5dMC3VPuVvVHDYmi78qvhJp8+M586T4DlDRYpFkyec=
189-
github.com/oracle/oci-go-sdk/v65 v65.77.0 h1:lFdbyJq7/VsB9gAIemTGx/8sSK3uYEKlQTf5FaTnpTs=
190-
github.com/oracle/oci-go-sdk/v65 v65.77.0/go.mod h1:IBEV9l1qBzUpo7zgGaRUhbB05BVfcDGYRFBCPlTcPp0=
189+
github.com/oracle/oci-go-sdk/v65 v65.78.1 h1:M9nLmaOsjTZJHQ5hlkF5UK6XV/sbFUodAgCfbM2Ve00=
190+
github.com/oracle/oci-go-sdk/v65 v65.78.1/go.mod h1:IBEV9l1qBzUpo7zgGaRUhbB05BVfcDGYRFBCPlTcPp0=
191191
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
192192
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
193193
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=

pkg/csi/driver/bv_controller_test.go

Lines changed: 97 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ package driver
1717
import (
1818
"context"
1919
"fmt"
20+
"os"
2021
"reflect"
2122
"strings"
2223
"testing"
@@ -783,13 +784,19 @@ type MockIdentityClient struct {
783784
common.BaseClient
784785
}
785786

786-
func (client MockIdentityClient) ListAvailabilityDomains(ctx context.Context, compartmentID string) ([]identity.AvailabilityDomain, error) {
787+
func (mockClient MockIdentityClient) ListAvailabilityDomains(ctx context.Context, compartmentID string) ([]identity.AvailabilityDomain, error) {
787788
return nil, nil
788789
}
789790

790791
// ListAvailabilityDomains mocks the client ListAvailabilityDomains implementation
791-
func (client MockIdentityClient) GetAvailabilityDomainByName(ctx context.Context, compartmentID, name string) (*identity.AvailabilityDomain, error) {
792-
ad1 := "AD1"
792+
func (mockClient MockIdentityClient) GetAvailabilityDomainByName(ctx context.Context, compartmentID, name string) (*identity.AvailabilityDomain, error) {
793+
var ad1 string
794+
795+
if client.IsIpv6SingleStackCluster() {
796+
ad1 = "AD1-compartments-response"
797+
} else {
798+
ad1 = "AD1"
799+
}
793800
return &identity.AvailabilityDomain{Name: &ad1}, nil
794801
}
795802

@@ -2113,3 +2120,90 @@ func TestGetBVTags(t *testing.T) {
21132120
})
21142121
}
21152122
}
2123+
2124+
func TestClient_GetAvailabilityDomainByName(t *testing.T) {
2125+
tests := []struct {
2126+
name string
2127+
ipFamilies string
2128+
want *identity.AvailabilityDomain
2129+
wantErr error
2130+
}{
2131+
{
2132+
name: "Dual stack IPv4 preferred (identity client usage)",
2133+
ipFamilies: "IPv4,IPv6",
2134+
want: &identity.AvailabilityDomain{
2135+
Name: common.String("AD1"), // Default to AD1 since only exact IPv6 triggers change
2136+
},
2137+
wantErr: nil,
2138+
},
2139+
{
2140+
name: "Dual stack IPv6 preferred (identity client usage)",
2141+
ipFamilies: "IPv6,IPv4",
2142+
want: &identity.AvailabilityDomain{
2143+
Name: common.String("AD1"), // Default to AD1 since only exact IPv6 triggers change
2144+
},
2145+
wantErr: nil,
2146+
},
2147+
{
2148+
name: "IPv4 only (defaults to AD1)",
2149+
ipFamilies: "IPv4",
2150+
want: &identity.AvailabilityDomain{
2151+
Name: common.String("AD1"),
2152+
},
2153+
wantErr: nil,
2154+
},
2155+
{
2156+
name: "IPv6 only",
2157+
ipFamilies: "IPv6",
2158+
want: &identity.AvailabilityDomain{
2159+
Name: common.String("AD1-compartments-response"), // Specific to IPv6
2160+
},
2161+
wantErr: nil,
2162+
},
2163+
{
2164+
name: "Empty IP families (defaults to AD1)",
2165+
ipFamilies: "",
2166+
want: &identity.AvailabilityDomain{
2167+
Name: common.String("AD1"),
2168+
},
2169+
wantErr: nil,
2170+
},
2171+
{
2172+
name: "Invalid IP families (defaults to AD1)",
2173+
ipFamilies: "Invalid",
2174+
want: &identity.AvailabilityDomain{
2175+
Name: common.String("AD1"), // Invalid defaults to AD1
2176+
},
2177+
wantErr: nil,
2178+
},
2179+
}
2180+
2181+
for _, tt := range tests {
2182+
t.Run(tt.name, func(t *testing.T) {
2183+
// Set the environment variable for IP families
2184+
os.Setenv(client.ClusterIpFamilyEnv, tt.ipFamilies)
2185+
defer os.Unsetenv(client.ClusterIpFamilyEnv)
2186+
2187+
ctx, cancel := context.WithTimeout(context.Background(), testTimeout)
2188+
defer cancel()
2189+
2190+
client := NewClientProvisioner(nil, &MockBlockStorageClient{}, nil)
2191+
got, err := client.Identity(nil).GetAvailabilityDomainByName(ctx, "ocid1.compartment.abcd", "AD-1")
2192+
2193+
// Check if the error matches what we expect
2194+
if tt.wantErr == nil && err != nil {
2195+
t.Errorf("got error %q, want none", err)
2196+
}
2197+
if tt.wantErr != nil && err == nil {
2198+
t.Errorf("want error %q, got none", tt.wantErr)
2199+
} else if tt.wantErr != nil && err != nil && !strings.Contains(err.Error(), tt.wantErr.Error()) {
2200+
t.Errorf("want error %q to include %q", err, tt.wantErr)
2201+
}
2202+
2203+
// Check if the result matches what we expect
2204+
if !reflect.DeepEqual(got, tt.want) {
2205+
t.Errorf("client.Identity().GetAvailabilityDomainByName() = %v, want %v", got, tt.want)
2206+
}
2207+
})
2208+
}
2209+
}

pkg/oci/client/client.go

Lines changed: 43 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,11 @@ type Interface interface {
5151
}
5252

5353
type OCIClientConfig struct {
54-
SaToken *authv1.TokenRequest
54+
SaToken *authv1.TokenRequest
5555
ParentRptURL string
56-
TenancyId string
56+
TenancyId string
5757
}
58+
5859
// RateLimiter reader and writer.
5960
type RateLimiter struct {
6061
Reader flowcontrol.RateLimiter
@@ -170,6 +171,11 @@ type identityClient interface {
170171
ListAvailabilityDomains(ctx context.Context, request identity.ListAvailabilityDomainsRequest) (identity.ListAvailabilityDomainsResponse, error)
171172
}
172173

174+
// TODO: Uncomment when compartments is available in OCI Go-SDK
175+
//type compartmentClient interface {
176+
// ListAvailabilityDomains(ctx context.Context, request compartments.ListAvailabilityDomainsRequest) (compartments.ListAvailabilityDomainsResponse, error)
177+
//}
178+
173179
type client struct {
174180
compute computeClient
175181
network virtualNetworkClient
@@ -178,6 +184,7 @@ type client struct {
178184
filestorage filestorageClient
179185
bs blockstorageClient
180186
identity identityClient
187+
//compartment compartmentClient
181188

182189
requestMetadata common.RequestMetadata
183190
rateLimiter RateLimiter
@@ -239,6 +246,17 @@ func New(logger *zap.SugaredLogger, cp common.ConfigurationProvider, opRateLimit
239246
return nil, errors.Wrap(err, "configuring identity service client custom transport")
240247
}
241248

249+
// TODO: Uncomment when compartments is available in OCI Go-SDK
250+
//compartment, err := compartments.NewCompartmentsClientWithConfigurationProvider(cp)
251+
//if err != nil {
252+
// return nil, errors.Wrap(err, "NewCompartmentsClientWithConfigurationProvider")
253+
//}
254+
//
255+
//err = configureCustomTransport(logger, &compartment.BaseClient)
256+
//if err != nil {
257+
// return nil, errors.Wrap(err, "configuring compartment service client custom transport")
258+
//}
259+
242260
bs, err := core.NewBlockstorageClientWithConfigurationProvider(cp)
243261
if err != nil {
244262
return nil, errors.Wrap(err, "NewBlockstorageClientWithConfigurationProvider")
@@ -282,6 +300,7 @@ func New(logger *zap.SugaredLogger, cp common.ConfigurationProvider, opRateLimit
282300
networkloadbalancer: &networkloadbalancer,
283301
bs: &bs,
284302
filestorage: &fss,
303+
//compartment: &compartment,
285304

286305
rateLimiter: *opRateLimiter,
287306
requestMetadata: requestMetadata,
@@ -360,7 +379,7 @@ func (c *client) LoadBalancer(logger *zap.SugaredLogger, lbType string, targetTe
360379
}
361380

362381
func (c *client) Networking(ociClientConfig *OCIClientConfig) NetworkingInterface {
363-
if ociClientConfig == nil{
382+
if ociClientConfig == nil {
364383
return c
365384
}
366385
if ociClientConfig.SaToken != nil {
@@ -374,7 +393,7 @@ func (c *client) Networking(ociClientConfig *OCIClientConfig) NetworkingInterfac
374393

375394
err = configureCustomTransport(c.logger, &network.BaseClient)
376395
if err != nil {
377-
c.logger.Error("Failed configure custom transport for Network Client %v", err)
396+
c.logger.Error("Failed configure custom transport for Network Client %v", err)
378397
return nil
379398
}
380399

@@ -410,16 +429,30 @@ func (c *client) Identity(ociClientConfig *OCIClientConfig) IdentityInterface {
410429

411430
err = configureCustomTransport(c.logger, &identity.BaseClient)
412431
if err != nil {
413-
c.logger.Error("Failed configure custom transport for Identity Client %v", err)
432+
c.logger.Error("Failed configure custom transport for Identity Client %v", err)
414433
return nil
415434
}
416435

436+
// TODO: Uncomment when compartments is available in OCI Go-SDK
437+
//compartment, err := compartments.NewCompartmentsClientWithConfigurationProvider(configProvider)
438+
//if err != nil {
439+
// c.logger.Errorf("Failed to create Compartments workload identity client %v", err)
440+
// return nil
441+
//}
442+
//
443+
//err = configureCustomTransport(c.logger, &compartment.BaseClient)
444+
//if err != nil {
445+
// c.logger.Error("Failed configure custom transport for Compartments Client %v", err)
446+
// return nil
447+
//}
448+
417449
return &client{
418-
identity: &identity,
419-
requestMetadata: c.requestMetadata,
420-
rateLimiter: c.rateLimiter,
421-
subnetCache: cache.NewTTLStore(subnetCacheKeyFn, time.Duration(24)*time.Hour),
422-
logger: c.logger,
450+
//compartment: &compartment,
451+
identity: &identity,
452+
requestMetadata: c.requestMetadata,
453+
rateLimiter: c.rateLimiter,
454+
subnetCache: cache.NewTTLStore(subnetCacheKeyFn, time.Duration(24)*time.Hour),
455+
logger: c.logger,
423456
}
424457
}
425458
return c

pkg/oci/client/identity.go

Lines changed: 50 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -28,19 +28,66 @@ import (
2828
// by the volume provisioner.
2929
type IdentityInterface interface {
3030
GetAvailabilityDomainByName(ctx context.Context, compartmentID, name string) (*identity.AvailabilityDomain, error)
31-
ListAvailabilityDomains(ctx context.Context, compartmentID string) ([]identity.AvailabilityDomain, error)
3231
}
3332

34-
func (c *client) ListAvailabilityDomains(ctx context.Context, compartmentID string) ([]identity.AvailabilityDomain, error) {
33+
func (c *client) GetAvailabilityDomainByName(ctx context.Context, compartmentID, name string) (*identity.AvailabilityDomain, error) {
3534
if !c.rateLimiter.Reader.TryAccept() {
3635
return nil, RateLimitError(false, "ListAvailabilityDomains")
3736
}
3837

38+
var availabilityDomains []identity.AvailabilityDomain
39+
var err error
40+
41+
// TODO: Uncomment when compartments is available in OCI Go-SDK
42+
//if IsIpv6SingleStackCluster() {
43+
// availabilityDomains, err = c.listAvailabilityDomainsV6(ctx, compartmentID)
44+
//} else {
45+
availabilityDomains, err = c.listAvailabilityDomains(ctx, compartmentID)
46+
//}
47+
48+
if err != nil {
49+
return nil, err
50+
}
51+
52+
// Find the desired availability domain by name
53+
for _, ad := range availabilityDomains {
54+
if strings.HasSuffix(strings.ToLower(*ad.Name), strings.ToLower(name)) {
55+
return &ad, nil
56+
}
57+
}
58+
return nil, fmt.Errorf("availability domain '%s' not found in list: %v", name, availabilityDomains)
59+
}
60+
61+
// listAvailabilityDomainsV6 lists availability domains for IPv6 single-stack clusters.
62+
//func (c *client) listAvailabilityDomainsV6(ctx context.Context, compartmentID string) ([]identity.AvailabilityDomain, error) {
63+
// resp, err := c.compartment.ListAvailabilityDomains(ctx, compartments.ListAvailabilityDomainsRequest{
64+
// CompartmentId: &compartmentID,
65+
// RequestMetadata: c.requestMetadata,
66+
// })
67+
// if resp.OpcRequestId != nil {
68+
// c.logger.With("service", "Compartment", "verb", listVerb).
69+
// With("OpcRequestId", *(resp.OpcRequestId)).With("statusCode", util.GetHttpStatusCode(err)).
70+
// Info("OPC Request ID recorded for Compartment ListAvailabilityDomains call.")
71+
// }
72+
// incRequestCounter(err, listVerb, availabilityDomainResource)
73+
// if err != nil {
74+
// return nil, errors.WithStack(err)
75+
// }
76+
//
77+
// availabilityDomains := make([]identity.AvailabilityDomain, len(resp.Items))
78+
// for i, ad := range resp.Items {
79+
// availabilityDomains[i] = identity.AvailabilityDomain{Name: ad.Name}
80+
// }
81+
// return availabilityDomains, nil
82+
//}
83+
84+
// listAvailabilityDomains lists availability domains for regular clusters.
85+
func (c *client) listAvailabilityDomains(ctx context.Context, compartmentID string) ([]identity.AvailabilityDomain, error) {
3986
resp, err := c.identity.ListAvailabilityDomains(ctx, identity.ListAvailabilityDomainsRequest{
4087
CompartmentId: &compartmentID,
4188
RequestMetadata: c.requestMetadata,
4289
})
43-
if resp.OpcRequestId != nil{
90+
if resp.OpcRequestId != nil {
4491
c.logger.With("service", "Identity", "verb", listVerb).
4592
With("OpcRequestId", *(resp.OpcRequestId)).With("statusCode", util.GetHttpStatusCode(err)).
4693
Info("OPC Request ID recorded for ListAvailabilityDomains call.")
@@ -52,17 +99,3 @@ func (c *client) ListAvailabilityDomains(ctx context.Context, compartmentID stri
5299

53100
return resp.Items, nil
54101
}
55-
56-
func (c *client) GetAvailabilityDomainByName(ctx context.Context, compartmentID, name string) (*identity.AvailabilityDomain, error) {
57-
ads, err := c.ListAvailabilityDomains(ctx, compartmentID)
58-
if err != nil {
59-
return nil, err
60-
}
61-
// TODO: Add paging when implemented in oci-go-sdk.
62-
for _, ad := range ads {
63-
if strings.HasSuffix(strings.ToLower(*ad.Name), strings.ToLower(name)) {
64-
return &ad, nil
65-
}
66-
}
67-
return nil, fmt.Errorf("error looking up availability domain '%s':%v", name, ads)
68-
}

0 commit comments

Comments
 (0)