mirror of
https://github.com/ceph/ceph-csi.git
synced 2024-12-18 02:50:30 +00:00
rbd: parse migration secret and set it for controller server operations
This commit adds a couple of helper functions to parse the migration request secret and set it for further csi driver operations. More details: The intree secret has a data field called "key" which is the base64 admin secret key. The ceph CSI driver currently expect the secret to contain data field "UserKey" for the equivalant. The CSI driver also expect the "UserID" field which is not available in the in-tree secret by deafult. This missing userID will be filled (if the username differ than 'admin') in the migration secret as 'adminId' field in the migration request, this commit adds the logic to parse this migration secret as below: "key" field value will be picked up from the migraion secret to "UserKey" field. "adminId" field value will be picked up from the migration secret to "UserID" field if `adminId` field is nil or not set, `UserID` field will be filled with default value ie `admin`.The above logic get activated only when the secret is a migration secret, otherwise skipped to the normal workflow as we have today. Signed-off-by: Humble Chirammal <hchiramm@redhat.com>
This commit is contained in:
parent
b132696e54
commit
b49bf4b987
@ -808,25 +808,34 @@ func (cs *ControllerServer) checkErrAndUndoReserve(
|
||||
func (cs *ControllerServer) DeleteVolume(
|
||||
ctx context.Context,
|
||||
req *csi.DeleteVolumeRequest) (*csi.DeleteVolumeResponse, error) {
|
||||
if err := cs.Driver.ValidateControllerServiceRequest(
|
||||
var err error
|
||||
if err = cs.Driver.ValidateControllerServiceRequest(
|
||||
csi.ControllerServiceCapability_RPC_CREATE_DELETE_VOLUME); err != nil {
|
||||
log.ErrorLog(ctx, "invalid delete volume req: %v", protosanitizer.StripSecrets(req))
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cr, err := util.NewUserCredentials(req.GetSecrets())
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
defer cr.DeleteCredentials()
|
||||
|
||||
// For now the image get unconditionally deleted, but here retention policy can be checked
|
||||
volumeID := req.GetVolumeId()
|
||||
if volumeID == "" {
|
||||
return nil, status.Error(codes.InvalidArgument, "empty volume ID in request")
|
||||
}
|
||||
|
||||
secrets := req.GetSecrets()
|
||||
if util.IsMigrationSecret(secrets) {
|
||||
secrets, err = util.ParseAndSetSecretMapFromMigSecret(secrets)
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.InvalidArgument, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
cr, err := util.NewUserCredentials(secrets)
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
defer cr.DeleteCredentials()
|
||||
|
||||
if acquired := cs.VolumeLocks.TryAcquire(volumeID); !acquired {
|
||||
log.ErrorLog(ctx, util.VolumeOperationAlreadyExistsFmt, volumeID)
|
||||
|
||||
@ -852,7 +861,7 @@ func (cs *ControllerServer) DeleteVolume(
|
||||
return &csi.DeleteVolumeResponse{}, nil
|
||||
}
|
||||
|
||||
rbdVol, err := genVolFromVolID(ctx, volumeID, cr, req.GetSecrets())
|
||||
rbdVol, err := genVolFromVolID(ctx, volumeID, cr, secrets)
|
||||
defer rbdVol.Destroy()
|
||||
if err != nil {
|
||||
return cs.checkErrAndUndoReserve(ctx, err, volumeID, rbdVol, cr)
|
||||
|
@ -31,6 +31,9 @@ const (
|
||||
credMonitors = "monitors"
|
||||
tmpKeyFileLocation = "/tmp/csi/keys"
|
||||
tmpKeyFileNamePrefix = "keyfile-"
|
||||
migUserName = "admin"
|
||||
migUserID = "adminId"
|
||||
migUserKey = "key"
|
||||
)
|
||||
|
||||
// Credentials struct represents credentials to access the ceph cluster.
|
||||
@ -119,3 +122,34 @@ func GetMonValFromSecret(secrets map[string]string) (string, error) {
|
||||
|
||||
return "", fmt.Errorf("missing %q", credMonitors)
|
||||
}
|
||||
|
||||
// ParseAndSetSecretMapFromMigSecret parse the secretmap from the migration request and return
|
||||
// newsecretmap with the userID and userKey fields set.
|
||||
func ParseAndSetSecretMapFromMigSecret(secretmap map[string]string) (map[string]string, error) {
|
||||
newSecretMap := make(map[string]string)
|
||||
// parse and set userKey
|
||||
if !IsMigrationSecret(secretmap) {
|
||||
return nil, errors.New("passed secret map does not contain user key or it is nil")
|
||||
}
|
||||
newSecretMap[credUserKey] = secretmap[migUserKey]
|
||||
// parse and set the userID
|
||||
newSecretMap[credUserID] = migUserName
|
||||
if secretmap[migUserID] != "" {
|
||||
newSecretMap[credUserID] = secretmap[migUserID]
|
||||
}
|
||||
|
||||
return newSecretMap, nil
|
||||
}
|
||||
|
||||
// IsMigrationSecret validates if the passed in secretmap is a secret
|
||||
// of a migration volume request. The migration secret carry a field
|
||||
// called `key` which is the equivalent of `userKey` which is what we
|
||||
// check here for identifying the secret.
|
||||
func IsMigrationSecret(passedSecretMap map[string]string) bool {
|
||||
// the below 'nil' check is an extra measure as the request validators like
|
||||
// ValidateNodeStageVolumeRequest() already does the nil check, however considering
|
||||
// this function can be called independently with a map of secret values
|
||||
// it is good to have this check in place, also it gives clear error about this
|
||||
// was hit on migration request compared to general one.
|
||||
return len(passedSecretMap) != 0 && passedSecretMap[migUserKey] != ""
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user