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:
Jiffin Tony Thottan
2021-08-19 23:57:11 +05:30
parent 67acab94dd
commit f4bb47e440
6 changed files with 104 additions and 10 deletions
+1 -1
View File
@@ -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
+2 -2
View File
@@ -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=
+68 -2
View File
@@ -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: &quotaEnabled})
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: &quotaEnabled}
//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)
}
+4 -5
View File
@@ -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"]
}
+11
View File
@@ -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")
})
})