Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:

steps:
- name: Checkout Code
uses: actions/checkout@v4
uses: actions/checkout@v5

- name: Print Go Version
run: go version
Expand Down Expand Up @@ -65,7 +65,7 @@ jobs:
/home/runner/work/ibm-object-csi-driver/ibm-object-csi-driver/cos-csi-mounter/cos-csi-mounter-${{ env.APP_VERSION }}.rpm.tar.gz.sha256
tag_name: v1.0.3
name: v1.0.3
## body:
## body:
prerelease: ${{ env.IS_LATEST_RELEASE != 'true' }}

- name: Perform CodeQL Analysis
Expand Down
6 changes: 3 additions & 3 deletions .secrets.baseline
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"files": "go.sum|^.secrets.baseline$",
"lines": null
},
"generated_at": "2025-08-08T10:24:11Z",
"generated_at": "2025-08-25T02:32:44Z",
"plugins_used": [
{
"name": "AWSKeyDetector"
Expand Down Expand Up @@ -209,7 +209,7 @@
"hashed_secret": "39f69c278f46165447f30d10acf54277aaa3d5fc",
"is_secret": false,
"is_verified": false,
"line_number": 85,
"line_number": 86,
"type": "Secret Keyword",
"verified_result": null
}
Expand Down Expand Up @@ -270,7 +270,7 @@
{
"hashed_secret": "c7c6508b19455e3e8040e60e9833fbede92e5d8e",
"is_verified": false,
"line_number": 356,
"line_number": 368,
"type": "Secret Keyword",
"verified_result": null
}
Expand Down
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
dist: bionic
language: go
go:
- 1.24.5
- 1.25.0

group: bluezone

Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ FROM registry.access.redhat.com/ubi8/ubi AS rclone-builder
RUN yum install wget git gcc -y

ENV ARCH=amd64
ENV GO_VERSION=1.24.5
ENV GO_VERSION=1.25.0

RUN echo $ARCH $GO_VERSION

Expand Down
2 changes: 1 addition & 1 deletion Dockerfile.builder
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM golang:1.24.5
FROM golang:1.25.0

WORKDIR /go/src/github.com/IBM/ibm-object-csi-driver
ADD . /go/src/github.com/IBM/ibm-object-csi-driver
Expand Down
2 changes: 1 addition & 1 deletion deploy/ibmCloud/kustomization.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ images:
newName: k8s.gcr.io/sig-storage/csi-node-driver-registrar
newTag: v2.12.0
- newName: registry.k8s.io/sig-storage/livenessprobe
newTag: v2.14.0
newTag: v2.16.0
name: liveness-probe-image
commonLabels:
app.kubernetes.io/part-of: ibm-object-csi-driver
Expand Down
2 changes: 1 addition & 1 deletion deploy/ibmUnmanaged/kustomization.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ images:
newName: k8s.gcr.io/sig-storage/csi-node-driver-registrar
newTag: v2.12.0
- newName: registry.k8s.io/sig-storage/livenessprobe
newTag: v2.14.0
newTag: v2.16.0
name: liveness-probe-image
commonLabels:
app.kubernetes.io/part-of: ibm-object-csi-driver
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ require (
go.uber.org/zap v1.27.0
golang.org/x/net v0.43.0
google.golang.org/grpc v1.74.2
google.golang.org/protobuf v1.36.6
google.golang.org/protobuf v1.36.7
k8s.io/api v0.33.4
k8s.io/apimachinery v0.33.4
k8s.io/client-go v0.33.4
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -392,8 +392,8 @@ google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a h1:
google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
google.golang.org/grpc v1.74.2 h1:WoosgB65DlWVC9FqI82dGsZhWFNBSLjQ84bjROOpMu4=
google.golang.org/grpc v1.74.2/go.mod h1:CtQ+BGjaAIXHs/5YS3i473GqwBBa1zGQNevxdeBEXrM=
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
google.golang.org/protobuf v1.36.7 h1:IgrO7UwFQGJdRNXH/sQux4R1Dj1WAKcLElzeeRaXV2A=
google.golang.org/protobuf v1.36.7/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
Expand Down
3 changes: 2 additions & 1 deletion pkg/constants/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ package constants
import "time"

const (
DefaultIAMEndPoint = "https://iam.cloud.ibm.com"
PublicIAMEndpoint = "https://iam.cloud.ibm.com"
PrivateIAMEndpoint = "https://private.iam.cloud.ibm.com"

// Maximum number of volumes that controller can publish to the node.
// If value is not set or zero CO SHALL decide how many volumes of
Expand Down
10 changes: 5 additions & 5 deletions pkg/driver/controllerserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ func (cs *controllerServer) CreateVolume(_ context.Context, req *csi.CreateVolum
klog.Infof("BucketVersioning value that will be set via storage class params: %s", bucketVersioning)
}

creds, err := getCredentials(secretMap)
creds, err := getObjectStorageCredentialsFromSecret(secretMap, cs.iamEndpoint)
if err != nil {
return nil, status.Error(codes.InvalidArgument, fmt.Sprintf("Error in getting credentials %v", err))
}
Expand Down Expand Up @@ -325,7 +325,7 @@ func (cs *controllerServer) DeleteVolume(_ context.Context, req *csi.DeleteVolum
secretMap = secretMapCustom
}

creds, err := getCredentials(secretMap)
creds, err := getObjectStorageCredentialsFromSecret(secretMap, cs.iamEndpoint)
if err != nil {
return nil, status.Error(codes.InvalidArgument, fmt.Sprintf("Error in getting credentials %v", err))
}
Expand Down Expand Up @@ -438,8 +438,8 @@ func (cs *controllerServer) ControllerModifyVolume(_ context.Context, req *csi.C
return nil, status.Error(codes.Unimplemented, "ControllerModifyVolume")
}

func getCredentials(secretMap map[string]string) (*s3client.ObjectStorageCredentials, error) {
klog.Infof("- getCredentials-")
func getObjectStorageCredentialsFromSecret(secretMap map[string]string, iamEP string) (*s3client.ObjectStorageCredentials, error) {
klog.Infof("- getObjectStorageCredentialsFromSecret-")
var (
accessKey string
secretKey string
Expand All @@ -453,7 +453,7 @@ func getCredentials(secretMap map[string]string) (*s3client.ObjectStorageCredent
iamEndpoint = val
}
if iamEndpoint == "" {
iamEndpoint = constants.DefaultIAMEndPoint
iamEndpoint = iamEP
}

if val, check := secretMap["apiKey"]; check {
Expand Down
6 changes: 6 additions & 0 deletions pkg/driver/controllerserver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,9 @@ func TestCreateVolume(t *testing.T) {
t.Log("Testcase being executed", zap.String("testcase", tc.testCaseName))

controllerServer := &controllerServer{
S3Driver: &S3Driver{
iamEndpoint: constants.PublicIAMEndpoint,
},
cosSession: tc.cosSession,
Stats: tc.driverStatsUtils,
}
Expand Down Expand Up @@ -720,6 +723,9 @@ func TestDeleteVolume(t *testing.T) {
defer teardown()

controllerServer := &controllerServer{
S3Driver: &S3Driver{
iamEndpoint: constants.PublicIAMEndpoint,
},
Stats: tc.driverStatsUtils,
cosSession: tc.cosSession,
Logger: lgr,
Expand Down
4 changes: 4 additions & 0 deletions pkg/driver/nodeserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,10 @@ func (ns *nodeServer) NodePublishVolume(_ context.Context, req *csi.NodePublishV
return nil, status.Error(codes.InvalidArgument, "S3 Service endpoint not provided")
}

if len(secretMap["iamEndpoint"]) == 0 {
secretMap["iamEndpoint"] = ns.iamEndpoint
}

// If bucket name wasn't provided by user, we use temp bucket created for volume.
if secretMap["bucketName"] == "" {
tempBucketName, err := ns.Stats.GetBucketNameFromPV(volumeID)
Expand Down
3 changes: 3 additions & 0 deletions pkg/driver/nodeserver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,9 @@ func TestNodePublishVolume(t *testing.T) {
t.Log("Testcase being executed", zap.String("testcase", tc.testCaseName))

nodeServer := nodeServer{
S3Driver: &S3Driver{
iamEndpoint: constants.PublicIAMEndpoint,
},
Stats: tc.driverStatsUtils,
Mounter: tc.Mounter,
}
Expand Down
17 changes: 13 additions & 4 deletions pkg/driver/s3-driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
pkgUtils "github.com/IBM/ibm-object-csi-driver/pkg/utils"
csi "github.com/container-storage-interface/spec/lib/go/csi"
"go.uber.org/zap"
"k8s.io/klog/v2"
)

var (
Expand All @@ -45,10 +46,11 @@ var (
)

type S3Driver struct {
name string
version string
mode string
endpoint string
name string
version string
mode string
endpoint string
iamEndpoint string

s3client s3client.ObjectStorageSession

Expand Down Expand Up @@ -170,6 +172,13 @@ func (driver *S3Driver) NewS3CosDriver(nodeID string, endpoint string, s3cosSess
return nil, err
}

iamEP, _, err := statsUtil.GetEndpoints()
if err != nil {
return nil, err
}
klog.Infof("iam endpoint: %v", iamEP)
driver.iamEndpoint = iamEP

driver.endpoint = endpoint
driver.s3client = s3client

Expand Down
23 changes: 22 additions & 1 deletion pkg/driver/s3-driver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,11 @@ func TestNewS3CosDriver(t *testing.T) {
{
testCaseName: "Positive: controller mode",
mode: "controller",
statsUtils: utils.NewFakeStatsUtilsImpl(utils.FakeStatsUtilsFuncStruct{}),
statsUtils: utils.NewFakeStatsUtilsImpl(utils.FakeStatsUtilsFuncStruct{
GetEndpointsFn: func() (string, string, error) {
return constants.PublicIAMEndpoint, "", nil
},
}),
verifyResult: func(t *testing.T, driver *S3Driver, err error) {
assert.NoError(t, err)
assert.NotEmpty(t, driver.cs)
Expand All @@ -263,6 +267,9 @@ func TestNewS3CosDriver(t *testing.T) {
testCaseName: "Positive: node mode",
mode: "node",
statsUtils: utils.NewFakeStatsUtilsImpl(utils.FakeStatsUtilsFuncStruct{
GetEndpointsFn: func() (string, string, error) {
return constants.PublicIAMEndpoint, "", nil
},
GetRegionAndZoneFn: func(nodeName string) (string, string, error) { return testRegion, testZone, nil },
}),
verifyResult: func(t *testing.T, driver *S3Driver, err error) {
Expand All @@ -277,6 +284,9 @@ func TestNewS3CosDriver(t *testing.T) {
testCaseName: "Positive: controller and node mode",
mode: "controller-node",
statsUtils: utils.NewFakeStatsUtilsImpl(utils.FakeStatsUtilsFuncStruct{
GetEndpointsFn: func() (string, string, error) {
return constants.PublicIAMEndpoint, "", nil
},
GetRegionAndZoneFn: func(nodeName string) (string, string, error) { return testRegion, testZone, nil },
}),
verifyResult: func(t *testing.T, driver *S3Driver, err error) {
Expand All @@ -288,6 +298,17 @@ func TestNewS3CosDriver(t *testing.T) {
},
expectedErr: nil,
},
{
testCaseName: "Negative: Failed to GetEndpoints",
mode: "controller-node",
statsUtils: utils.NewFakeStatsUtilsImpl(utils.FakeStatsUtilsFuncStruct{
GetEndpointsFn: func() (string, string, error) {
return "", "", errors.New("failed")
},
}),
verifyResult: nil,
expectedErr: errors.New("failed"),
},
}

fakeCosSession := &s3client.FakeCOSSessionFactory{}
Expand Down
8 changes: 6 additions & 2 deletions pkg/mounter/mounter-s3fs.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ type S3fsMounter struct {
LocConstraint string //From Secret in SC
AuthType string
AccessKeys string
IAMEndpoint string
KpRootKeyCrn string
MountOptions []string
MounterUtils utils.MounterUtils
Expand Down Expand Up @@ -87,6 +88,9 @@ func NewS3fsMounter(secretMap map[string]string, mountOptions []string, mounterU
if val, check = secretMap["kpRootKeyCRN"]; check {
mounter.KpRootKeyCrn = val
}
if val, check = secretMap["iamEndpoint"]; check {
mounter.IAMEndpoint = val
}

if apiKey != "" {
mounter.AccessKeys = fmt.Sprintf(":%s", apiKey)
Expand Down Expand Up @@ -325,10 +329,10 @@ func (s3fs *S3fsMounter) formulateMountOptions(bucket, target, passwdFile string

if s3fs.AuthType != "hmac" {
nodeServerOp = append(nodeServerOp, "-o", "ibm_iam_auth")
nodeServerOp = append(nodeServerOp, "-o", "ibm_iam_endpoint="+constants.DefaultIAMEndPoint)
nodeServerOp = append(nodeServerOp, "-o", "ibm_iam_endpoint="+s3fs.IAMEndpoint)

workerNodeOp["ibm_iam_auth"] = "true"
workerNodeOp["ibm_iam_endpoint"] = constants.DefaultIAMEndPoint
workerNodeOp["ibm_iam_endpoint"] = s3fs.IAMEndpoint
} else {
nodeServerOp = append(nodeServerOp, "-o", "default_acl=private")
workerNodeOp["default_acl"] = "private"
Expand Down
1 change: 1 addition & 0 deletions pkg/mounter/mounter-s3fs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ func TestNewS3fsMounter_Success_Hmac(t *testing.T) {
"tmpdir": "test-tmpdir",
"use_cache": "true",
"gid": "test-gid",
"iamEndpoint": "test-iamEndpoint",
}

mountOptions := []string{"opt1=val1", "opt2=val2", " ", "opt3"}
Expand Down
26 changes: 19 additions & 7 deletions pkg/utils/driver_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ type StatsUtils interface {
GetBucketUsage(volumeID string) (int64, error)
GetBucketNameFromPV(volumeID string) (string, error)
GetRegionAndZone(nodeName string) (string, string, error)
GetEndpoints() (string, string, error)
GetPVAttributes(volumeID string) (map[string]string, error)
GetPVC(pvcName, pvcNamespace string) (*v1.PersistentVolumeClaim, error)
GetSecret(secretName, secretNamespace string) (*v1.Secret, error)
Expand Down Expand Up @@ -61,6 +62,21 @@ func (su *DriverStatsUtils) GetRegionAndZone(nodeName string) (region, zone stri
return region, zone, nil
}

// GetEndpoints return IAMEndpoint, COSResourceConfigEndpoint, error
func (su *DriverStatsUtils) GetEndpoints() (string, string, error) {
clusterType, err := getClusterType()
if err != nil {
return "", "", err
}

if strings.Contains(strings.ToLower(clusterType), "vpc") {
// Use private iam endpoint for VPC clusters
return constants.PrivateIAMEndpoint, constants.ResourceConfigEPDirect, nil
}
// Use public iam endpoint for classic clusters
return constants.PublicIAMEndpoint, constants.ResourceConfigEPPrivate, nil
}

func (su *DriverStatsUtils) BucketToDelete(volumeID string) (string, error) {
clientset, err := CreateK8sClient()
if err != nil {
Expand Down Expand Up @@ -115,7 +131,7 @@ func (su *DriverStatsUtils) GetTotalCapacityFromPV(volumeID string) (resource.Qu
}

func (su *DriverStatsUtils) GetBucketUsage(volumeID string) (int64, error) {
ep, err := getEPBasedOnCluserInfra()
_, ep, err := su.GetEndpoints()
if err != nil {
return 0, err
}
Expand Down Expand Up @@ -305,7 +321,7 @@ func CreateK8sClient() (*kubernetes.Clientset, error) {
return clientset, nil
}

func getEPBasedOnCluserInfra() (string, error) {
func getClusterType() (string, error) {
k8sClient, err := CreateK8sClient()
if err != nil {
return "", err
Expand All @@ -325,11 +341,7 @@ func getEPBasedOnCluserInfra() (string, error) {

clusterType := clusterConfig["cluster_type"]
klog.Info("Cluster Type ", clusterType)

if strings.Contains(clusterType, "vpc") {
return constants.ResourceConfigEPDirect, nil
}
return constants.ResourceConfigEPPrivate, nil
return clusterType, nil
}

func fetchSecretUsingPV(volumeID string, su *DriverStatsUtils) (*v1.Secret, error) {
Expand Down
Loading