|
@@ -38,6 +38,7 @@ import (
|
|
|
authaws "github.com/hashicorp/vault/api/auth/aws"
|
|
authaws "github.com/hashicorp/vault/api/auth/aws"
|
|
|
authkubernetes "github.com/hashicorp/vault/api/auth/kubernetes"
|
|
authkubernetes "github.com/hashicorp/vault/api/auth/kubernetes"
|
|
|
authldap "github.com/hashicorp/vault/api/auth/ldap"
|
|
authldap "github.com/hashicorp/vault/api/auth/ldap"
|
|
|
|
|
+ authuserpass "github.com/hashicorp/vault/api/auth/userpass"
|
|
|
"github.com/spf13/pflag"
|
|
"github.com/spf13/pflag"
|
|
|
"github.com/tidwall/gjson"
|
|
"github.com/tidwall/gjson"
|
|
|
authenticationv1 "k8s.io/api/authentication/v1"
|
|
authenticationv1 "k8s.io/api/authentication/v1"
|
|
@@ -118,21 +119,22 @@ const (
|
|
|
errUnknownCAProvider = "unknown caProvider type given"
|
|
errUnknownCAProvider = "unknown caProvider type given"
|
|
|
errCANamespace = "cannot read secret for CAProvider due to missing namespace on kind ClusterSecretStore"
|
|
errCANamespace = "cannot read secret for CAProvider due to missing namespace on kind ClusterSecretStore"
|
|
|
|
|
|
|
|
- errInvalidStore = "invalid store"
|
|
|
|
|
- errInvalidStoreSpec = "invalid store spec"
|
|
|
|
|
- errInvalidStoreProv = "invalid store provider"
|
|
|
|
|
- errInvalidVaultProv = "invalid vault provider"
|
|
|
|
|
- errInvalidAppRoleID = "invalid Auth.AppRole: neither `roleId` nor `roleRef` was supplied"
|
|
|
|
|
- errInvalidAppRoleRef = "invalid Auth.AppRole.RoleRef: %w"
|
|
|
|
|
- errInvalidAppRoleSec = "invalid Auth.AppRole.SecretRef: %w"
|
|
|
|
|
- errInvalidClientCert = "invalid Auth.Cert.ClientCert: %w"
|
|
|
|
|
- errInvalidCertSec = "invalid Auth.Cert.SecretRef: %w"
|
|
|
|
|
- errInvalidJwtSec = "invalid Auth.Jwt.SecretRef: %w"
|
|
|
|
|
- errInvalidJwtK8sSA = "invalid Auth.Jwt.KubernetesServiceAccountToken.ServiceAccountRef: %w"
|
|
|
|
|
- errInvalidKubeSA = "invalid Auth.Kubernetes.ServiceAccountRef: %w"
|
|
|
|
|
- errInvalidKubeSec = "invalid Auth.Kubernetes.SecretRef: %w"
|
|
|
|
|
- errInvalidLdapSec = "invalid Auth.Ldap.SecretRef: %w"
|
|
|
|
|
- errInvalidTokenRef = "invalid Auth.TokenSecretRef: %w"
|
|
|
|
|
|
|
+ errInvalidStore = "invalid store"
|
|
|
|
|
+ errInvalidStoreSpec = "invalid store spec"
|
|
|
|
|
+ errInvalidStoreProv = "invalid store provider"
|
|
|
|
|
+ errInvalidVaultProv = "invalid vault provider"
|
|
|
|
|
+ errInvalidAppRoleID = "invalid Auth.AppRole: neither `roleId` nor `roleRef` was supplied"
|
|
|
|
|
+ errInvalidAppRoleRef = "invalid Auth.AppRole.RoleRef: %w"
|
|
|
|
|
+ errInvalidAppRoleSec = "invalid Auth.AppRole.SecretRef: %w"
|
|
|
|
|
+ errInvalidClientCert = "invalid Auth.Cert.ClientCert: %w"
|
|
|
|
|
+ errInvalidCertSec = "invalid Auth.Cert.SecretRef: %w"
|
|
|
|
|
+ errInvalidJwtSec = "invalid Auth.Jwt.SecretRef: %w"
|
|
|
|
|
+ errInvalidJwtK8sSA = "invalid Auth.Jwt.KubernetesServiceAccountToken.ServiceAccountRef: %w"
|
|
|
|
|
+ errInvalidKubeSA = "invalid Auth.Kubernetes.ServiceAccountRef: %w"
|
|
|
|
|
+ errInvalidKubeSec = "invalid Auth.Kubernetes.SecretRef: %w"
|
|
|
|
|
+ errInvalidLdapSec = "invalid Auth.Ldap.SecretRef: %w"
|
|
|
|
|
+ errInvalidTokenRef = "invalid Auth.TokenSecretRef: %w"
|
|
|
|
|
+ errInvalidUserPassSec = "invalid Auth.UserPass.SecretRef: %w"
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
// https://github.com/external-secrets/external-secrets/issues/644
|
|
// https://github.com/external-secrets/external-secrets/issues/644
|
|
@@ -375,6 +377,11 @@ func (c *Connector) ValidateStore(store esv1beta1.GenericStore) error {
|
|
|
return fmt.Errorf(errInvalidLdapSec, err)
|
|
return fmt.Errorf(errInvalidLdapSec, err)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+ if p.Auth.UserPass != nil {
|
|
|
|
|
+ if err := utils.ValidateReferentSecretSelector(store, p.Auth.UserPass.SecretRef); err != nil {
|
|
|
|
|
+ return fmt.Errorf(errInvalidUserPassSec, err)
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
if p.Auth.TokenSecretRef != nil {
|
|
if p.Auth.TokenSecretRef != nil {
|
|
|
if err := utils.ValidateReferentSecretSelector(store, *p.Auth.TokenSecretRef); err != nil {
|
|
if err := utils.ValidateReferentSecretSelector(store, *p.Auth.TokenSecretRef); err != nil {
|
|
|
return fmt.Errorf(errInvalidTokenRef, err)
|
|
return fmt.Errorf(errInvalidTokenRef, err)
|
|
@@ -823,6 +830,9 @@ func isReferentSpec(prov *esv1beta1.VaultProvider) bool {
|
|
|
if prov.Auth.Ldap != nil && prov.Auth.Ldap.SecretRef.Namespace == nil {
|
|
if prov.Auth.Ldap != nil && prov.Auth.Ldap.SecretRef.Namespace == nil {
|
|
|
return true
|
|
return true
|
|
|
}
|
|
}
|
|
|
|
|
+ if prov.Auth.UserPass != nil && prov.Auth.UserPass.SecretRef.Namespace == nil {
|
|
|
|
|
+ return true
|
|
|
|
|
+ }
|
|
|
if prov.Auth.Jwt != nil && prov.Auth.Jwt.SecretRef != nil && prov.Auth.Jwt.SecretRef.Namespace == nil {
|
|
if prov.Auth.Jwt != nil && prov.Auth.Jwt.SecretRef != nil && prov.Auth.Jwt.SecretRef.Namespace == nil {
|
|
|
return true
|
|
return true
|
|
|
}
|
|
}
|
|
@@ -1123,6 +1133,11 @@ func (v *client) setAuth(ctx context.Context, cfg *vault.Config) error {
|
|
|
return err
|
|
return err
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ tokenExists, err = setUserPassAuthToken(ctx, v)
|
|
|
|
|
+ if tokenExists {
|
|
|
|
|
+ v.log.V(1).Info("Retrieved new token using userPass auth")
|
|
|
|
|
+ return err
|
|
|
|
|
+ }
|
|
|
tokenExists, err = setJwtAuthToken(ctx, v)
|
|
tokenExists, err = setJwtAuthToken(ctx, v)
|
|
|
if tokenExists {
|
|
if tokenExists {
|
|
|
v.log.V(1).Info("Retrieved new token using JWT auth")
|
|
v.log.V(1).Info("Retrieved new token using JWT auth")
|
|
@@ -1193,6 +1208,18 @@ func setLdapAuthToken(ctx context.Context, v *client) (bool, error) {
|
|
|
return false, nil
|
|
return false, nil
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+func setUserPassAuthToken(ctx context.Context, v *client) (bool, error) {
|
|
|
|
|
+ userPassAuth := v.store.Auth.UserPass
|
|
|
|
|
+ if userPassAuth != nil {
|
|
|
|
|
+ err := v.requestTokenWithUserPassAuth(ctx, userPassAuth)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return true, err
|
|
|
|
|
+ }
|
|
|
|
|
+ return true, nil
|
|
|
|
|
+ }
|
|
|
|
|
+ return false, nil
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
func setJwtAuthToken(ctx context.Context, v *client) (bool, error) {
|
|
func setJwtAuthToken(ctx context.Context, v *client) (bool, error) {
|
|
|
jwtAuth := v.store.Auth.Jwt
|
|
jwtAuth := v.store.Auth.Jwt
|
|
|
if jwtAuth != nil {
|
|
if jwtAuth != nil {
|
|
@@ -1463,6 +1490,26 @@ func (v *client) requestTokenWithLdapAuth(ctx context.Context, ldapAuth *esv1bet
|
|
|
return nil
|
|
return nil
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+func (v *client) requestTokenWithUserPassAuth(ctx context.Context, userPassAuth *esv1beta1.VaultUserPassAuth) error {
|
|
|
|
|
+ username := strings.TrimSpace(userPassAuth.Username)
|
|
|
|
|
+
|
|
|
|
|
+ password, err := v.secretKeyRef(ctx, &userPassAuth.SecretRef)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return err
|
|
|
|
|
+ }
|
|
|
|
|
+ pass := authuserpass.Password{FromString: password}
|
|
|
|
|
+ l, err := authuserpass.NewUserpassAuth(username, &pass, authuserpass.WithMountPath(userPassAuth.Path))
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return err
|
|
|
|
|
+ }
|
|
|
|
|
+ _, err = v.auth.Login(ctx, l)
|
|
|
|
|
+ metrics.ObserveAPICall(constants.ProviderHCVault, constants.CallHCVaultLogin, err)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return err
|
|
|
|
|
+ }
|
|
|
|
|
+ return nil
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
func (v *client) requestTokenWithJwtAuth(ctx context.Context, jwtAuth *esv1beta1.VaultJwtAuth) error {
|
|
func (v *client) requestTokenWithJwtAuth(ctx context.Context, jwtAuth *esv1beta1.VaultJwtAuth) error {
|
|
|
role := strings.TrimSpace(jwtAuth.Role)
|
|
role := strings.TrimSpace(jwtAuth.Role)
|
|
|
var jwt string
|
|
var jwt string
|