rbd: implement pv key rotation

This patch implements the EncryptionKeyRotation spec for ceph-csi

Signed-off-by: Niraj Yadav <niryadav@redhat.com>
This commit is contained in:
Niraj Yadav 2024-06-21 15:49:06 +05:30 committed by mergify[bot]
parent 64c5be5242
commit ebc56887cd
16 changed files with 930 additions and 58 deletions

2
go.mod
View File

@ -9,7 +9,7 @@ require (
github.com/ceph/ceph-csi/api v0.0.0-00010101000000-000000000000 github.com/ceph/ceph-csi/api v0.0.0-00010101000000-000000000000
github.com/ceph/go-ceph v0.28.0 github.com/ceph/go-ceph v0.28.0
github.com/container-storage-interface/spec v1.10.0 github.com/container-storage-interface/spec v1.10.0
github.com/csi-addons/spec v0.2.1-0.20240627093359-0dd74d521e67 github.com/csi-addons/spec v0.2.1-0.20240718113938-dc98b454ba65
github.com/gemalto/kmip-go v0.0.10 github.com/gemalto/kmip-go v0.0.10
github.com/golang/protobuf v1.5.4 github.com/golang/protobuf v1.5.4
github.com/google/fscrypt v0.3.6-0.20240502174735-068b9f8f5dec github.com/google/fscrypt v0.3.6-0.20240502174735-068b9f8f5dec

4
go.sum
View File

@ -911,8 +911,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46t
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
github.com/csi-addons/spec v0.2.1-0.20240627093359-0dd74d521e67 h1:UAcAhE1pTkWaFBS0kvhHUcUsoEv5fsieD0tl8psQMCs= github.com/csi-addons/spec v0.2.1-0.20240718113938-dc98b454ba65 h1:i9JGGQTEmRQXSpQQPR96+DV4D4o+V1+gjAWf+bpxQxk=
github.com/csi-addons/spec v0.2.1-0.20240627093359-0dd74d521e67/go.mod h1:Mwq4iLiUV4s+K1bszcWU6aMsR5KPsbIYzzszJ6+56vI= github.com/csi-addons/spec v0.2.1-0.20240718113938-dc98b454ba65/go.mod h1:Mwq4iLiUV4s+K1bszcWU6aMsR5KPsbIYzzszJ6+56vI=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=

View File

@ -0,0 +1,101 @@
/*
Copyright 2024 The Ceph-CSI Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package rbd
import (
"context"
"errors"
csicommon "github.com/ceph/ceph-csi/internal/csi-common"
"github.com/ceph/ceph-csi/internal/rbd"
"github.com/ceph/ceph-csi/internal/util"
"github.com/ceph/ceph-csi/internal/util/log"
"github.com/container-storage-interface/spec/lib/go/csi"
ekr "github.com/csi-addons/spec/lib/go/encryptionkeyrotation"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)
type EncryptionKeyRotationServer struct {
*ekr.UnimplementedEncryptionKeyRotationControllerServer
volLock *util.VolumeLocks
}
func NewEncryptionKeyRotationServer(volLock *util.VolumeLocks) *EncryptionKeyRotationServer {
return &EncryptionKeyRotationServer{volLock: volLock}
}
func (ekrs *EncryptionKeyRotationServer) RegisterService(svc grpc.ServiceRegistrar) {
ekr.RegisterEncryptionKeyRotationControllerServer(svc, ekrs)
}
func (ekrs *EncryptionKeyRotationServer) EncryptionKeyRotate(
ctx context.Context,
req *ekr.EncryptionKeyRotateRequest,
) (*ekr.EncryptionKeyRotateResponse, error) {
// Get the volume ID from the request
volID := req.GetVolumeId()
if volID == "" {
return nil, status.Error(codes.InvalidArgument, "empty volume ID in request")
}
// Block key rotation for RWX/ROX volumes
_, isMultiNode := csicommon.IsBlockMultiNode([]*csi.VolumeCapability{req.GetVolumeCapability()})
if isMultiNode {
return nil, status.Error(codes.Unimplemented, "multi-node key rotation is not supported")
}
if acquired := ekrs.volLock.TryAcquire(volID); !acquired {
return nil, status.Errorf(codes.Aborted, util.VolumeOperationAlreadyExistsFmt, volID)
}
defer ekrs.volLock.Release(volID)
// Get the credentials required to authenticate
// against a ceph cluster
creds, err := util.NewUserCredentials(req.GetSecrets())
if err != nil {
return nil, status.Error(codes.Internal, err.Error())
}
defer creds.DeleteCredentials()
rbdVol, err := rbd.GenVolFromVolID(ctx, volID, creds, req.GetSecrets())
if err != nil {
switch {
case errors.Is(err, rbd.ErrImageNotFound):
err = status.Errorf(codes.NotFound, "volume ID %s not found", volID)
case errors.Is(err, util.ErrPoolNotFound):
log.ErrorLog(ctx, "failed to get backend volume for %s: %v", volID, err)
err = status.Errorf(codes.NotFound, err.Error())
default:
err = status.Errorf(codes.Internal, err.Error())
}
return nil, err
}
defer rbdVol.Destroy(ctx)
err = rbdVol.RotateEncryptionKey(ctx)
if err != nil {
return nil, status.Errorf(
codes.Internal, "failed to rotate the key for volume with ID %q: %s", volID, err.Error())
}
// Success
return &ekr.EncryptionKeyRotateResponse{}, nil
}

View File

@ -133,6 +133,13 @@ func (is *IdentityServer) GetCapabilities(
Type: identity.Capability_ReclaimSpace_ONLINE, Type: identity.Capability_ReclaimSpace_ONLINE,
}, },
}, },
},
&identity.Capability{
Type: &identity.Capability_EncryptionKeyRotation_{
EncryptionKeyRotation: &identity.Capability_EncryptionKeyRotation{
Type: identity.Capability_EncryptionKeyRotation_ENCRYPTIONKEYROTATION,
},
},
}) })
} }

View File

@ -28,6 +28,8 @@ import (
"github.com/hashicorp/vault/api" "github.com/hashicorp/vault/api"
loss "github.com/libopenstorage/secrets" loss "github.com/libopenstorage/secrets"
"github.com/libopenstorage/secrets/vault" "github.com/libopenstorage/secrets/vault"
"github.com/ceph/ceph-csi/internal/util/file"
) )
const ( const (
@ -269,10 +271,12 @@ func (vc *vaultConnection) initCertificates(config map[string]interface{}, secre
return fmt.Errorf("missing vault CA in secret %s", vaultCAFromSecret) return fmt.Errorf("missing vault CA in secret %s", vaultCAFromSecret)
} }
vaultConfig[api.EnvVaultCACert], err = createTempFile("vault-ca-cert", []byte(caPEM)) tf, err := file.CreateTempFile("vault-ca-cert", caPEM)
if err != nil { if err != nil {
return fmt.Errorf("failed to create temporary file for Vault CA: %w", err) return fmt.Errorf("failed to create temporary file for Vault CA: %w", err)
} }
vaultConfig[api.EnvVaultCACert] = tf.Name()
// update the existing config // update the existing config
for key, value := range vaultConfig { for key, value := range vaultConfig {
vc.vaultConfig[key] = value vc.vaultConfig[key] = value
@ -480,31 +484,3 @@ func detectAuthMountPath(path string) (string, error) {
return authMountPath, nil return authMountPath, nil
} }
// createTempFile writes data to a temporary file that contains the pattern in
// the filename (see os.CreateTemp for details).
func createTempFile(pattern string, data []byte) (string, error) {
t, err := os.CreateTemp("", pattern)
if err != nil {
return "", fmt.Errorf("failed to create temporary file: %w", err)
}
// delete the tmpfile on error
defer func() {
if err != nil {
// ignore error on failure to remove tmpfile (gosec complains)
_ = os.Remove(t.Name())
}
}()
s, err := t.Write(data)
if err != nil || s != len(data) {
return "", fmt.Errorf("failed to write temporary file: %w", err)
}
err = t.Close()
if err != nil {
return "", fmt.Errorf("failed to close temporary file: %w", err)
}
return t.Name(), nil
}

View File

@ -18,7 +18,6 @@ package kms
import ( import (
"errors" "errors"
"os"
"testing" "testing"
loss "github.com/libopenstorage/secrets" loss "github.com/libopenstorage/secrets"
@ -44,23 +43,6 @@ func TestDetectAuthMountPath(t *testing.T) {
} }
} }
func TestCreateTempFile(t *testing.T) {
t.Parallel()
data := []byte("Hello World!")
tmpfile, err := createTempFile("my-file", data)
if err != nil {
t.Errorf("createTempFile() failed: %s", err)
}
if tmpfile == "" {
t.Errorf("createTempFile() returned an empty filename")
}
err = os.Remove(tmpfile)
if err != nil {
t.Errorf("failed to remove tmpfile (%s): %s", tmpfile, err)
}
}
func TestSetConfigString(t *testing.T) { func TestSetConfigString(t *testing.T) {
t.Parallel() t.Parallel()
const defaultValue = "default-value" const defaultValue = "default-value"

View File

@ -24,6 +24,7 @@ import (
"os" "os"
"strconv" "strconv"
"github.com/ceph/ceph-csi/internal/util/file"
"github.com/ceph/ceph-csi/internal/util/k8s" "github.com/ceph/ceph-csi/internal/util/k8s"
"github.com/hashicorp/vault/api" "github.com/hashicorp/vault/api"
@ -378,10 +379,11 @@ func (vtc *vaultTenantConnection) initCertificates(config map[string]interface{}
return fmt.Errorf("failed to get CA certificate from secret %s: %w", vaultCAFromSecret, cErr) return fmt.Errorf("failed to get CA certificate from secret %s: %w", vaultCAFromSecret, cErr)
} }
} }
vaultConfig[api.EnvVaultCACert], err = createTempFile("vault-ca-cert", []byte(cert)) cer, ferr := file.CreateTempFile("vault-ca-cert", cert)
if err != nil { if ferr != nil {
return fmt.Errorf("failed to create temporary file for Vault CA: %w", err) return fmt.Errorf("failed to create temporary file for Vault CA: %w", ferr)
} }
vaultConfig[api.EnvVaultCACert] = cer.Name()
} }
vaultClientCertFromSecret := "" // optional vaultClientCertFromSecret := "" // optional
@ -403,10 +405,11 @@ func (vtc *vaultTenantConnection) initCertificates(config map[string]interface{}
return fmt.Errorf("failed to get client certificate from secret %s: %w", vaultCAFromSecret, cErr) return fmt.Errorf("failed to get client certificate from secret %s: %w", vaultCAFromSecret, cErr)
} }
} }
vaultConfig[api.EnvVaultClientCert], err = createTempFile("vault-ca-cert", []byte(cert)) cer, ferr := file.CreateTempFile("vault-ca-cert", cert)
if err != nil { if ferr != nil {
return fmt.Errorf("failed to create temporary file for Vault client certificate: %w", err) return fmt.Errorf("failed to create temporary file for Vault client certificate: %w", ferr)
} }
vaultConfig[api.EnvVaultClientCert] = cer.Name()
} }
vaultClientCertKeyFromSecret := "" // optional vaultClientCertKeyFromSecret := "" // optional
@ -432,10 +435,11 @@ func (vtc *vaultTenantConnection) initCertificates(config map[string]interface{}
return fmt.Errorf("failed to get client certificate key from secret %s: %w", vaultCAFromSecret, err) return fmt.Errorf("failed to get client certificate key from secret %s: %w", vaultCAFromSecret, err)
} }
} }
vaultConfig[api.EnvVaultClientKey], err = createTempFile("vault-client-cert-key", []byte(certKey)) ckey, err := file.CreateTempFile("vault-client-cert-key", certKey)
if err != nil { if err != nil {
return fmt.Errorf("failed to create temporary file for Vault client cert key: %w", err) return fmt.Errorf("failed to create temporary file for Vault client cert key: %w", err)
} }
vaultConfig[api.EnvVaultClientKey] = ckey.Name()
} }
for key, value := range vaultConfig { for key, value := range vaultConfig {

View File

@ -229,6 +229,9 @@ func (r *Driver) setupCSIAddonsServer(conf *util.Config) error {
if conf.IsNodeServer { if conf.IsNodeServer {
rs := casrbd.NewReclaimSpaceNodeServer() rs := casrbd.NewReclaimSpaceNodeServer()
r.cas.RegisterService(rs) r.cas.RegisterService(rs)
ekr := casrbd.NewEncryptionKeyRotationServer(r.ns.VolumeLocks)
r.cas.RegisterService(ekr)
} }
// start the server, this does not block, it runs a new go-routine // start the server, this does not block, it runs a new go-routine

View File

@ -63,6 +63,10 @@ const (
// user did not specify an "encryptionType", but set // user did not specify an "encryptionType", but set
// "encryption": true. // "encryption": true.
rbdDefaultEncryptionType = util.EncryptionTypeBlock rbdDefaultEncryptionType = util.EncryptionTypeBlock
// Luks slots.
luksSlot0 = "0"
luksSlot1 = "1"
) )
// checkRbdImageEncrypted verifies if rbd image was encrypted when created. // checkRbdImageEncrypted verifies if rbd image was encrypted when created.
@ -437,3 +441,72 @@ func (ri *rbdImage) RemoveDEK(ctx context.Context, volumeID string) error {
return nil return nil
} }
// GetEncryptionPassphraseSize returns the value of `encryptionPassphraseSize`.
func GetEncryptionPassphraseSize() int {
return encryptionPassphraseSize
}
// RotateEncryptionKey processes the key rotation for the RBD Volume.
func (rv *rbdVolume) RotateEncryptionKey(ctx context.Context) error {
if !rv.isBlockEncrypted() {
return errors.New("key rotation unsupported for non block encrypted device")
}
// Verify that the underlying device has been setup for encryption
currState, err := rv.checkRbdImageEncrypted(ctx)
if err != nil {
return fmt.Errorf("failed to check encryption state: %w", err)
}
if currState != rbdImageEncrypted {
return errors.New("key rotation not supported for unencrypted device")
}
// Get the device path for the underlying image
useNbd := rv.Mounter == rbdNbdMounter && hasNBD
devicePath, found := waitForPath(ctx, rv.Pool, rv.RadosNamespace, rv.RbdImageName, 1, useNbd)
if !found {
return fmt.Errorf("failed to get the device path for %q: %w", rv, err)
}
// Step 1: Get the current passphrase
oldPassphrase, err := rv.blockEncryption.GetCryptoPassphrase(ctx, rv.VolID)
if err != nil {
return fmt.Errorf("failed to fetch the current passphrase for %q: %w", rv, err)
}
// Step 2: Add current key to slot 1
err = util.LuksAddKey(devicePath, oldPassphrase, oldPassphrase, luksSlot1)
if err != nil {
return fmt.Errorf("failed to add curr key to luksSlot1: %w", err)
}
// Step 3: Generate new key and add it to slot 0
newPassphrase, err := rv.blockEncryption.GetNewCryptoPassphrase(
GetEncryptionPassphraseSize())
if err != nil {
return fmt.Errorf("failed to generate a new passphrase: %w", err)
}
err = util.LuksAddKey(devicePath, oldPassphrase, newPassphrase, luksSlot0)
if err != nil {
return fmt.Errorf("failed to add the new key to luksSlot0: %w", err)
}
// Step 4: Add the new key to KMS
err = rv.blockEncryption.StoreCryptoPassphrase(ctx, rv.VolID, newPassphrase)
if err != nil {
return fmt.Errorf("failed to update the new key into the KMS: %w", err)
}
// Step 5: Remove the old key from slot 1
// We use the newPassphrase to authenticate LUKS here
err = util.LuksRemoveKey(devicePath, newPassphrase, luksSlot1)
if err != nil {
return fmt.Errorf("failed to remove the backup key from luksSlot1: %w", err)
}
// Return error accordingly.
return nil
}

View File

@ -237,6 +237,11 @@ func (ve *VolumeEncryption) GetCryptoPassphrase(ctx context.Context, volumeID st
return ve.KMS.DecryptDEK(ctx, volumeID, passphrase) return ve.KMS.DecryptDEK(ctx, volumeID, passphrase)
} }
// GetNewCryptoPassphrase returns a random passphrase of given length.
func (ve *VolumeEncryption) GetNewCryptoPassphrase(length int) (string, error) {
return generateNewEncryptionPassphrase(length)
}
// generateNewEncryptionPassphrase generates a random passphrase for encryption. // generateNewEncryptionPassphrase generates a random passphrase for encryption.
func generateNewEncryptionPassphrase(length int) (string, error) { func generateNewEncryptionPassphrase(length int) (string, error) {
bytesPassphrase := make([]byte, length) bytesPassphrase := make([]byte, length)

View File

@ -19,9 +19,13 @@ package util
import ( import (
"bytes" "bytes"
"fmt" "fmt"
"os"
"os/exec" "os/exec"
"strconv" "strconv"
"strings" "strings"
"github.com/ceph/ceph-csi/internal/util/file"
"github.com/ceph/ceph-csi/internal/util/log"
) )
// Limit memory used by Argon2i PBKDF to 32 MiB. // Limit memory used by Argon2i PBKDF to 32 MiB.
@ -66,6 +70,135 @@ func LuksStatus(mapperFile string) (string, string, error) {
return execCryptsetupCommand(nil, "status", mapperFile) return execCryptsetupCommand(nil, "status", mapperFile)
} }
// LuksAddKey adds a new key to the specified slot.
func LuksAddKey(devicePath, passphrase, newPassphrase, slot string) error {
passFile, err := file.CreateTempFile("luks-", passphrase)
if err != nil {
return err
}
defer os.Remove(passFile.Name())
newPassFile, err := file.CreateTempFile("luks-", newPassphrase)
if err != nil {
return err
}
defer os.Remove(newPassFile.Name())
_, stderr, err := execCryptsetupCommand(
nil,
"--verbose",
"--key-file="+passFile.Name(),
"--key-slot="+slot,
"luksAddKey",
devicePath,
newPassFile.Name(),
)
// Return early if no error to save us some time
if err == nil {
return nil
}
// Possible scenarios
// 1. The provided passphrase to unlock the disk is wrong
// 2. The key slot is already in use
// If so, check if the key we want to add to the slot is already there
// If not, remove it and then add the new key to the slot
if strings.Contains(stderr, fmt.Sprintf("Key slot %s is full", slot)) {
// The given slot already has a key
// Check if it is the one that we want to update with
exists, fErr := LuksVerifyKey(devicePath, newPassphrase, slot)
if fErr != nil {
return fErr
}
// Verification passed, return early
if exists {
return nil
}
// Else, we remove the key from the given slot and add the new one
// Note: we use existing passphrase here as we are not yet sure if
// the newPassphrase is present in the headers
fErr = LuksRemoveKey(devicePath, passphrase, slot)
if fErr != nil {
return fErr
}
// Now the slot is free, add the new key to it
fErr = LuksAddKey(devicePath, passphrase, newPassphrase, slot)
if fErr != nil {
return fErr
}
// No errors, we good.
return nil
}
// The existing passphrase is wrong and the slot is empty
return err
}
// LuksRemoveKey removes the key by killing the specified slot.
func LuksRemoveKey(devicePath, passphrase, slot string) error {
keyFile, err := file.CreateTempFile("luks-", passphrase)
if err != nil {
return err
}
defer os.Remove(keyFile.Name())
_, stderr, err := execCryptsetupCommand(
nil,
"--verbose",
"--key-file="+keyFile.Name(),
"luksKillSlot",
devicePath,
slot,
)
if err != nil {
// If a slot is not active, don't treat that as an error
if !strings.Contains(stderr, fmt.Sprintf("Keyslot %s is not active.", slot)) {
return fmt.Errorf("failed to kill slot %s for device %s: %w", slot, devicePath, err)
}
}
return nil
}
// LuksVerifyKey verifies that a key exists in a given slot.
func LuksVerifyKey(devicePath, passphrase, slot string) (bool, error) {
// Create a temp file that we will use to open the device
keyFile, err := file.CreateTempFile("luks-", passphrase)
if err != nil {
return false, err
}
defer os.Remove(keyFile.Name())
_, stderr, err := execCryptsetupCommand(
nil,
"--verbose",
"--key-file="+keyFile.Name(),
"--key-slot="+slot,
"luksChangeKey",
devicePath,
keyFile.Name(),
)
if err != nil {
// If the passphrase doesn't match the key in given slot
if strings.Contains(stderr, "No key available with this passphrase.") {
// No match, no error
return false, nil
}
// Otherwise it was something else, return the wrapped error
log.ErrorLogMsg("failed to verify key in slot %s. stderr: %s. err: %v", slot, stderr, err)
return false, fmt.Errorf("failed to verify key in slot %s for device %s: %w", slot, devicePath, err)
}
return true, nil
}
func execCryptsetupCommand(stdin *string, args ...string) (string, string, error) { func execCryptsetupCommand(stdin *string, args ...string) (string, string, error) {
var ( var (
program = "cryptsetup" program = "cryptsetup"

View File

@ -0,0 +1,54 @@
/*
Copyright 2024 The Ceph-CSI Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package file
import (
"fmt"
"os"
)
// CreateTempFile create a temporary file with the given string
// content and returns the reference to the file.
// The caller is responsible for disposing the file.
func CreateTempFile(prefix, contents string) (*os.File, error) {
// Create a temp file
file, err := os.CreateTemp("", prefix)
if err != nil {
return nil, fmt.Errorf("failed to create temporary file: %w", err)
}
// In case of error, remove the file if it was created
defer func() {
if err != nil {
_ = os.Remove(file.Name())
}
}()
// Write the contents
var c int
c, err = file.WriteString(contents)
if err != nil || c != len(contents) {
return nil, fmt.Errorf("failed to write temporary file: %w", err)
}
// Close the handle
if err = file.Close(); err != nil {
return nil, fmt.Errorf("failed to close temporary file: %w", err)
}
return file, nil
}

View File

@ -0,0 +1,100 @@
/*
Copyright 2024 The Ceph-CSI Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package file
import (
"os"
"testing"
)
func TestCreateTempFile_WithValidContent(t *testing.T) {
t.Parallel()
content := "Valid Content"
file, err := CreateTempFile("test-", content)
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
defer func() {
err = os.Remove(file.Name())
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
}()
readContent, err := os.ReadFile(file.Name())
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
if string(readContent) != content {
t.Fatalf("Content mismatch: got %v, want %v", string(readContent), content)
}
}
func TestCreateTempFile_WithEmptyContent(t *testing.T) {
t.Parallel()
content := ""
file, err := CreateTempFile("test-", content)
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
defer func() {
err = os.Remove(file.Name())
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
}()
readContent, err := os.ReadFile(file.Name())
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
if string(readContent) != content {
t.Fatalf("Content mismatch: got %v, want %v", string(readContent), content)
}
}
func TestCreateTempFile_WithLargeContent(t *testing.T) {
t.Parallel()
content := string(make([]byte, 1<<20))
file, err := CreateTempFile("test-", content)
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
defer func() {
err = os.Remove(file.Name())
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
}()
readContent, err := os.ReadFile(file.Name())
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
if string(readContent) != content {
t.Fatalf("Content mismatch: got %v, want %v", string(readContent), content)
}
}

View File

@ -0,0 +1,317 @@
// Code generated by make; DO NOT EDIT.
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.28.1
// protoc v3.20.2
// source: encryptionkeyrotation/encryptionkeyrotation.proto
package encryptionkeyrotation
import (
csi "github.com/container-storage-interface/spec/lib/go/csi"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
_ "google.golang.org/protobuf/types/descriptorpb"
reflect "reflect"
sync "sync"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// EncryptionKeyRotateRequest contains the information needed to identify
// the volume by the SP and access any backend services so that the key can be
// rotated.
type EncryptionKeyRotateRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// The ID of the volume for which the key is to be rotated.
// This field is required
VolumeId string `protobuf:"bytes,1,opt,name=volume_id,json=volumeId,proto3" json:"volume_id,omitempty"`
// The path where the volume is available.
// This field is OPTIONAL
// Useful if you are implementing the RPC on CSI Driver NodePlugin
VolumePath string `protobuf:"bytes,2,opt,name=volume_path,json=volumePath,proto3" json:"volume_path,omitempty"`
// Provide the encryption key to be set
// This field is OPTIONAL
EncryptionKey string `protobuf:"bytes,3,opt,name=encryption_key,json=encryptionKey,proto3" json:"encryption_key,omitempty"`
// Plugin specific parameters passed in as opaque key-value pairs.
Parameters map[string]string `protobuf:"bytes,4,rep,name=parameters,proto3" json:"parameters,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
// Secrets required by the plugin to complete the request.
Secrets map[string]string `protobuf:"bytes,5,rep,name=secrets,proto3" json:"secrets,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
// Volume capability describing how the CO intends to use this volume.
// This allows SP to determine if volume is being used as a block
// device or mounted file system. This is OPTIONAL.
VolumeCapability *csi.VolumeCapability `protobuf:"bytes,6,opt,name=volume_capability,json=volumeCapability,proto3" json:"volume_capability,omitempty"`
}
func (x *EncryptionKeyRotateRequest) Reset() {
*x = EncryptionKeyRotateRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_encryptionkeyrotation_encryptionkeyrotation_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *EncryptionKeyRotateRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*EncryptionKeyRotateRequest) ProtoMessage() {}
func (x *EncryptionKeyRotateRequest) ProtoReflect() protoreflect.Message {
mi := &file_encryptionkeyrotation_encryptionkeyrotation_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use EncryptionKeyRotateRequest.ProtoReflect.Descriptor instead.
func (*EncryptionKeyRotateRequest) Descriptor() ([]byte, []int) {
return file_encryptionkeyrotation_encryptionkeyrotation_proto_rawDescGZIP(), []int{0}
}
func (x *EncryptionKeyRotateRequest) GetVolumeId() string {
if x != nil {
return x.VolumeId
}
return ""
}
func (x *EncryptionKeyRotateRequest) GetVolumePath() string {
if x != nil {
return x.VolumePath
}
return ""
}
func (x *EncryptionKeyRotateRequest) GetEncryptionKey() string {
if x != nil {
return x.EncryptionKey
}
return ""
}
func (x *EncryptionKeyRotateRequest) GetParameters() map[string]string {
if x != nil {
return x.Parameters
}
return nil
}
func (x *EncryptionKeyRotateRequest) GetSecrets() map[string]string {
if x != nil {
return x.Secrets
}
return nil
}
func (x *EncryptionKeyRotateRequest) GetVolumeCapability() *csi.VolumeCapability {
if x != nil {
return x.VolumeCapability
}
return nil
}
// EncryptionKeyRotateResponse holds the information about the result of the
// EncryptionKeyRotateRequest call.
type EncryptionKeyRotateResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
}
func (x *EncryptionKeyRotateResponse) Reset() {
*x = EncryptionKeyRotateResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_encryptionkeyrotation_encryptionkeyrotation_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *EncryptionKeyRotateResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*EncryptionKeyRotateResponse) ProtoMessage() {}
func (x *EncryptionKeyRotateResponse) ProtoReflect() protoreflect.Message {
mi := &file_encryptionkeyrotation_encryptionkeyrotation_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use EncryptionKeyRotateResponse.ProtoReflect.Descriptor instead.
func (*EncryptionKeyRotateResponse) Descriptor() ([]byte, []int) {
return file_encryptionkeyrotation_encryptionkeyrotation_proto_rawDescGZIP(), []int{1}
}
var File_encryptionkeyrotation_encryptionkeyrotation_proto protoreflect.FileDescriptor
var file_encryptionkeyrotation_encryptionkeyrotation_proto_rawDesc = []byte{
0x0a, 0x31, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x6b, 0x65, 0x79, 0x72,
0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69,
0x6f, 0x6e, 0x6b, 0x65, 0x79, 0x72, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x12, 0x15, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x6b,
0x65, 0x79, 0x72, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x40, 0x67, 0x69, 0x74, 0x68,
0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72,
0x2d, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2d, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61,
0x63, 0x65, 0x2f, 0x73, 0x70, 0x65, 0x63, 0x2f, 0x6c, 0x69, 0x62, 0x2f, 0x67, 0x6f, 0x2f, 0x63,
0x73, 0x69, 0x2f, 0x63, 0x73, 0x69, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x20, 0x67, 0x6f,
0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x65,
0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x8a,
0x04, 0x0a, 0x1a, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79,
0x52, 0x6f, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a,
0x09, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
0x52, 0x08, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x76, 0x6f,
0x6c, 0x75, 0x6d, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
0x0a, 0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x2a, 0x0a, 0x0e, 0x65,
0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20,
0x01, 0x28, 0x09, 0x42, 0x03, 0x98, 0x42, 0x01, 0x52, 0x0d, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70,
0x74, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x12, 0x61, 0x0a, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d,
0x65, 0x74, 0x65, 0x72, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x41, 0x2e, 0x65, 0x6e,
0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x6b, 0x65, 0x79, 0x72, 0x6f, 0x74, 0x61, 0x74,
0x69, 0x6f, 0x6e, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x4b, 0x65,
0x79, 0x52, 0x6f, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x50,
0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a,
0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x5d, 0x0a, 0x07, 0x73, 0x65,
0x63, 0x72, 0x65, 0x74, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3e, 0x2e, 0x65, 0x6e,
0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x6b, 0x65, 0x79, 0x72, 0x6f, 0x74, 0x61, 0x74,
0x69, 0x6f, 0x6e, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x4b, 0x65,
0x79, 0x52, 0x6f, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x53,
0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x42, 0x03, 0x98, 0x42, 0x01,
0x52, 0x07, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x12, 0x45, 0x0a, 0x11, 0x76, 0x6f, 0x6c,
0x75, 0x6d, 0x65, 0x5f, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x18, 0x06,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x63, 0x73, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x6f,
0x6c, 0x75, 0x6d, 0x65, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x10,
0x76, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79,
0x1a, 0x3d, 0x0a, 0x0f, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x45, 0x6e,
0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02,
0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a,
0x3a, 0x0a, 0x0c, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12,
0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65,
0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x1d, 0x0a, 0x1b, 0x45,
0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x52, 0x6f, 0x74, 0x61,
0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xa1, 0x01, 0x0a, 0x1f, 0x45,
0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x52, 0x6f, 0x74, 0x61,
0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x12, 0x7e,
0x0a, 0x13, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x52,
0x6f, 0x74, 0x61, 0x74, 0x65, 0x12, 0x31, 0x2e, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69,
0x6f, 0x6e, 0x6b, 0x65, 0x79, 0x72, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x45, 0x6e,
0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x52, 0x6f, 0x74, 0x61, 0x74,
0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x65, 0x6e, 0x63, 0x72, 0x79,
0x70, 0x74, 0x69, 0x6f, 0x6e, 0x6b, 0x65, 0x79, 0x72, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e,
0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x52, 0x6f,
0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x39,
0x5a, 0x37, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x73, 0x69,
0x2d, 0x61, 0x64, 0x64, 0x6f, 0x6e, 0x73, 0x2f, 0x73, 0x70, 0x65, 0x63, 0x2f, 0x6c, 0x69, 0x62,
0x2f, 0x67, 0x6f, 0x2f, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x6b, 0x65,
0x79, 0x72, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x33,
}
var (
file_encryptionkeyrotation_encryptionkeyrotation_proto_rawDescOnce sync.Once
file_encryptionkeyrotation_encryptionkeyrotation_proto_rawDescData = file_encryptionkeyrotation_encryptionkeyrotation_proto_rawDesc
)
func file_encryptionkeyrotation_encryptionkeyrotation_proto_rawDescGZIP() []byte {
file_encryptionkeyrotation_encryptionkeyrotation_proto_rawDescOnce.Do(func() {
file_encryptionkeyrotation_encryptionkeyrotation_proto_rawDescData = protoimpl.X.CompressGZIP(file_encryptionkeyrotation_encryptionkeyrotation_proto_rawDescData)
})
return file_encryptionkeyrotation_encryptionkeyrotation_proto_rawDescData
}
var file_encryptionkeyrotation_encryptionkeyrotation_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
var file_encryptionkeyrotation_encryptionkeyrotation_proto_goTypes = []interface{}{
(*EncryptionKeyRotateRequest)(nil), // 0: encryptionkeyrotation.EncryptionKeyRotateRequest
(*EncryptionKeyRotateResponse)(nil), // 1: encryptionkeyrotation.EncryptionKeyRotateResponse
nil, // 2: encryptionkeyrotation.EncryptionKeyRotateRequest.ParametersEntry
nil, // 3: encryptionkeyrotation.EncryptionKeyRotateRequest.SecretsEntry
(*csi.VolumeCapability)(nil), // 4: csi.v1.VolumeCapability
}
var file_encryptionkeyrotation_encryptionkeyrotation_proto_depIdxs = []int32{
2, // 0: encryptionkeyrotation.EncryptionKeyRotateRequest.parameters:type_name -> encryptionkeyrotation.EncryptionKeyRotateRequest.ParametersEntry
3, // 1: encryptionkeyrotation.EncryptionKeyRotateRequest.secrets:type_name -> encryptionkeyrotation.EncryptionKeyRotateRequest.SecretsEntry
4, // 2: encryptionkeyrotation.EncryptionKeyRotateRequest.volume_capability:type_name -> csi.v1.VolumeCapability
0, // 3: encryptionkeyrotation.EncryptionKeyRotationController.EncryptionKeyRotate:input_type -> encryptionkeyrotation.EncryptionKeyRotateRequest
1, // 4: encryptionkeyrotation.EncryptionKeyRotationController.EncryptionKeyRotate:output_type -> encryptionkeyrotation.EncryptionKeyRotateResponse
4, // [4:5] is the sub-list for method output_type
3, // [3:4] is the sub-list for method input_type
3, // [3:3] is the sub-list for extension type_name
3, // [3:3] is the sub-list for extension extendee
0, // [0:3] is the sub-list for field type_name
}
func init() { file_encryptionkeyrotation_encryptionkeyrotation_proto_init() }
func file_encryptionkeyrotation_encryptionkeyrotation_proto_init() {
if File_encryptionkeyrotation_encryptionkeyrotation_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_encryptionkeyrotation_encryptionkeyrotation_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*EncryptionKeyRotateRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_encryptionkeyrotation_encryptionkeyrotation_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*EncryptionKeyRotateResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_encryptionkeyrotation_encryptionkeyrotation_proto_rawDesc,
NumEnums: 0,
NumMessages: 4,
NumExtensions: 0,
NumServices: 1,
},
GoTypes: file_encryptionkeyrotation_encryptionkeyrotation_proto_goTypes,
DependencyIndexes: file_encryptionkeyrotation_encryptionkeyrotation_proto_depIdxs,
MessageInfos: file_encryptionkeyrotation_encryptionkeyrotation_proto_msgTypes,
}.Build()
File_encryptionkeyrotation_encryptionkeyrotation_proto = out.File
file_encryptionkeyrotation_encryptionkeyrotation_proto_rawDesc = nil
file_encryptionkeyrotation_encryptionkeyrotation_proto_goTypes = nil
file_encryptionkeyrotation_encryptionkeyrotation_proto_depIdxs = nil
}

View File

@ -0,0 +1,116 @@
// Code generated by make; DO NOT EDIT.
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.3.0
// - protoc v3.20.2
// source: encryptionkeyrotation/encryptionkeyrotation.proto
package encryptionkeyrotation
import (
context "context"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
)
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
// Requires gRPC-Go v1.32.0 or later.
const _ = grpc.SupportPackageIsVersion7
const (
EncryptionKeyRotationController_EncryptionKeyRotate_FullMethodName = "/encryptionkeyrotation.EncryptionKeyRotationController/EncryptionKeyRotate"
)
// EncryptionKeyRotationControllerClient is the client API for EncryptionKeyRotationController service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
type EncryptionKeyRotationControllerClient interface {
// EncryptionKeyRotate is a procedure that is called
// on the CSI ControllerPlugin or NodePlugin
EncryptionKeyRotate(ctx context.Context, in *EncryptionKeyRotateRequest, opts ...grpc.CallOption) (*EncryptionKeyRotateResponse, error)
}
type encryptionKeyRotationControllerClient struct {
cc grpc.ClientConnInterface
}
func NewEncryptionKeyRotationControllerClient(cc grpc.ClientConnInterface) EncryptionKeyRotationControllerClient {
return &encryptionKeyRotationControllerClient{cc}
}
func (c *encryptionKeyRotationControllerClient) EncryptionKeyRotate(ctx context.Context, in *EncryptionKeyRotateRequest, opts ...grpc.CallOption) (*EncryptionKeyRotateResponse, error) {
out := new(EncryptionKeyRotateResponse)
err := c.cc.Invoke(ctx, EncryptionKeyRotationController_EncryptionKeyRotate_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// EncryptionKeyRotationControllerServer is the server API for EncryptionKeyRotationController service.
// All implementations must embed UnimplementedEncryptionKeyRotationControllerServer
// for forward compatibility
type EncryptionKeyRotationControllerServer interface {
// EncryptionKeyRotate is a procedure that is called
// on the CSI ControllerPlugin or NodePlugin
EncryptionKeyRotate(context.Context, *EncryptionKeyRotateRequest) (*EncryptionKeyRotateResponse, error)
mustEmbedUnimplementedEncryptionKeyRotationControllerServer()
}
// UnimplementedEncryptionKeyRotationControllerServer must be embedded to have forward compatible implementations.
type UnimplementedEncryptionKeyRotationControllerServer struct {
}
func (UnimplementedEncryptionKeyRotationControllerServer) EncryptionKeyRotate(context.Context, *EncryptionKeyRotateRequest) (*EncryptionKeyRotateResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method EncryptionKeyRotate not implemented")
}
func (UnimplementedEncryptionKeyRotationControllerServer) mustEmbedUnimplementedEncryptionKeyRotationControllerServer() {
}
// UnsafeEncryptionKeyRotationControllerServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to EncryptionKeyRotationControllerServer will
// result in compilation errors.
type UnsafeEncryptionKeyRotationControllerServer interface {
mustEmbedUnimplementedEncryptionKeyRotationControllerServer()
}
func RegisterEncryptionKeyRotationControllerServer(s grpc.ServiceRegistrar, srv EncryptionKeyRotationControllerServer) {
s.RegisterService(&EncryptionKeyRotationController_ServiceDesc, srv)
}
func _EncryptionKeyRotationController_EncryptionKeyRotate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(EncryptionKeyRotateRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(EncryptionKeyRotationControllerServer).EncryptionKeyRotate(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: EncryptionKeyRotationController_EncryptionKeyRotate_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(EncryptionKeyRotationControllerServer).EncryptionKeyRotate(ctx, req.(*EncryptionKeyRotateRequest))
}
return interceptor(ctx, in, info, handler)
}
// EncryptionKeyRotationController_ServiceDesc is the grpc.ServiceDesc for EncryptionKeyRotationController service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var EncryptionKeyRotationController_ServiceDesc = grpc.ServiceDesc{
ServiceName: "encryptionkeyrotation.EncryptionKeyRotationController",
HandlerType: (*EncryptionKeyRotationControllerServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "EncryptionKeyRotate",
Handler: _EncryptionKeyRotationController_EncryptionKeyRotate_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "encryptionkeyrotation/encryptionkeyrotation.proto",
}

3
vendor/modules.txt vendored
View File

@ -236,8 +236,9 @@ github.com/coreos/go-semver/semver
## explicit; go 1.12 ## explicit; go 1.12
github.com/coreos/go-systemd/v22/daemon github.com/coreos/go-systemd/v22/daemon
github.com/coreos/go-systemd/v22/journal github.com/coreos/go-systemd/v22/journal
# github.com/csi-addons/spec v0.2.1-0.20240627093359-0dd74d521e67 # github.com/csi-addons/spec v0.2.1-0.20240718113938-dc98b454ba65
## explicit ## explicit
github.com/csi-addons/spec/lib/go/encryptionkeyrotation
github.com/csi-addons/spec/lib/go/fence github.com/csi-addons/spec/lib/go/fence
github.com/csi-addons/spec/lib/go/identity github.com/csi-addons/spec/lib/go/identity
github.com/csi-addons/spec/lib/go/reclaimspace github.com/csi-addons/spec/lib/go/reclaimspace