mirror of
https://github.com/ceph/ceph-csi.git
synced 2025-06-13 18:43:34 +00:00
rebase: update github.com/libopenstorage/secrets to latest
With this update, we no longer import github.com/hashicorp/vault which now is under BSL license. https://github.com/hashicorp/vault/blob/main/LICENSE resolves: #4196 Signed-off-by: Rakshith R <rar@redhat.com>
This commit is contained in:
2
vendor/github.com/libopenstorage/secrets/.travis.yml
generated
vendored
2
vendor/github.com/libopenstorage/secrets/.travis.yml
generated
vendored
@ -1,6 +1,6 @@
|
||||
language: go
|
||||
go:
|
||||
- 1.14.6
|
||||
- 1.19.x
|
||||
script:
|
||||
- |
|
||||
make unit-test
|
||||
|
3
vendor/github.com/libopenstorage/secrets/Makefile
generated
vendored
3
vendor/github.com/libopenstorage/secrets/Makefile
generated
vendored
@ -6,3 +6,6 @@ unit-test:
|
||||
|
||||
ci-test:
|
||||
go test -timeout 1800s -v github.com/libopenstorage/secrets/vault -tags ci
|
||||
|
||||
integration-test:
|
||||
go test -timeout 1800s -v github.com/libopenstorage/secrets/vault -tags integration
|
||||
|
46
vendor/github.com/libopenstorage/secrets/secrets.go
generated
vendored
46
vendor/github.com/libopenstorage/secrets/secrets.go
generated
vendored
@ -42,16 +42,17 @@ const (
|
||||
)
|
||||
|
||||
const (
|
||||
TypeAWS = "aws-kms"
|
||||
TypeAzure = "azure-kv"
|
||||
TypeDCOS = "dcos"
|
||||
TypeDocker = "docker"
|
||||
TypeGCloud = "gcloud-kms"
|
||||
TypeIBM = "ibm-kp"
|
||||
TypeK8s = "k8s"
|
||||
TypeKVDB = "kvdb"
|
||||
TypeVault = "vault"
|
||||
TypeVaultTransit = "vault-transit"
|
||||
TypeAWSKMS = "aws-kms"
|
||||
TypeAzure = "azure-kv"
|
||||
TypeDCOS = "dcos"
|
||||
TypeDocker = "docker"
|
||||
TypeGCloud = "gcloud-kms"
|
||||
TypeIBM = "ibm-kp"
|
||||
TypeK8s = "k8s"
|
||||
TypeKVDB = "kvdb"
|
||||
TypeVault = "vault"
|
||||
TypeVaultTransit = "vault-transit"
|
||||
TypeAWSSecretsManager = "aws-secrets-manager"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -64,6 +65,14 @@ const (
|
||||
DestroySecret = "destroy-all-secret-versions"
|
||||
)
|
||||
|
||||
// Version represents the unique identifier associated with the version of the new secret.
|
||||
type Version string
|
||||
|
||||
const (
|
||||
// NoVersion indicates that the provider does not support versions for secrets
|
||||
NoVersion Version = "noversion"
|
||||
)
|
||||
|
||||
// Secrets interface implemented by backend Key Management Systems (KMS)
|
||||
type Secrets interface {
|
||||
// String representation of the backend KMS
|
||||
@ -76,15 +85,17 @@ type Secrets interface {
|
||||
GetSecret(
|
||||
secretId string,
|
||||
keyContext map[string]string,
|
||||
) (map[string]interface{}, error)
|
||||
) (map[string]interface{}, Version, error)
|
||||
|
||||
// PutSecret will associate an secretId to its secret data
|
||||
// provided in the arguments and store it into the secret backend
|
||||
// The caller should ensure they use unique secretIDs so that they won't
|
||||
// unknowingly overwrite an existing secret.
|
||||
PutSecret(
|
||||
secretId string,
|
||||
plainText map[string]interface{},
|
||||
keyContext map[string]string,
|
||||
) error
|
||||
) (Version, error)
|
||||
|
||||
// DeleteSecret deletes the secret data associated with the
|
||||
// supplied secretId.
|
||||
@ -141,6 +152,17 @@ func (e *ErrInvalidKeyContext) Error() string {
|
||||
return fmt.Sprintf("invalid key context: %v", e.Reason)
|
||||
}
|
||||
|
||||
// ErrProviderInternal is returned when an error is received from the secrets provider which
|
||||
// is not known to this library
|
||||
type ErrProviderInternal struct {
|
||||
Provider string
|
||||
Reason string
|
||||
}
|
||||
|
||||
func (e *ErrProviderInternal) Error() string {
|
||||
return fmt.Sprintf("%v returned error: %v", e.Provider, e.Reason)
|
||||
}
|
||||
|
||||
// KeyContextChecks performs a series of checks on the keys and values
|
||||
// passed through the key context map
|
||||
func KeyContextChecks(
|
||||
|
97
vendor/github.com/libopenstorage/secrets/secrets_store.go
generated
vendored
Normal file
97
vendor/github.com/libopenstorage/secrets/secrets_store.go
generated
vendored
Normal file
@ -0,0 +1,97 @@
|
||||
package secrets
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type ReaderInit func(map[string]interface{}) (SecretReader, error)
|
||||
type StoreInit func(map[string]interface{}) (SecretStore, error)
|
||||
|
||||
var (
|
||||
secretReaders = make(map[string]ReaderInit)
|
||||
secretStores = make(map[string]StoreInit)
|
||||
readersLock sync.RWMutex
|
||||
storesLock sync.RWMutex
|
||||
)
|
||||
|
||||
// NewReader returns a new instance of SecretReader backend SM identified by
|
||||
// the supplied name. SecretConfig is a map of key value pairs which could
|
||||
// be used for authenticating with the backend
|
||||
func NewReader(name string, secretConfig map[string]interface{}) (SecretReader, error) {
|
||||
readersLock.RLock()
|
||||
defer readersLock.RUnlock()
|
||||
|
||||
if init, exists := secretReaders[name]; exists {
|
||||
return init(secretConfig)
|
||||
}
|
||||
return nil, ErrNotSupported
|
||||
}
|
||||
|
||||
// NewStore returns a new instance of SecretStore backend SM identified by
|
||||
// the supplied name. SecretConfig is a map of key value pairs which could
|
||||
// be used for authenticating with the backend
|
||||
func NewStore(name string, secretConfig map[string]interface{}) (SecretStore, error) {
|
||||
storesLock.RLock()
|
||||
defer storesLock.RUnlock()
|
||||
|
||||
if init, exists := secretStores[name]; exists {
|
||||
return init(secretConfig)
|
||||
}
|
||||
return nil, ErrNotSupported
|
||||
}
|
||||
|
||||
// RegisterReader adds a new backend KMS that implements SecretReader
|
||||
func RegisterReader(name string, init ReaderInit) error {
|
||||
readersLock.Lock()
|
||||
defer readersLock.Unlock()
|
||||
|
||||
if _, exists := secretReaders[name]; exists {
|
||||
return fmt.Errorf("secrets reader %v is already registered", name)
|
||||
}
|
||||
secretReaders[name] = init
|
||||
return nil
|
||||
}
|
||||
|
||||
// RegisterStore adds a new backend KMS that implements SecretStore and SecretReader
|
||||
func RegisterStore(name string, init StoreInit) error {
|
||||
storesLock.Lock()
|
||||
defer storesLock.Unlock()
|
||||
|
||||
if _, exists := secretStores[name]; exists {
|
||||
return fmt.Errorf("secrets store %v is already registered", name)
|
||||
}
|
||||
secretStores[name] = init
|
||||
|
||||
return RegisterReader(name, func(m map[string]interface{}) (SecretReader, error) {
|
||||
return init(m)
|
||||
})
|
||||
}
|
||||
|
||||
// A SecretKey identifies a secret
|
||||
type SecretKey struct {
|
||||
// Prefix is an optional part of the SecretKey.
|
||||
Prefix string
|
||||
// Name is a mandatory part of the SecretKey.
|
||||
Name string
|
||||
}
|
||||
|
||||
// SecretReader interface implemented by Secrets Managers to read secrets
|
||||
type SecretReader interface {
|
||||
// String representation of the backend.
|
||||
String() string
|
||||
// Get returns the secret associate with the supplied key.
|
||||
Get(ctx context.Context, key SecretKey) (secret map[string]interface{}, err error)
|
||||
}
|
||||
|
||||
// SecretStore interface implemented by Secrets Managers to set and delete secrets.
|
||||
type SecretStore interface {
|
||||
SecretReader
|
||||
// Set stores the secret data identified by the key.
|
||||
// The caller should ensure they use unique key so that they won't
|
||||
// unknowingly overwrite an existing secret.
|
||||
Set(ctx context.Context, key SecretKey, secret map[string]interface{}) error
|
||||
// Delete deletes the secret data associated with the supplied key.
|
||||
Delete(ctx context.Context, key SecretKey) error
|
||||
}
|
105
vendor/github.com/libopenstorage/secrets/vault/utils/utils.go
generated
vendored
105
vendor/github.com/libopenstorage/secrets/vault/utils/utils.go
generated
vendored
@ -3,24 +3,23 @@ package utils
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/go-hclog"
|
||||
"github.com/hashicorp/vault/api"
|
||||
"github.com/hashicorp/vault/command/agent/auth"
|
||||
"github.com/hashicorp/vault/command/agent/auth/kubernetes"
|
||||
"github.com/hashicorp/vault/api/auth/approle"
|
||||
"github.com/hashicorp/vault/api/auth/kubernetes"
|
||||
)
|
||||
|
||||
const (
|
||||
vaultAddressPrefix = "http"
|
||||
vaultAddressPrefix = "http"
|
||||
|
||||
// AuthMethodKubernetes is a named auth method.
|
||||
AuthMethodKubernetes = "kubernetes"
|
||||
// AuthMethodApprole
|
||||
AuthMethodAppRole = "approle"
|
||||
// AuthMethod is a vault authentication method used.
|
||||
// https://www.vaultproject.io/docs/auth#auth-methods
|
||||
AuthMethod = "VAULT_AUTH_METHOD"
|
||||
@ -33,6 +32,10 @@ const (
|
||||
AuthKubernetesTokenPath = "VAULT_AUTH_KUBERNETES_TOKEN_PATH"
|
||||
// AuthKubernetesMountPath
|
||||
AuthKubernetesMountPath = "kubernetes"
|
||||
// AuthAppRoleRoleID
|
||||
AuthAppRoleRoleID = "VAULT_APPROLE_ROLE_ID"
|
||||
// AuthAppRoleSecretID
|
||||
AuthAppRoleSecretID = "VAULT_APPROLE_SECRET_ID"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -40,6 +43,7 @@ var (
|
||||
ErrVaultAddressNotSet = errors.New("VAULT_ADDR not set")
|
||||
ErrInvalidVaultToken = errors.New("VAULT_TOKEN is invalid")
|
||||
ErrInvalidSkipVerify = errors.New("VAULT_SKIP_VERIFY is invalid")
|
||||
ErrAppRoleIDNotSet = errors.New("VAULT_APPROLE_ROLE_ID or VAULT_APPROLE_SECRET_ID not set")
|
||||
ErrInvalidVaultAddress = errors.New("VAULT_ADDRESS is invalid. " +
|
||||
"Should be of the form http(s)://<ip>:<port>")
|
||||
|
||||
@ -117,23 +121,29 @@ func Authenticate(client *api.Client, config map[string]interface{}) (token stri
|
||||
return token, false, nil
|
||||
}
|
||||
|
||||
// or try to use the kubernetes auth method
|
||||
// or use other authentication method: kubernetes, approle
|
||||
if GetVaultParam(config, AuthMethod) != "" {
|
||||
token, err = GetAuthToken(client, config)
|
||||
return token, true, err
|
||||
}
|
||||
|
||||
return "", false, ErrVaultAuthParamsNotSet
|
||||
}
|
||||
}
|
||||
|
||||
// GetAuthToken tries to get the vault token for the provided authentication method.
|
||||
func GetAuthToken(client *api.Client, config map[string]interface{}) (string, error) {
|
||||
path, _, data, err := authenticate(client, config)
|
||||
if err != nil {
|
||||
return "", err
|
||||
method := GetVaultParam(config, AuthMethod)
|
||||
var secret *api.Secret
|
||||
var err error
|
||||
switch method {
|
||||
case AuthMethodKubernetes:
|
||||
secret, err = authKubernetes(client, config)
|
||||
case AuthMethodAppRole:
|
||||
secret, err = authAppRole(client, config)
|
||||
default:
|
||||
return "", ErrAuthMethodUnknown
|
||||
}
|
||||
|
||||
secret, err := client.Logical().Write(path, data)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@ -144,49 +154,52 @@ func GetAuthToken(client *api.Client, config map[string]interface{}) (string, er
|
||||
return "", errors.New("authentication returned empty client token")
|
||||
}
|
||||
|
||||
return secret.Auth.ClientToken, err
|
||||
return secret.Auth.ClientToken, nil
|
||||
}
|
||||
|
||||
func authenticate(client *api.Client, config map[string]interface{}) (string, http.Header, map[string]interface{}, error) {
|
||||
method := GetVaultParam(config, AuthMethod)
|
||||
switch method {
|
||||
case AuthMethodKubernetes:
|
||||
return authKubernetes(client, config)
|
||||
}
|
||||
return "", nil, nil, fmt.Errorf("%s method: %s", method, ErrAuthMethodUnknown)
|
||||
}
|
||||
|
||||
func authKubernetes(client *api.Client, config map[string]interface{}) (string, http.Header, map[string]interface{}, error) {
|
||||
authConfig, err := buildAuthConfig(config)
|
||||
if err != nil {
|
||||
return "", nil, nil, err
|
||||
}
|
||||
method, err := kubernetes.NewKubernetesAuthMethod(authConfig)
|
||||
if err != nil {
|
||||
return "", nil, nil, err
|
||||
}
|
||||
|
||||
return method.Authenticate(context.TODO(), client)
|
||||
}
|
||||
|
||||
func buildAuthConfig(config map[string]interface{}) (*auth.AuthConfig, error) {
|
||||
func authKubernetes(client *api.Client, config map[string]interface{}) (*api.Secret, error) {
|
||||
role := GetVaultParam(config, AuthKubernetesRole)
|
||||
if role == "" {
|
||||
return nil, ErrKubernetesRole
|
||||
}
|
||||
|
||||
loginOpts := []kubernetes.LoginOption{}
|
||||
|
||||
mountPath := GetVaultParam(config, AuthMountPath)
|
||||
if mountPath == "" {
|
||||
mountPath = AuthKubernetesMountPath
|
||||
}
|
||||
tokenPath := GetVaultParam(config, AuthKubernetesTokenPath)
|
||||
loginOpts = append(loginOpts, kubernetes.WithMountPath(mountPath))
|
||||
|
||||
authMountPath := path.Join("auth", mountPath)
|
||||
return &auth.AuthConfig{
|
||||
Logger: hclog.NewNullLogger(),
|
||||
MountPath: authMountPath,
|
||||
Config: map[string]interface{}{
|
||||
"role": role,
|
||||
"token_path": tokenPath,
|
||||
},
|
||||
}, nil
|
||||
tokenPath := GetVaultParam(config, AuthKubernetesTokenPath)
|
||||
if tokenPath != "" {
|
||||
loginOpts = append(loginOpts, kubernetes.WithServiceAccountTokenPath(tokenPath))
|
||||
}
|
||||
|
||||
kAuth, err := kubernetes.NewKubernetesAuth(role, loginOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return kAuth.Login(context.TODO(), client)
|
||||
}
|
||||
|
||||
func authAppRole(client *api.Client, config map[string]interface{}) (*api.Secret, error) {
|
||||
roleID := GetVaultParam(config, AuthAppRoleRoleID)
|
||||
secretIDRaw := GetVaultParam(config, AuthAppRoleSecretID)
|
||||
|
||||
if roleID == "" || secretIDRaw == "" {
|
||||
return nil, ErrAppRoleIDNotSet
|
||||
}
|
||||
secretID := &approle.SecretID{FromString: secretIDRaw}
|
||||
|
||||
appRoleAuth, err := approle.NewAppRoleAuth(
|
||||
roleID,
|
||||
secretID,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return client.Auth().Login(context.TODO(), appRoleAuth)
|
||||
}
|
||||
|
33
vendor/github.com/libopenstorage/secrets/vault/vault.go
generated
vendored
33
vendor/github.com/libopenstorage/secrets/vault/vault.go
generated
vendored
@ -9,6 +9,7 @@ import (
|
||||
"github.com/hashicorp/vault/api"
|
||||
"github.com/libopenstorage/secrets"
|
||||
"github.com/libopenstorage/secrets/vault/utils"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -28,6 +29,8 @@ const (
|
||||
AuthKubernetesRole = utils.AuthKubernetesRole
|
||||
AuthKubernetesTokenPath = utils.AuthKubernetesTokenPath
|
||||
AuthKubernetesMountPath = utils.AuthKubernetesMountPath
|
||||
AuthAppRoleRoleID = utils.AuthAppRoleRoleID
|
||||
AuthAppRoleSecretID = utils.AuthAppRoleSecretID
|
||||
)
|
||||
|
||||
func init() {
|
||||
@ -100,6 +103,14 @@ func New(
|
||||
}
|
||||
client.SetToken(token)
|
||||
|
||||
authMethod := "token"
|
||||
method := utils.GetVaultParam(secretConfig, AuthMethod)
|
||||
if method != "" && utils.GetVaultParam(secretConfig, api.EnvVaultToken) == "" {
|
||||
authMethod = method
|
||||
}
|
||||
|
||||
logrus.Infof("Authenticated to Vault with %v\n", authMethod)
|
||||
|
||||
backendPath := utils.GetVaultParam(secretConfig, VaultBackendPathKey)
|
||||
if backendPath == "" {
|
||||
backendPath = DefaultBackendPath
|
||||
@ -164,25 +175,29 @@ func (v *vaultSecrets) keyPath(secretID string, keyContext map[string]string) ke
|
||||
func (v *vaultSecrets) GetSecret(
|
||||
secretID string,
|
||||
keyContext map[string]string,
|
||||
) (map[string]interface{}, error) {
|
||||
) (map[string]interface{}, secrets.Version, error) {
|
||||
key := v.keyPath(secretID, keyContext)
|
||||
secretValue, err := v.read(key)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get secret: %s: %s", key, err)
|
||||
return nil, secrets.NoVersion, fmt.Errorf("failed to get secret: %s: %s", key, err)
|
||||
}
|
||||
if secretValue == nil {
|
||||
return nil, secrets.ErrInvalidSecretId
|
||||
return nil, secrets.NoVersion, secrets.ErrInvalidSecretId
|
||||
}
|
||||
|
||||
if v.isKvBackendV2 {
|
||||
if data, exists := secretValue.Data[kvDataKey]; exists && data != nil {
|
||||
if data, ok := data.(map[string]interface{}); ok {
|
||||
return data, nil
|
||||
// TODO: Vault does support versioned secrets with KV Backend 2
|
||||
// However it requires clients to invoke a different metadata API call
|
||||
// to fetch the version. Once there is a need for versions from Vault
|
||||
// we can add support for it.
|
||||
return data, secrets.NoVersion, nil
|
||||
}
|
||||
}
|
||||
return nil, secrets.ErrInvalidSecretId
|
||||
return nil, secrets.NoVersion, secrets.ErrInvalidSecretId
|
||||
} else {
|
||||
return secretValue.Data, nil
|
||||
return secretValue.Data, secrets.NoVersion, nil
|
||||
}
|
||||
}
|
||||
|
||||
@ -190,7 +205,7 @@ func (v *vaultSecrets) PutSecret(
|
||||
secretID string,
|
||||
secretData map[string]interface{},
|
||||
keyContext map[string]string,
|
||||
) error {
|
||||
) (secrets.Version, error) {
|
||||
if v.isKvBackendV2 {
|
||||
secretData = map[string]interface{}{
|
||||
kvDataKey: secretData,
|
||||
@ -199,9 +214,9 @@ func (v *vaultSecrets) PutSecret(
|
||||
|
||||
key := v.keyPath(secretID, keyContext)
|
||||
if _, err := v.write(key, secretData); err != nil {
|
||||
return fmt.Errorf("failed to put secret: %s: %s", key, err)
|
||||
return secrets.NoVersion, fmt.Errorf("failed to put secret: %s: %s", key, err)
|
||||
}
|
||||
return nil
|
||||
return secrets.NoVersion, nil
|
||||
}
|
||||
|
||||
func (v *vaultSecrets) DeleteSecret(
|
||||
|
Reference in New Issue
Block a user