forked from rook/rook
ceph: add support for update() from lib-bucket-provisioner
Recently lib-bucket-provisioner add support for update() API. Include that on the obc implementation since it can be used to update quota for OBC. Fixes: #7146 Signed-off-by: Jiffin Tony Thottan <thottanjiffin@gmail.com>
This commit is contained in:
@@ -15,7 +15,7 @@ require (
|
||||
github.com/google/uuid v1.1.2
|
||||
github.com/hashicorp/vault/api v1.0.5-0.20200902155336-f9d5ce5a171a
|
||||
github.com/k8snetworkplumbingwg/network-attachment-definition-client v1.1.0
|
||||
github.com/kube-object-storage/lib-bucket-provisioner v0.0.0-20210311161930-4bea5edaff58
|
||||
github.com/kube-object-storage/lib-bucket-provisioner v0.0.0-20210818162813-3eee31c01875
|
||||
github.com/libopenstorage/secrets v0.0.0-20210709082113-dde442ea20ec
|
||||
github.com/openshift/cluster-api v0.0.0-20191129101638-b09907ac6668
|
||||
github.com/openshift/machine-api-operator v0.2.1-0.20190903202259-474e14e4965a
|
||||
|
||||
@@ -719,8 +719,8 @@ github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/kube-object-storage/lib-bucket-provisioner v0.0.0-20210311161930-4bea5edaff58 h1:O9m6tfyhjr3F3yKGsgGMp1+seFyTRovmGMmbcNp6GSo=
|
||||
github.com/kube-object-storage/lib-bucket-provisioner v0.0.0-20210311161930-4bea5edaff58/go.mod h1:XpQ9HGG9uF5aJCBP+s6w5kSiyTIVSqCV8+XAE4qms5E=
|
||||
github.com/kube-object-storage/lib-bucket-provisioner v0.0.0-20210818162813-3eee31c01875 h1:jX3VXgmNOye8XYKjwcTVXcBYcPv3jj657fwX8DN/HiM=
|
||||
github.com/kube-object-storage/lib-bucket-provisioner v0.0.0-20210818162813-3eee31c01875/go.mod h1:XpQ9HGG9uF5aJCBP+s6w5kSiyTIVSqCV8+XAE4qms5E=
|
||||
github.com/kubernetes-csi/csi-lib-utils v0.9.1 h1:sGq6ifVujfMSkfTsMZip44Ttv8SDXvsBlFk9GdYl/b8=
|
||||
github.com/kubernetes-csi/csi-lib-utils v0.9.1/go.mod h1:8E2jVUX9j3QgspwHXa6LwyN7IHQDjW9jX3kwoWnSC+M=
|
||||
github.com/kubernetes-csi/external-snapshotter/client/v4 v4.0.0/go.mod h1:YBCo4DoEeDndqvAn6eeu0vWM7QdXmHEeI9cFWplmBys=
|
||||
|
||||
@@ -554,8 +554,8 @@ func (p *Provisioner) deleteOBCResourceLogError(bucketname string) {
|
||||
// Check for additional options mentioned in OBC and set them accordingly
|
||||
func (p Provisioner) setAdditionalSettings(options *apibkt.BucketOptions) error {
|
||||
quotaEnabled := true
|
||||
maxObjects := MaxObjectQuota(options)
|
||||
maxSize := MaxSizeQuota(options)
|
||||
maxObjects := MaxObjectQuota(options.ObjectBucketClaim.Spec.AdditionalConfig)
|
||||
maxSize := MaxSizeQuota(options.ObjectBucketClaim.Spec.AdditionalConfig)
|
||||
if maxObjects == "" && maxSize == "" {
|
||||
return nil
|
||||
}
|
||||
@@ -665,3 +665,69 @@ func (p *Provisioner) setAdminOpsAPIClient() error {
|
||||
|
||||
return nil
|
||||
}
|
||||
func (p Provisioner) updateAdditionalSettings(ob *bktv1alpha1.ObjectBucket) error {
|
||||
var maxObjectsInt64 int64
|
||||
var maxSizeInt64 int64
|
||||
var err error
|
||||
var quotaEnabled bool
|
||||
maxObjects := MaxObjectQuota(ob.Spec.Endpoint.AdditionalConfigData)
|
||||
maxSize := MaxSizeQuota(ob.Spec.Endpoint.AdditionalConfigData)
|
||||
if maxObjects != "" {
|
||||
maxObjectsInt, err := strconv.Atoi(maxObjects)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to convert maxObjects to integer")
|
||||
}
|
||||
maxObjectsInt64 = int64(maxObjectsInt)
|
||||
}
|
||||
if maxSize != "" {
|
||||
maxSizeInt64, err = maxSizeToInt64(maxSize)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to parse maxSize quota for user %q", p.cephUserName)
|
||||
}
|
||||
}
|
||||
objectUser, err := p.adminOpsClient.GetUser(context.TODO(), admin.User{ID: ob.Spec.Connection.AdditionalState[cephUser]})
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to fetch user %q", p.cephUserName)
|
||||
}
|
||||
if *objectUser.UserQuota.Enabled &&
|
||||
(maxObjects == "" || maxObjectsInt64 < 0) &&
|
||||
(maxSize == "" || maxSizeInt64 < 0) {
|
||||
quotaEnabled = false
|
||||
err = p.adminOpsClient.SetUserQuota(context.TODO(), admin.QuotaSpec{UID: p.cephUserName, Enabled: "aEnabled})
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to disable quota to user %q", p.cephUserName)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
quotaEnabled = true
|
||||
quotaSpec := admin.QuotaSpec{UID: p.cephUserName, Enabled: "aEnabled}
|
||||
|
||||
//MaxObject is modified
|
||||
if maxObjects != "" && (maxObjectsInt64 != *objectUser.UserQuota.MaxObjects) {
|
||||
quotaSpec.MaxObjects = &maxObjectsInt64
|
||||
}
|
||||
|
||||
//MaxSize is modified
|
||||
if maxSize != "" && (maxSizeInt64 != *objectUser.UserQuota.MaxSize) {
|
||||
quotaSpec.MaxSize = &maxSizeInt64
|
||||
}
|
||||
err = p.adminOpsClient.SetUserQuota(context.TODO(), quotaSpec)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to update quota to user %q", p.cephUserName)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Update is sent when only there is modification to AdditionalConfig field in OBC
|
||||
func (p Provisioner) Update(ob *bktv1alpha1.ObjectBucket) error {
|
||||
logger.Debugf("Update event for OB: %+v", ob)
|
||||
|
||||
err := p.initializeDeleteOrRevoke(ob)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return p.updateAdditionalSettings(ob)
|
||||
}
|
||||
|
||||
@@ -23,7 +23,6 @@ import (
|
||||
"github.com/coreos/pkg/capnslog"
|
||||
bktv1alpha1 "github.com/kube-object-storage/lib-bucket-provisioner/pkg/apis/objectbucket.io/v1alpha1"
|
||||
"github.com/kube-object-storage/lib-bucket-provisioner/pkg/provisioner"
|
||||
apibkt "github.com/kube-object-storage/lib-bucket-provisioner/pkg/provisioner/api"
|
||||
"github.com/pkg/errors"
|
||||
storagev1 "k8s.io/api/storage/v1"
|
||||
kerrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
@@ -117,10 +116,10 @@ func randomString(n int) string {
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func MaxObjectQuota(options *apibkt.BucketOptions) string {
|
||||
return options.ObjectBucketClaim.Spec.AdditionalConfig["maxObjects"]
|
||||
func MaxObjectQuota(AdditionalConfig map[string]string) string {
|
||||
return AdditionalConfig["maxObjects"]
|
||||
}
|
||||
|
||||
func MaxSizeQuota(options *apibkt.BucketOptions) string {
|
||||
return options.ObjectBucketClaim.Spec.AdditionalConfig["maxSize"]
|
||||
func MaxSizeQuota(AdditionalConfig map[string]string) string {
|
||||
return AdditionalConfig["maxSize"]
|
||||
}
|
||||
|
||||
@@ -53,6 +53,10 @@ func (b *BucketOperation) DeleteObc(obcName string, storageClassName string, buc
|
||||
return b.k8sh.ResourceOperation("delete", b.manifests.GetOBC(obcName, storageClassName, bucketName, maxObject, createBucket))
|
||||
}
|
||||
|
||||
func (b *BucketOperation) UpdateObc(obcName string, storageClassName string, bucketName string, maxObject string, createBucket bool) error {
|
||||
return b.k8sh.ResourceOperation("apply", b.manifests.GetOBC(obcName, storageClassName, bucketName, maxObject, createBucket))
|
||||
}
|
||||
|
||||
// CheckOBC, returns true if the obc, secret and configmap are all in the "check" state,
|
||||
// and returns false if any of these resources are not in the "check" state.
|
||||
// Check state values:
|
||||
@@ -123,3 +127,10 @@ func (b *BucketOperation) GetSecretKey(obcName string) (string, error) {
|
||||
return string(decode), nil
|
||||
|
||||
}
|
||||
|
||||
// Checks whether MaxObject is updated for ob
|
||||
func (b *BucketOperation) CheckOBMaxObject(obcName, maxobject string) bool {
|
||||
obName, _ := b.k8sh.GetResource("obc", obcName, "--output", "jsonpath={.spec.objectBucketName}")
|
||||
fetchMaxObject, _ := b.k8sh.GetResource("ob", obName, "--output", "jsonpath={.spec.endpoint.additionalConfig.maxObjects}")
|
||||
return maxobject == fetchMaxObject
|
||||
}
|
||||
|
||||
@@ -48,10 +48,12 @@ var (
|
||||
ObjectKey1 = "rookObj1"
|
||||
ObjectKey2 = "rookObj2"
|
||||
ObjectKey3 = "rookObj3"
|
||||
ObjectKey4 = "rookObj4"
|
||||
contentType = "plain/text"
|
||||
obcName = "smoke-delete-bucket"
|
||||
region = "us-east-1"
|
||||
maxObject = "2"
|
||||
newMaxObject = "3"
|
||||
bucketStorageClassName = "rook-smoke-delete-bucket"
|
||||
)
|
||||
|
||||
@@ -280,11 +282,27 @@ func testObjectStoreOperations(s suite.Suite, helper *clients.TestClient, k8sh *
|
||||
assert.Error(s.T(), poErr)
|
||||
})
|
||||
|
||||
t.Run("test update quota on OBC bucket", func(t *testing.T) {
|
||||
poErr := helper.BucketClient.UpdateObc(obcName, bucketStorageClassName, bucketname, newMaxObject, true)
|
||||
assert.Nil(s.T(), poErr)
|
||||
updated := utils.Retry(5, 2*time.Second, "OBC is updated", func() bool {
|
||||
return helper.BucketClient.CheckOBMaxObject(obcName, newMaxObject)
|
||||
})
|
||||
assert.True(s.T(), updated)
|
||||
logger.Infof("Testing the updated object limit")
|
||||
_, poErr = s3client.PutObjectInBucket(bucketname, ObjBody, ObjectKey3, contentType)
|
||||
assert.NoError(s.T(), poErr)
|
||||
_, poErr = s3client.PutObjectInBucket(bucketname, ObjBody, ObjectKey4, contentType)
|
||||
assert.Error(s.T(), poErr)
|
||||
})
|
||||
|
||||
t.Run("delete objects on OBC bucket", func(t *testing.T) {
|
||||
_, delobjErr := s3client.DeleteObjectInBucket(bucketname, ObjectKey1)
|
||||
assert.Nil(s.T(), delobjErr)
|
||||
_, delobjErr = s3client.DeleteObjectInBucket(bucketname, ObjectKey2)
|
||||
assert.Nil(s.T(), delobjErr)
|
||||
_, delobjErr = s3client.DeleteObjectInBucket(bucketname, ObjectKey3)
|
||||
assert.Nil(s.T(), delobjErr)
|
||||
logger.Info("Objects deleted on bucket successfully")
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user