mirror of
https://github.com/external-secrets/external-secrets.git
synced 2024-12-15 17:51:01 +00:00
feat: add beyondtrust provider (#3683)
* feat: add beyondtrust provider Signed-off-by: Felipe Hernandez <fhernandez@beyondtrust.com> * feat: edit go.mod and go.sum files Signed-off-by: Felipe Hernandez <fhernandez@beyondtrust.com> * feat: change test file name (provider_test.go) Signed-off-by: Felipe Hernandez <fhernandez@beyondtrust.com> * feat: solve PR comments Signed-off-by: Felipe Hernandez <fhernandez@beyondtrust.com> * feat: organize attributes in a higher hierarchy Signed-off-by: Felipe Hernandez <fhernandez@beyondtrust.com> * fix: fix sonar cloud issues and go.mod file conflicts Signed-off-by: Felipe Hernandez <fhernandez@beyondtrust.com> * fix: fix PR comments and apply table driven tests Signed-off-by: Felipe Hernandez <fhernandez@beyondtrust.com> * fix: fix PR comments Signed-off-by: Felipe Hernandez <fhernandez@beyondtrust.com> * fix: fix lint issues Signed-off-by: Felipe Hernandez <fhernandez@beyondtrust.com> * fix: fix lint issues on tests Signed-off-by: Felipe Hernandez <fhernandez@beyondtrust.com> * fix: run make fmt Signed-off-by: Felipe Hernandez <fhernandez@beyondtrust.com> * fix: apply camelCase to yaml attributes Signed-off-by: Felipe Hernandez <fhernandez@beyondtrust.com> * fix: solve go.mod file conflict Signed-off-by: Felipe Hernandez <fhernandez@beyondtrust.com> * fix: run make check-diff Signed-off-by: Felipe Hernandez <fhernandez@beyondtrust.com> --------- Signed-off-by: Felipe Hernandez <fhernandez@beyondtrust.com> Signed-off-by: btfhernandez <133419363+btfhernandez@users.noreply.github.com>
This commit is contained in:
parent
e359df615a
commit
77f5d0ad91
16 changed files with 1767 additions and 0 deletions
|
@ -0,0 +1,63 @@
|
||||||
|
/*
|
||||||
|
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 v1beta1
|
||||||
|
|
||||||
|
import esmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
|
||||||
|
|
||||||
|
type BeyondTrustProviderSecretRef struct {
|
||||||
|
|
||||||
|
// Value can be specified directly to set a value without using a secret.
|
||||||
|
// +optional
|
||||||
|
Value string `json:"value,omitempty"`
|
||||||
|
|
||||||
|
// SecretRef references a key in a secret that will be used as value.
|
||||||
|
// +optional
|
||||||
|
SecretRef *esmeta.SecretKeySelector `json:"secretRef,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configures a store to sync secrets using BeyondTrust Password Safe.
|
||||||
|
type BeyondtrustAuth struct {
|
||||||
|
// +required - API OAuth Client ID.
|
||||||
|
ClientID *BeyondTrustProviderSecretRef `json:"clientId"`
|
||||||
|
// +required - API OAuth Client Secret.
|
||||||
|
ClientSecret *BeyondTrustProviderSecretRef `json:"clientSecret"`
|
||||||
|
// Content of the certificate (cert.pem) for use when authenticating with an OAuth client Id using a Client Certificate.
|
||||||
|
Certificate *BeyondTrustProviderSecretRef `json:"certificate,omitempty"`
|
||||||
|
// Certificate private key (key.pem). For use when authenticating with an OAuth client Id
|
||||||
|
CertificateKey *BeyondTrustProviderSecretRef `json:"certificateKey,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configures a store to sync secrets using BeyondTrust Password Safe.
|
||||||
|
type BeyondtrustServer struct {
|
||||||
|
// +required - BeyondTrust Password Safe API URL. https://example.com:443/beyondtrust/api/public/V3.
|
||||||
|
APIURL string `json:"apiUrl"`
|
||||||
|
// The secret retrieval type. SECRET = Secrets Safe (credential, text, file). MANAGED_ACCOUNT = Password Safe account associated with a system.
|
||||||
|
RetrievalType string `json:"retrievalType,omitempty"`
|
||||||
|
// A character that separates the folder names.
|
||||||
|
Separator string `json:"separator,omitempty"`
|
||||||
|
// +required - Indicates whether to verify the certificate authority on the Secrets Safe instance. Warning - false is insecure, instructs the BT provider not to verify the certificate authority.
|
||||||
|
VerifyCA bool `json:"verifyCA"`
|
||||||
|
// Timeout specifies a time limit for requests made by this Client. The timeout includes connection time, any redirects, and reading the response body. Defaults to 45 seconds.
|
||||||
|
ClientTimeOutSeconds int `json:"clientTimeOutSeconds,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type BeyondtrustProvider struct {
|
||||||
|
|
||||||
|
// Auth configures how the operator authenticates with Beyondtrust.
|
||||||
|
Auth *BeyondtrustAuth `json:"auth"`
|
||||||
|
|
||||||
|
// Auth configures how API server works.
|
||||||
|
Server *BeyondtrustServer `json:"server"`
|
||||||
|
}
|
|
@ -185,6 +185,10 @@ type SecretStoreProvider struct {
|
||||||
// Infisical configures this store to sync secrets using the Infisical provider
|
// Infisical configures this store to sync secrets using the Infisical provider
|
||||||
// +optional
|
// +optional
|
||||||
Infisical *InfisicalProvider `json:"infisical,omitempty"`
|
Infisical *InfisicalProvider `json:"infisical,omitempty"`
|
||||||
|
|
||||||
|
// Beyondtrust configures this store to sync secrets using Password Safe provider.
|
||||||
|
// +optional
|
||||||
|
Beyondtrust *BeyondtrustProvider `json:"beyondtrust,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type CAProviderType string
|
type CAProviderType string
|
||||||
|
|
|
@ -391,6 +391,101 @@ func (in *AzureKVProvider) DeepCopy() *AzureKVProvider {
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *BeyondTrustProviderSecretRef) DeepCopyInto(out *BeyondTrustProviderSecretRef) {
|
||||||
|
*out = *in
|
||||||
|
if in.SecretRef != nil {
|
||||||
|
in, out := &in.SecretRef, &out.SecretRef
|
||||||
|
*out = new(metav1.SecretKeySelector)
|
||||||
|
(*in).DeepCopyInto(*out)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BeyondTrustProviderSecretRef.
|
||||||
|
func (in *BeyondTrustProviderSecretRef) DeepCopy() *BeyondTrustProviderSecretRef {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(BeyondTrustProviderSecretRef)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *BeyondtrustAuth) DeepCopyInto(out *BeyondtrustAuth) {
|
||||||
|
*out = *in
|
||||||
|
if in.ClientID != nil {
|
||||||
|
in, out := &in.ClientID, &out.ClientID
|
||||||
|
*out = new(BeyondTrustProviderSecretRef)
|
||||||
|
(*in).DeepCopyInto(*out)
|
||||||
|
}
|
||||||
|
if in.ClientSecret != nil {
|
||||||
|
in, out := &in.ClientSecret, &out.ClientSecret
|
||||||
|
*out = new(BeyondTrustProviderSecretRef)
|
||||||
|
(*in).DeepCopyInto(*out)
|
||||||
|
}
|
||||||
|
if in.Certificate != nil {
|
||||||
|
in, out := &in.Certificate, &out.Certificate
|
||||||
|
*out = new(BeyondTrustProviderSecretRef)
|
||||||
|
(*in).DeepCopyInto(*out)
|
||||||
|
}
|
||||||
|
if in.CertificateKey != nil {
|
||||||
|
in, out := &in.CertificateKey, &out.CertificateKey
|
||||||
|
*out = new(BeyondTrustProviderSecretRef)
|
||||||
|
(*in).DeepCopyInto(*out)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BeyondtrustAuth.
|
||||||
|
func (in *BeyondtrustAuth) DeepCopy() *BeyondtrustAuth {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(BeyondtrustAuth)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *BeyondtrustProvider) DeepCopyInto(out *BeyondtrustProvider) {
|
||||||
|
*out = *in
|
||||||
|
if in.Auth != nil {
|
||||||
|
in, out := &in.Auth, &out.Auth
|
||||||
|
*out = new(BeyondtrustAuth)
|
||||||
|
(*in).DeepCopyInto(*out)
|
||||||
|
}
|
||||||
|
if in.Server != nil {
|
||||||
|
in, out := &in.Server, &out.Server
|
||||||
|
*out = new(BeyondtrustServer)
|
||||||
|
**out = **in
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BeyondtrustProvider.
|
||||||
|
func (in *BeyondtrustProvider) DeepCopy() *BeyondtrustProvider {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(BeyondtrustProvider)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *BeyondtrustServer) DeepCopyInto(out *BeyondtrustServer) {
|
||||||
|
*out = *in
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BeyondtrustServer.
|
||||||
|
func (in *BeyondtrustServer) DeepCopy() *BeyondtrustServer {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(BeyondtrustServer)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
func (in *BitwardenSecretsManagerAuth) DeepCopyInto(out *BitwardenSecretsManagerAuth) {
|
func (in *BitwardenSecretsManagerAuth) DeepCopyInto(out *BitwardenSecretsManagerAuth) {
|
||||||
*out = *in
|
*out = *in
|
||||||
|
@ -2543,6 +2638,11 @@ func (in *SecretStoreProvider) DeepCopyInto(out *SecretStoreProvider) {
|
||||||
*out = new(InfisicalProvider)
|
*out = new(InfisicalProvider)
|
||||||
(*in).DeepCopyInto(*out)
|
(*in).DeepCopyInto(*out)
|
||||||
}
|
}
|
||||||
|
if in.Beyondtrust != nil {
|
||||||
|
in, out := &in.Beyondtrust, &out.Beyondtrust
|
||||||
|
*out = new(BeyondtrustProvider)
|
||||||
|
(*in).DeepCopyInto(*out)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretStoreProvider.
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretStoreProvider.
|
||||||
|
|
|
@ -2297,6 +2297,156 @@ spec:
|
||||||
required:
|
required:
|
||||||
- vaultUrl
|
- vaultUrl
|
||||||
type: object
|
type: object
|
||||||
|
beyondtrust:
|
||||||
|
description: Beyondtrust configures this store to sync secrets
|
||||||
|
using Password Safe provider.
|
||||||
|
properties:
|
||||||
|
auth:
|
||||||
|
description: Auth configures how the operator authenticates
|
||||||
|
with Beyondtrust.
|
||||||
|
properties:
|
||||||
|
certificate:
|
||||||
|
description: Content of the certificate (cert.pem) for
|
||||||
|
use when authenticating with an OAuth client Id using
|
||||||
|
a Client Certificate.
|
||||||
|
properties:
|
||||||
|
secretRef:
|
||||||
|
description: SecretRef references a key in a secret
|
||||||
|
that will be used as value.
|
||||||
|
properties:
|
||||||
|
key:
|
||||||
|
description: |-
|
||||||
|
The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be
|
||||||
|
defaulted, in others it may be required.
|
||||||
|
type: string
|
||||||
|
name:
|
||||||
|
description: The name of the Secret resource being
|
||||||
|
referred to.
|
||||||
|
type: string
|
||||||
|
namespace:
|
||||||
|
description: |-
|
||||||
|
Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults
|
||||||
|
to the namespace of the referent.
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
value:
|
||||||
|
description: Value can be specified directly to set
|
||||||
|
a value without using a secret.
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
certificateKey:
|
||||||
|
description: Certificate private key (key.pem). For use
|
||||||
|
when authenticating with an OAuth client Id
|
||||||
|
properties:
|
||||||
|
secretRef:
|
||||||
|
description: SecretRef references a key in a secret
|
||||||
|
that will be used as value.
|
||||||
|
properties:
|
||||||
|
key:
|
||||||
|
description: |-
|
||||||
|
The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be
|
||||||
|
defaulted, in others it may be required.
|
||||||
|
type: string
|
||||||
|
name:
|
||||||
|
description: The name of the Secret resource being
|
||||||
|
referred to.
|
||||||
|
type: string
|
||||||
|
namespace:
|
||||||
|
description: |-
|
||||||
|
Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults
|
||||||
|
to the namespace of the referent.
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
value:
|
||||||
|
description: Value can be specified directly to set
|
||||||
|
a value without using a secret.
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
clientId:
|
||||||
|
properties:
|
||||||
|
secretRef:
|
||||||
|
description: SecretRef references a key in a secret
|
||||||
|
that will be used as value.
|
||||||
|
properties:
|
||||||
|
key:
|
||||||
|
description: |-
|
||||||
|
The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be
|
||||||
|
defaulted, in others it may be required.
|
||||||
|
type: string
|
||||||
|
name:
|
||||||
|
description: The name of the Secret resource being
|
||||||
|
referred to.
|
||||||
|
type: string
|
||||||
|
namespace:
|
||||||
|
description: |-
|
||||||
|
Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults
|
||||||
|
to the namespace of the referent.
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
value:
|
||||||
|
description: Value can be specified directly to set
|
||||||
|
a value without using a secret.
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
clientSecret:
|
||||||
|
properties:
|
||||||
|
secretRef:
|
||||||
|
description: SecretRef references a key in a secret
|
||||||
|
that will be used as value.
|
||||||
|
properties:
|
||||||
|
key:
|
||||||
|
description: |-
|
||||||
|
The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be
|
||||||
|
defaulted, in others it may be required.
|
||||||
|
type: string
|
||||||
|
name:
|
||||||
|
description: The name of the Secret resource being
|
||||||
|
referred to.
|
||||||
|
type: string
|
||||||
|
namespace:
|
||||||
|
description: |-
|
||||||
|
Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults
|
||||||
|
to the namespace of the referent.
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
value:
|
||||||
|
description: Value can be specified directly to set
|
||||||
|
a value without using a secret.
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- clientId
|
||||||
|
- clientSecret
|
||||||
|
type: object
|
||||||
|
server:
|
||||||
|
description: Auth configures how API server works.
|
||||||
|
properties:
|
||||||
|
apiUrl:
|
||||||
|
type: string
|
||||||
|
clientTimeOutSeconds:
|
||||||
|
description: Timeout specifies a time limit for requests
|
||||||
|
made by this Client. The timeout includes connection
|
||||||
|
time, any redirects, and reading the response body.
|
||||||
|
Defaults to 45 seconds.
|
||||||
|
type: integer
|
||||||
|
retrievalType:
|
||||||
|
description: The secret retrieval type. SECRET = Secrets
|
||||||
|
Safe (credential, text, file). MANAGED_ACCOUNT = Password
|
||||||
|
Safe account associated with a system.
|
||||||
|
type: string
|
||||||
|
separator:
|
||||||
|
description: A character that separates the folder names.
|
||||||
|
type: string
|
||||||
|
verifyCA:
|
||||||
|
type: boolean
|
||||||
|
required:
|
||||||
|
- apiUrl
|
||||||
|
- verifyCA
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- auth
|
||||||
|
- server
|
||||||
|
type: object
|
||||||
bitwardensecretsmanager:
|
bitwardensecretsmanager:
|
||||||
description: BitwardenSecretsManager configures this store to
|
description: BitwardenSecretsManager configures this store to
|
||||||
sync secrets using BitwardenSecretsManager provider
|
sync secrets using BitwardenSecretsManager provider
|
||||||
|
|
|
@ -2297,6 +2297,156 @@ spec:
|
||||||
required:
|
required:
|
||||||
- vaultUrl
|
- vaultUrl
|
||||||
type: object
|
type: object
|
||||||
|
beyondtrust:
|
||||||
|
description: Beyondtrust configures this store to sync secrets
|
||||||
|
using Password Safe provider.
|
||||||
|
properties:
|
||||||
|
auth:
|
||||||
|
description: Auth configures how the operator authenticates
|
||||||
|
with Beyondtrust.
|
||||||
|
properties:
|
||||||
|
certificate:
|
||||||
|
description: Content of the certificate (cert.pem) for
|
||||||
|
use when authenticating with an OAuth client Id using
|
||||||
|
a Client Certificate.
|
||||||
|
properties:
|
||||||
|
secretRef:
|
||||||
|
description: SecretRef references a key in a secret
|
||||||
|
that will be used as value.
|
||||||
|
properties:
|
||||||
|
key:
|
||||||
|
description: |-
|
||||||
|
The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be
|
||||||
|
defaulted, in others it may be required.
|
||||||
|
type: string
|
||||||
|
name:
|
||||||
|
description: The name of the Secret resource being
|
||||||
|
referred to.
|
||||||
|
type: string
|
||||||
|
namespace:
|
||||||
|
description: |-
|
||||||
|
Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults
|
||||||
|
to the namespace of the referent.
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
value:
|
||||||
|
description: Value can be specified directly to set
|
||||||
|
a value without using a secret.
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
certificateKey:
|
||||||
|
description: Certificate private key (key.pem). For use
|
||||||
|
when authenticating with an OAuth client Id
|
||||||
|
properties:
|
||||||
|
secretRef:
|
||||||
|
description: SecretRef references a key in a secret
|
||||||
|
that will be used as value.
|
||||||
|
properties:
|
||||||
|
key:
|
||||||
|
description: |-
|
||||||
|
The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be
|
||||||
|
defaulted, in others it may be required.
|
||||||
|
type: string
|
||||||
|
name:
|
||||||
|
description: The name of the Secret resource being
|
||||||
|
referred to.
|
||||||
|
type: string
|
||||||
|
namespace:
|
||||||
|
description: |-
|
||||||
|
Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults
|
||||||
|
to the namespace of the referent.
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
value:
|
||||||
|
description: Value can be specified directly to set
|
||||||
|
a value without using a secret.
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
clientId:
|
||||||
|
properties:
|
||||||
|
secretRef:
|
||||||
|
description: SecretRef references a key in a secret
|
||||||
|
that will be used as value.
|
||||||
|
properties:
|
||||||
|
key:
|
||||||
|
description: |-
|
||||||
|
The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be
|
||||||
|
defaulted, in others it may be required.
|
||||||
|
type: string
|
||||||
|
name:
|
||||||
|
description: The name of the Secret resource being
|
||||||
|
referred to.
|
||||||
|
type: string
|
||||||
|
namespace:
|
||||||
|
description: |-
|
||||||
|
Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults
|
||||||
|
to the namespace of the referent.
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
value:
|
||||||
|
description: Value can be specified directly to set
|
||||||
|
a value without using a secret.
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
clientSecret:
|
||||||
|
properties:
|
||||||
|
secretRef:
|
||||||
|
description: SecretRef references a key in a secret
|
||||||
|
that will be used as value.
|
||||||
|
properties:
|
||||||
|
key:
|
||||||
|
description: |-
|
||||||
|
The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be
|
||||||
|
defaulted, in others it may be required.
|
||||||
|
type: string
|
||||||
|
name:
|
||||||
|
description: The name of the Secret resource being
|
||||||
|
referred to.
|
||||||
|
type: string
|
||||||
|
namespace:
|
||||||
|
description: |-
|
||||||
|
Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults
|
||||||
|
to the namespace of the referent.
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
value:
|
||||||
|
description: Value can be specified directly to set
|
||||||
|
a value without using a secret.
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- clientId
|
||||||
|
- clientSecret
|
||||||
|
type: object
|
||||||
|
server:
|
||||||
|
description: Auth configures how API server works.
|
||||||
|
properties:
|
||||||
|
apiUrl:
|
||||||
|
type: string
|
||||||
|
clientTimeOutSeconds:
|
||||||
|
description: Timeout specifies a time limit for requests
|
||||||
|
made by this Client. The timeout includes connection
|
||||||
|
time, any redirects, and reading the response body.
|
||||||
|
Defaults to 45 seconds.
|
||||||
|
type: integer
|
||||||
|
retrievalType:
|
||||||
|
description: The secret retrieval type. SECRET = Secrets
|
||||||
|
Safe (credential, text, file). MANAGED_ACCOUNT = Password
|
||||||
|
Safe account associated with a system.
|
||||||
|
type: string
|
||||||
|
separator:
|
||||||
|
description: A character that separates the folder names.
|
||||||
|
type: string
|
||||||
|
verifyCA:
|
||||||
|
type: boolean
|
||||||
|
required:
|
||||||
|
- apiUrl
|
||||||
|
- verifyCA
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- auth
|
||||||
|
- server
|
||||||
|
type: object
|
||||||
bitwardensecretsmanager:
|
bitwardensecretsmanager:
|
||||||
description: BitwardenSecretsManager configures this store to
|
description: BitwardenSecretsManager configures this store to
|
||||||
sync secrets using BitwardenSecretsManager provider
|
sync secrets using BitwardenSecretsManager provider
|
||||||
|
|
|
@ -2807,6 +2807,134 @@ spec:
|
||||||
required:
|
required:
|
||||||
- vaultUrl
|
- vaultUrl
|
||||||
type: object
|
type: object
|
||||||
|
beyondtrust:
|
||||||
|
description: Beyondtrust configures this store to sync secrets using Password Safe provider.
|
||||||
|
properties:
|
||||||
|
auth:
|
||||||
|
description: Auth configures how the operator authenticates with Beyondtrust.
|
||||||
|
properties:
|
||||||
|
certificate:
|
||||||
|
description: Content of the certificate (cert.pem) for use when authenticating with an OAuth client Id using a Client Certificate.
|
||||||
|
properties:
|
||||||
|
secretRef:
|
||||||
|
description: SecretRef references a key in a secret that will be used as value.
|
||||||
|
properties:
|
||||||
|
key:
|
||||||
|
description: |-
|
||||||
|
The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be
|
||||||
|
defaulted, in others it may be required.
|
||||||
|
type: string
|
||||||
|
name:
|
||||||
|
description: The name of the Secret resource being referred to.
|
||||||
|
type: string
|
||||||
|
namespace:
|
||||||
|
description: |-
|
||||||
|
Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults
|
||||||
|
to the namespace of the referent.
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
value:
|
||||||
|
description: Value can be specified directly to set a value without using a secret.
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
certificateKey:
|
||||||
|
description: Certificate private key (key.pem). For use when authenticating with an OAuth client Id
|
||||||
|
properties:
|
||||||
|
secretRef:
|
||||||
|
description: SecretRef references a key in a secret that will be used as value.
|
||||||
|
properties:
|
||||||
|
key:
|
||||||
|
description: |-
|
||||||
|
The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be
|
||||||
|
defaulted, in others it may be required.
|
||||||
|
type: string
|
||||||
|
name:
|
||||||
|
description: The name of the Secret resource being referred to.
|
||||||
|
type: string
|
||||||
|
namespace:
|
||||||
|
description: |-
|
||||||
|
Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults
|
||||||
|
to the namespace of the referent.
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
value:
|
||||||
|
description: Value can be specified directly to set a value without using a secret.
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
clientId:
|
||||||
|
properties:
|
||||||
|
secretRef:
|
||||||
|
description: SecretRef references a key in a secret that will be used as value.
|
||||||
|
properties:
|
||||||
|
key:
|
||||||
|
description: |-
|
||||||
|
The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be
|
||||||
|
defaulted, in others it may be required.
|
||||||
|
type: string
|
||||||
|
name:
|
||||||
|
description: The name of the Secret resource being referred to.
|
||||||
|
type: string
|
||||||
|
namespace:
|
||||||
|
description: |-
|
||||||
|
Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults
|
||||||
|
to the namespace of the referent.
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
value:
|
||||||
|
description: Value can be specified directly to set a value without using a secret.
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
clientSecret:
|
||||||
|
properties:
|
||||||
|
secretRef:
|
||||||
|
description: SecretRef references a key in a secret that will be used as value.
|
||||||
|
properties:
|
||||||
|
key:
|
||||||
|
description: |-
|
||||||
|
The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be
|
||||||
|
defaulted, in others it may be required.
|
||||||
|
type: string
|
||||||
|
name:
|
||||||
|
description: The name of the Secret resource being referred to.
|
||||||
|
type: string
|
||||||
|
namespace:
|
||||||
|
description: |-
|
||||||
|
Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults
|
||||||
|
to the namespace of the referent.
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
value:
|
||||||
|
description: Value can be specified directly to set a value without using a secret.
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- clientId
|
||||||
|
- clientSecret
|
||||||
|
type: object
|
||||||
|
server:
|
||||||
|
description: Auth configures how API server works.
|
||||||
|
properties:
|
||||||
|
apiUrl:
|
||||||
|
type: string
|
||||||
|
clientTimeOutSeconds:
|
||||||
|
description: Timeout specifies a time limit for requests made by this Client. The timeout includes connection time, any redirects, and reading the response body. Defaults to 45 seconds.
|
||||||
|
type: integer
|
||||||
|
retrievalType:
|
||||||
|
description: The secret retrieval type. SECRET = Secrets Safe (credential, text, file). MANAGED_ACCOUNT = Password Safe account associated with a system.
|
||||||
|
type: string
|
||||||
|
separator:
|
||||||
|
description: A character that separates the folder names.
|
||||||
|
type: string
|
||||||
|
verifyCA:
|
||||||
|
type: boolean
|
||||||
|
required:
|
||||||
|
- apiUrl
|
||||||
|
- verifyCA
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- auth
|
||||||
|
- server
|
||||||
|
type: object
|
||||||
bitwardensecretsmanager:
|
bitwardensecretsmanager:
|
||||||
description: BitwardenSecretsManager configures this store to sync secrets using BitwardenSecretsManager provider
|
description: BitwardenSecretsManager configures this store to sync secrets using BitwardenSecretsManager provider
|
||||||
properties:
|
properties:
|
||||||
|
@ -8441,6 +8569,134 @@ spec:
|
||||||
required:
|
required:
|
||||||
- vaultUrl
|
- vaultUrl
|
||||||
type: object
|
type: object
|
||||||
|
beyondtrust:
|
||||||
|
description: Beyondtrust configures this store to sync secrets using Password Safe provider.
|
||||||
|
properties:
|
||||||
|
auth:
|
||||||
|
description: Auth configures how the operator authenticates with Beyondtrust.
|
||||||
|
properties:
|
||||||
|
certificate:
|
||||||
|
description: Content of the certificate (cert.pem) for use when authenticating with an OAuth client Id using a Client Certificate.
|
||||||
|
properties:
|
||||||
|
secretRef:
|
||||||
|
description: SecretRef references a key in a secret that will be used as value.
|
||||||
|
properties:
|
||||||
|
key:
|
||||||
|
description: |-
|
||||||
|
The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be
|
||||||
|
defaulted, in others it may be required.
|
||||||
|
type: string
|
||||||
|
name:
|
||||||
|
description: The name of the Secret resource being referred to.
|
||||||
|
type: string
|
||||||
|
namespace:
|
||||||
|
description: |-
|
||||||
|
Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults
|
||||||
|
to the namespace of the referent.
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
value:
|
||||||
|
description: Value can be specified directly to set a value without using a secret.
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
certificateKey:
|
||||||
|
description: Certificate private key (key.pem). For use when authenticating with an OAuth client Id
|
||||||
|
properties:
|
||||||
|
secretRef:
|
||||||
|
description: SecretRef references a key in a secret that will be used as value.
|
||||||
|
properties:
|
||||||
|
key:
|
||||||
|
description: |-
|
||||||
|
The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be
|
||||||
|
defaulted, in others it may be required.
|
||||||
|
type: string
|
||||||
|
name:
|
||||||
|
description: The name of the Secret resource being referred to.
|
||||||
|
type: string
|
||||||
|
namespace:
|
||||||
|
description: |-
|
||||||
|
Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults
|
||||||
|
to the namespace of the referent.
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
value:
|
||||||
|
description: Value can be specified directly to set a value without using a secret.
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
clientId:
|
||||||
|
properties:
|
||||||
|
secretRef:
|
||||||
|
description: SecretRef references a key in a secret that will be used as value.
|
||||||
|
properties:
|
||||||
|
key:
|
||||||
|
description: |-
|
||||||
|
The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be
|
||||||
|
defaulted, in others it may be required.
|
||||||
|
type: string
|
||||||
|
name:
|
||||||
|
description: The name of the Secret resource being referred to.
|
||||||
|
type: string
|
||||||
|
namespace:
|
||||||
|
description: |-
|
||||||
|
Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults
|
||||||
|
to the namespace of the referent.
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
value:
|
||||||
|
description: Value can be specified directly to set a value without using a secret.
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
clientSecret:
|
||||||
|
properties:
|
||||||
|
secretRef:
|
||||||
|
description: SecretRef references a key in a secret that will be used as value.
|
||||||
|
properties:
|
||||||
|
key:
|
||||||
|
description: |-
|
||||||
|
The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be
|
||||||
|
defaulted, in others it may be required.
|
||||||
|
type: string
|
||||||
|
name:
|
||||||
|
description: The name of the Secret resource being referred to.
|
||||||
|
type: string
|
||||||
|
namespace:
|
||||||
|
description: |-
|
||||||
|
Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults
|
||||||
|
to the namespace of the referent.
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
value:
|
||||||
|
description: Value can be specified directly to set a value without using a secret.
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- clientId
|
||||||
|
- clientSecret
|
||||||
|
type: object
|
||||||
|
server:
|
||||||
|
description: Auth configures how API server works.
|
||||||
|
properties:
|
||||||
|
apiUrl:
|
||||||
|
type: string
|
||||||
|
clientTimeOutSeconds:
|
||||||
|
description: Timeout specifies a time limit for requests made by this Client. The timeout includes connection time, any redirects, and reading the response body. Defaults to 45 seconds.
|
||||||
|
type: integer
|
||||||
|
retrievalType:
|
||||||
|
description: The secret retrieval type. SECRET = Secrets Safe (credential, text, file). MANAGED_ACCOUNT = Password Safe account associated with a system.
|
||||||
|
type: string
|
||||||
|
separator:
|
||||||
|
description: A character that separates the folder names.
|
||||||
|
type: string
|
||||||
|
verifyCA:
|
||||||
|
type: boolean
|
||||||
|
required:
|
||||||
|
- apiUrl
|
||||||
|
- verifyCA
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- auth
|
||||||
|
- server
|
||||||
|
type: object
|
||||||
bitwardensecretsmanager:
|
bitwardensecretsmanager:
|
||||||
description: BitwardenSecretsManager configures this store to sync secrets using BitwardenSecretsManager provider
|
description: BitwardenSecretsManager configures this store to sync secrets using BitwardenSecretsManager provider
|
||||||
properties:
|
properties:
|
||||||
|
|
243
docs/api/spec.md
243
docs/api/spec.md
|
@ -1013,6 +1013,235 @@ string
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
<h3 id="external-secrets.io/v1beta1.BeyondTrustProviderSecretRef">BeyondTrustProviderSecretRef
|
||||||
|
</h3>
|
||||||
|
<p>
|
||||||
|
(<em>Appears on:</em>
|
||||||
|
<a href="#external-secrets.io/v1beta1.BeyondtrustAuth">BeyondtrustAuth</a>)
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
</p>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Field</th>
|
||||||
|
<th>Description</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<code>value</code></br>
|
||||||
|
<em>
|
||||||
|
string
|
||||||
|
</em>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<em>(Optional)</em>
|
||||||
|
<p>Value can be specified directly to set a value without using a secret.</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<code>secretRef</code></br>
|
||||||
|
<em>
|
||||||
|
<a href="https://pkg.go.dev/github.com/external-secrets/external-secrets/apis/meta/v1#SecretKeySelector">
|
||||||
|
External Secrets meta/v1.SecretKeySelector
|
||||||
|
</a>
|
||||||
|
</em>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<em>(Optional)</em>
|
||||||
|
<p>SecretRef references a key in a secret that will be used as value.</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<h3 id="external-secrets.io/v1beta1.BeyondtrustAuth">BeyondtrustAuth
|
||||||
|
</h3>
|
||||||
|
<p>
|
||||||
|
(<em>Appears on:</em>
|
||||||
|
<a href="#external-secrets.io/v1beta1.BeyondtrustProvider">BeyondtrustProvider</a>)
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<p>Configures a store to sync secrets using BeyondTrust Password Safe.</p>
|
||||||
|
</p>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Field</th>
|
||||||
|
<th>Description</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<code>clientId</code></br>
|
||||||
|
<em>
|
||||||
|
<a href="#external-secrets.io/v1beta1.BeyondTrustProviderSecretRef">
|
||||||
|
BeyondTrustProviderSecretRef
|
||||||
|
</a>
|
||||||
|
</em>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<code>clientSecret</code></br>
|
||||||
|
<em>
|
||||||
|
<a href="#external-secrets.io/v1beta1.BeyondTrustProviderSecretRef">
|
||||||
|
BeyondTrustProviderSecretRef
|
||||||
|
</a>
|
||||||
|
</em>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<code>certificate</code></br>
|
||||||
|
<em>
|
||||||
|
<a href="#external-secrets.io/v1beta1.BeyondTrustProviderSecretRef">
|
||||||
|
BeyondTrustProviderSecretRef
|
||||||
|
</a>
|
||||||
|
</em>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p>Content of the certificate (cert.pem) for use when authenticating with an OAuth client Id using a Client Certificate.</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<code>certificateKey</code></br>
|
||||||
|
<em>
|
||||||
|
<a href="#external-secrets.io/v1beta1.BeyondTrustProviderSecretRef">
|
||||||
|
BeyondTrustProviderSecretRef
|
||||||
|
</a>
|
||||||
|
</em>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p>Certificate private key (key.pem). For use when authenticating with an OAuth client Id</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<h3 id="external-secrets.io/v1beta1.BeyondtrustProvider">BeyondtrustProvider
|
||||||
|
</h3>
|
||||||
|
<p>
|
||||||
|
(<em>Appears on:</em>
|
||||||
|
<a href="#external-secrets.io/v1beta1.SecretStoreProvider">SecretStoreProvider</a>)
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
</p>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Field</th>
|
||||||
|
<th>Description</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<code>auth</code></br>
|
||||||
|
<em>
|
||||||
|
<a href="#external-secrets.io/v1beta1.BeyondtrustAuth">
|
||||||
|
BeyondtrustAuth
|
||||||
|
</a>
|
||||||
|
</em>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p>Auth configures how the operator authenticates with Beyondtrust.</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<code>server</code></br>
|
||||||
|
<em>
|
||||||
|
<a href="#external-secrets.io/v1beta1.BeyondtrustServer">
|
||||||
|
BeyondtrustServer
|
||||||
|
</a>
|
||||||
|
</em>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p>Auth configures how API server works.</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<h3 id="external-secrets.io/v1beta1.BeyondtrustServer">BeyondtrustServer
|
||||||
|
</h3>
|
||||||
|
<p>
|
||||||
|
(<em>Appears on:</em>
|
||||||
|
<a href="#external-secrets.io/v1beta1.BeyondtrustProvider">BeyondtrustProvider</a>)
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<p>Configures a store to sync secrets using BeyondTrust Password Safe.</p>
|
||||||
|
</p>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Field</th>
|
||||||
|
<th>Description</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<code>apiUrl</code></br>
|
||||||
|
<em>
|
||||||
|
string
|
||||||
|
</em>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<code>retrievalType</code></br>
|
||||||
|
<em>
|
||||||
|
string
|
||||||
|
</em>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p>The secret retrieval type. SECRET = Secrets Safe (credential, text, file). MANAGED_ACCOUNT = Password Safe account associated with a system.</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<code>separator</code></br>
|
||||||
|
<em>
|
||||||
|
string
|
||||||
|
</em>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p>A character that separates the folder names.</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<code>verifyCA</code></br>
|
||||||
|
<em>
|
||||||
|
bool
|
||||||
|
</em>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<code>clientTimeOutSeconds</code></br>
|
||||||
|
<em>
|
||||||
|
int
|
||||||
|
</em>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p>Timeout specifies a time limit for requests made by this Client. The timeout includes connection time, any redirects, and reading the response body. Defaults to 45 seconds.</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
<h3 id="external-secrets.io/v1beta1.BitwardenSecretsManagerAuth">BitwardenSecretsManagerAuth
|
<h3 id="external-secrets.io/v1beta1.BitwardenSecretsManagerAuth">BitwardenSecretsManagerAuth
|
||||||
</h3>
|
</h3>
|
||||||
<p>
|
<p>
|
||||||
|
@ -6660,6 +6889,20 @@ InfisicalProvider
|
||||||
<p>Infisical configures this store to sync secrets using the Infisical provider</p>
|
<p>Infisical configures this store to sync secrets using the Infisical provider</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<code>beyondtrust</code></br>
|
||||||
|
<em>
|
||||||
|
<a href="#external-secrets.io/v1beta1.BeyondtrustProvider">
|
||||||
|
BeyondtrustProvider
|
||||||
|
</a>
|
||||||
|
</em>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<em>(Optional)</em>
|
||||||
|
<p>Beyondtrust configures this store to sync secrets using Password Safe provider.</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<h3 id="external-secrets.io/v1beta1.SecretStoreRef">SecretStoreRef
|
<h3 id="external-secrets.io/v1beta1.SecretStoreRef">SecretStoreRef
|
||||||
|
|
|
@ -53,6 +53,7 @@ The following table describes the stability level of each provider and who's res
|
||||||
| [Scaleway](https://external-secrets.io/latest/provider/scaleway) | alpha | [@azert9](https://github.com/azert9/) |
|
| [Scaleway](https://external-secrets.io/latest/provider/scaleway) | alpha | [@azert9](https://github.com/azert9/) |
|
||||||
| [Conjur](https://external-secrets.io/latest/provider/conjur) | stable | [@davidh-cyberark](https://github.com/davidh-cyberark/) [@szh](https://github.com/szh) |
|
| [Conjur](https://external-secrets.io/latest/provider/conjur) | stable | [@davidh-cyberark](https://github.com/davidh-cyberark/) [@szh](https://github.com/szh) |
|
||||||
| [Delinea](https://external-secrets.io/latest/provider/delinea) | alpha | [@michaelsauter](https://github.com/michaelsauter/) |
|
| [Delinea](https://external-secrets.io/latest/provider/delinea) | alpha | [@michaelsauter](https://github.com/michaelsauter/) |
|
||||||
|
| [Beyondtrust](https://external-secrets.io/latest/provider/beyondtrust) | alpha | [@btfhernandez](https://github.com/btfhernandez/) |
|
||||||
| [SecretServer](https://external-secrets.io/latest/provider/secretserver) | alpha | [@billhamilton](https://github.com/pacificcode/) |
|
| [SecretServer](https://external-secrets.io/latest/provider/secretserver) | alpha | [@billhamilton](https://github.com/pacificcode/) |
|
||||||
| [Pulumi ESC](https://external-secrets.io/latest/provider/pulumi) | alpha | [@dirien](https://github.com/dirien) |
|
| [Pulumi ESC](https://external-secrets.io/latest/provider/pulumi) | alpha | [@dirien](https://github.com/dirien) |
|
||||||
| [Passbolt](https://external-secrets.io/latest/provider/passbolt) | alpha | |
|
| [Passbolt](https://external-secrets.io/latest/provider/passbolt) | alpha | |
|
||||||
|
@ -86,6 +87,7 @@ The following table show the support for features across different providers.
|
||||||
| Scaleway | x | x | | | x | x | x |
|
| Scaleway | x | x | | | x | x | x |
|
||||||
| Conjur | x | x | | | x | | |
|
| Conjur | x | x | | | x | | |
|
||||||
| Delinea | x | | | | x | | |
|
| Delinea | x | | | | x | | |
|
||||||
|
| Beyondtrust | x | | | | x | | |
|
||||||
| SecretServer | x | | | | x | | |
|
| SecretServer | x | | | | x | | |
|
||||||
| Pulumi ESC | x | | | | x | | |
|
| Pulumi ESC | x | | | | x | | |
|
||||||
| Passbolt | x | | | | x | | |
|
| Passbolt | x | | | | x | | |
|
||||||
|
|
124
docs/provider/beyondtrust.md
Normal file
124
docs/provider/beyondtrust.md
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
## BeyondTrust Password Safe
|
||||||
|
|
||||||
|
External Secrets Operator integrates with [BeyondTrust Password Safe](https://www.beyondtrust.com/docs/beyondinsight-password-safe/).
|
||||||
|
|
||||||
|
Warning: The External Secrets Operator secure usage involves taking several measures. Please see [Security Best Practices](https://external-secrets.io/latest/guides/security-best-practices/) for more information.
|
||||||
|
|
||||||
|
Warning: If the BT provider secret is deleted it will still exist in the Kubernetes secrets.
|
||||||
|
|
||||||
|
### Prerequisites
|
||||||
|
The BT provider supports retrieval of a secret from BeyondInsight/Password Safe versions 23.1 or greater.
|
||||||
|
|
||||||
|
For this provider to retrieve a secret the Password Safe/Secrets Safe instance must be preconfigured with the secret in question and authorized to read it.
|
||||||
|
|
||||||
|
### Authentication
|
||||||
|
|
||||||
|
BeyondTrust [OAuth Authentication](https://www.beyondtrust.com/docs/beyondinsight-password-safe/ps/admin/configure-api-registration.htm).
|
||||||
|
|
||||||
|
1. Create an API access registration in BeyondInsight
|
||||||
|
2. Create or use an existing Secrets Safe Group
|
||||||
|
3. Create or use an existing Application User
|
||||||
|
4. Add API registration to the Application user
|
||||||
|
5. Add the user to the group
|
||||||
|
6. Add the Secrets Safe Feature to the group
|
||||||
|
|
||||||
|
> NOTE: The ClentID and ClientSecret must be stored in a Kubernetes secret in order for the SecretStore to read the configuration.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
kubectl create secret generic bt-secret --from-literal ClientSecret="<your secret>"
|
||||||
|
kubectl create secret generic bt-id --from-literal ClientId="<your ID>"
|
||||||
|
```
|
||||||
|
### Client Certificate
|
||||||
|
Download the pfx certificate from Secrets Safe extract the certificate and create two Kubernetes secret.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
openssl pkcs12 -in client_certificate.pfx -nocerts -out ps_key.pem -nodes
|
||||||
|
openssl pkcs12 -in client_certificate.pfx -clcerts -nokeys -out ps_cert.pem
|
||||||
|
|
||||||
|
# Copy the text from the ps_key.pem to a file.
|
||||||
|
-----BEGIN PRIVATE KEY-----
|
||||||
|
...
|
||||||
|
-----END PRIVATE KEY-----
|
||||||
|
|
||||||
|
# Copy the text from the ps_cert.pem to a file.
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
...
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
|
||||||
|
kubectl create secret generic bt-certificate --from-file=ClientCertificate=./ps_cert.pem
|
||||||
|
kubectl create secret generic bt-certificatekey --from-file=ClientCertificateKey=./ps_key.pem
|
||||||
|
```
|
||||||
|
|
||||||
|
### Creating a SecretStore
|
||||||
|
|
||||||
|
You can follow the below example to create a `SecretStore` resource.
|
||||||
|
You can also use a `ClusterSecretStore` allowing you to reference secrets from all namespaces. [ClusterSecretStore](https://external-secrets.io/latest/api/clustersecretstore/)
|
||||||
|
|
||||||
|
```sh
|
||||||
|
kubectl apply -f secret-store.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: external-secrets.io/v1beta1
|
||||||
|
kind: SecretStore
|
||||||
|
metadata:
|
||||||
|
name: secretstore-beyondtrust
|
||||||
|
spec:
|
||||||
|
provider:
|
||||||
|
beyondtrust:
|
||||||
|
apiurl: https://example.com:443/BeyondTrust/api/public/v3/
|
||||||
|
certificate:
|
||||||
|
secretRef:
|
||||||
|
name: bt-certificate
|
||||||
|
key: ClientCertificate
|
||||||
|
certificatekey:
|
||||||
|
secretRef:
|
||||||
|
name: bt-certificatekey
|
||||||
|
key: ClientCertificateKey
|
||||||
|
clientsecret:
|
||||||
|
secretRef:
|
||||||
|
name: bt-secret
|
||||||
|
key: ClientSecret
|
||||||
|
clientid:
|
||||||
|
secretRef:
|
||||||
|
name: bt-id
|
||||||
|
key: ClientId
|
||||||
|
retrievaltype: MANAGED_ACCOUNT
|
||||||
|
verifyca: true
|
||||||
|
clienttimeoutseconds: 45
|
||||||
|
```
|
||||||
|
|
||||||
|
### Creating a ExternalSecret
|
||||||
|
|
||||||
|
You can follow the below example to create a `ExternalSecret` resource. Secrets can be referenced by path.
|
||||||
|
You can also use a `ClusterExternalSecret` allowing you to reference secrets from all namespaces.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
kubectl apply -f external-secret.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: external-secrets.io/v1beta1
|
||||||
|
kind: ExternalSecret
|
||||||
|
metadata:
|
||||||
|
name: beyondtrust-external-secret
|
||||||
|
spec:
|
||||||
|
refreshInterval: 300s
|
||||||
|
secretStoreRef:
|
||||||
|
kind: SecretStore
|
||||||
|
name: secretstore-beyondtrust
|
||||||
|
target:
|
||||||
|
name: my-beyondtrust-secret # name of secret to create in k8s secrets (etcd)
|
||||||
|
creationPolicy: Owner
|
||||||
|
data:
|
||||||
|
- secretKey: secretKey
|
||||||
|
remoteRef:
|
||||||
|
key: system01/managed_account01
|
||||||
|
```
|
||||||
|
|
||||||
|
### Get the K8s secret
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# WARNING: this command will reveal the stored secret in plain text
|
||||||
|
kubectl get secret my-beyondtrust-secret -o jsonpath="{.data.secretKey}" | base64 --decode && echo
|
||||||
|
```
|
16
docs/snippets/beyondtrust-external-secret.yaml
Normal file
16
docs/snippets/beyondtrust-external-secret.yaml
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
apiVersion: external-secrets.io/v1beta1
|
||||||
|
kind: ExternalSecret
|
||||||
|
metadata:
|
||||||
|
name: beyondtrust-external-secret
|
||||||
|
spec:
|
||||||
|
refreshInterval: 300s
|
||||||
|
secretStoreRef:
|
||||||
|
kind: SecretStore
|
||||||
|
name: secretstore-beyondtrust
|
||||||
|
target:
|
||||||
|
name: my-beyondtrust-secret # name of secret to create in k8s secrets (etcd)
|
||||||
|
creationPolicy: Owner
|
||||||
|
data:
|
||||||
|
- secretKey: secretKey
|
||||||
|
remoteRef:
|
||||||
|
key: system01/managed_account01
|
29
docs/snippets/beyondtrust-secret-store.yaml
Normal file
29
docs/snippets/beyondtrust-secret-store.yaml
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
apiVersion: external-secrets.io/v1beta1
|
||||||
|
kind: SecretStore
|
||||||
|
metadata:
|
||||||
|
name: secretstore-beyondtrust
|
||||||
|
spec:
|
||||||
|
provider:
|
||||||
|
beyondtrust:
|
||||||
|
auth:
|
||||||
|
certificate:
|
||||||
|
secretRef:
|
||||||
|
name: bt-certificate
|
||||||
|
key: ClientCertificate
|
||||||
|
certificateKey:
|
||||||
|
secretRef:
|
||||||
|
name: bt-certificatekey
|
||||||
|
key: ClientCertificateKey
|
||||||
|
clientSecret:
|
||||||
|
secretRef:
|
||||||
|
name: bt-secret
|
||||||
|
key: ClientSecret
|
||||||
|
clientId:
|
||||||
|
secretRef:
|
||||||
|
name: bt-id
|
||||||
|
key: ClientId
|
||||||
|
server:
|
||||||
|
retrievalType: MANAGED_ACCOUNT
|
||||||
|
verifyCA: true
|
||||||
|
clientTimeOutSeconds: 45
|
||||||
|
apiurl: https://example.ps-dev.beyondtrustcloud.com:443/BeyondTrust/api/public/v3/
|
2
go.mod
2
go.mod
|
@ -65,6 +65,7 @@ require (
|
||||||
dario.cat/mergo v1.0.0
|
dario.cat/mergo v1.0.0
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.13.0
|
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.13.0
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0
|
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0
|
||||||
|
github.com/BeyondTrust/go-client-library-passwordsafe v0.6.0
|
||||||
github.com/DelineaXPM/dsv-sdk-go/v2 v2.1.2
|
github.com/DelineaXPM/dsv-sdk-go/v2 v2.1.2
|
||||||
github.com/DelineaXPM/tss-sdk-go/v2 v2.0.1
|
github.com/DelineaXPM/tss-sdk-go/v2 v2.0.1
|
||||||
github.com/Onboardbase/go-cryptojs-aes-decrypt v0.0.0-20230430095000-27c0d3a9016d
|
github.com/Onboardbase/go-cryptojs-aes-decrypt v0.0.0-20230430095000-27c0d3a9016d
|
||||||
|
@ -76,6 +77,7 @@ require (
|
||||||
github.com/alibabacloud-go/tea-utils/v2 v2.0.6
|
github.com/alibabacloud-go/tea-utils/v2 v2.0.6
|
||||||
github.com/aliyun/credentials-go v1.3.6
|
github.com/aliyun/credentials-go v1.3.6
|
||||||
github.com/avast/retry-go/v4 v4.6.0
|
github.com/avast/retry-go/v4 v4.6.0
|
||||||
|
github.com/cenkalti/backoff/v4 v4.3.0
|
||||||
github.com/cyberark/conjur-api-go v0.12.4
|
github.com/cyberark/conjur-api-go v0.12.4
|
||||||
github.com/fortanix/sdkms-client-go v0.4.0
|
github.com/fortanix/sdkms-client-go v0.4.0
|
||||||
github.com/go-openapi/strfmt v0.23.0
|
github.com/go-openapi/strfmt v0.23.0
|
||||||
|
|
4
go.sum
4
go.sum
|
@ -95,6 +95,8 @@ github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBp
|
||||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.1.1/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI=
|
github.com/AzureAD/microsoft-authentication-library-for-go v1.1.1/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI=
|
||||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 h1:XHOnouVk1mxXfQidrMEnLlPk9UMeRtyBTnEFtxkV0kU=
|
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 h1:XHOnouVk1mxXfQidrMEnLlPk9UMeRtyBTnEFtxkV0kU=
|
||||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI=
|
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI=
|
||||||
|
github.com/BeyondTrust/go-client-library-passwordsafe v0.6.0 h1:3zdjZl8h3/9DzTnpWqAzhiUqMwIzpU+EL0grJ7BODV8=
|
||||||
|
github.com/BeyondTrust/go-client-library-passwordsafe v0.6.0/go.mod h1:TnbBwWYg9rtfDxQGF7pmD0gCPcbWgCUQIqum3dFMRTk=
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||||
github.com/DelineaXPM/dsv-sdk-go/v2 v2.1.2 h1:cmX2QC9s5kPqmghWLLZP8YRFO1ZD/C59BpNH2ujP99w=
|
github.com/DelineaXPM/dsv-sdk-go/v2 v2.1.2 h1:cmX2QC9s5kPqmghWLLZP8YRFO1ZD/C59BpNH2ujP99w=
|
||||||
|
@ -201,6 +203,8 @@ github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7N
|
||||||
github.com/c2h5oh/datasize v0.0.0-20200112174442-28bbd4740fee/go.mod h1:S/7n9copUssQ56c7aAgHqftWO4LTf4xY6CGWt8Bc+3M=
|
github.com/c2h5oh/datasize v0.0.0-20200112174442-28bbd4740fee/go.mod h1:S/7n9copUssQ56c7aAgHqftWO4LTf4xY6CGWt8Bc+3M=
|
||||||
github.com/cenkalti/backoff/v3 v3.2.2 h1:cfUAAO3yvKMYKPrvhDuHSwQnhZNk/RMHKdZqKTxfm6M=
|
github.com/cenkalti/backoff/v3 v3.2.2 h1:cfUAAO3yvKMYKPrvhDuHSwQnhZNk/RMHKdZqKTxfm6M=
|
||||||
github.com/cenkalti/backoff/v3 v3.2.2/go.mod h1:cIeZDE3IrqwwJl6VUwCN6trj1oXrTS4rc0ij+ULvLYs=
|
github.com/cenkalti/backoff/v3 v3.2.2/go.mod h1:cIeZDE3IrqwwJl6VUwCN6trj1oXrTS4rc0ij+ULvLYs=
|
||||||
|
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
|
||||||
|
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
||||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
|
|
338
pkg/provider/beyondtrust/provider.go
Normal file
338
pkg/provider/beyondtrust/provider.go
Normal file
|
@ -0,0 +1,338 @@
|
||||||
|
/*
|
||||||
|
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 implieclient.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package beyondtrust
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"net/url"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
auth "github.com/BeyondTrust/go-client-library-passwordsafe/api/authentication"
|
||||||
|
"github.com/BeyondTrust/go-client-library-passwordsafe/api/logging"
|
||||||
|
managed_account "github.com/BeyondTrust/go-client-library-passwordsafe/api/managed_account"
|
||||||
|
"github.com/BeyondTrust/go-client-library-passwordsafe/api/secrets"
|
||||||
|
"github.com/BeyondTrust/go-client-library-passwordsafe/api/utils"
|
||||||
|
"github.com/cenkalti/backoff/v4"
|
||||||
|
v1 "k8s.io/api/core/v1"
|
||||||
|
ctrl "sigs.k8s.io/controller-runtime"
|
||||||
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
|
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
|
||||||
|
|
||||||
|
esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
|
||||||
|
esoClient "github.com/external-secrets/external-secrets/pkg/utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
errNilStore = "nil store found"
|
||||||
|
errMissingStoreSpec = "store is missing spec"
|
||||||
|
errMissingProvider = "storeSpec is missing provider"
|
||||||
|
errInvalidProvider = "invalid provider spec. Missing field in store %s"
|
||||||
|
errInvalidHostURL = "invalid host URL"
|
||||||
|
errNoSuchKeyFmt = "no such key in secret: %q"
|
||||||
|
errInvalidRetrievalPath = "invalid retrieval path. Provide one path, separator and name"
|
||||||
|
errNotImplemented = "not implemented"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
errSecretRefAndValueConflict = errors.New("cannot specify both secret reference and value")
|
||||||
|
errMissingSecretName = errors.New("must specify a secret name")
|
||||||
|
errMissingSecretKey = errors.New("must specify a secret key")
|
||||||
|
ESOLogger = ctrl.Log.WithName("provider").WithName("beyondtrust")
|
||||||
|
maxFileSecretSizeBytes = 5000000
|
||||||
|
)
|
||||||
|
|
||||||
|
// Provider is a Password Safe secrets provider implementing NewClient and ValidateStore for the esv1beta1.Provider interface.
|
||||||
|
type Provider struct {
|
||||||
|
apiURL string
|
||||||
|
retrievaltype string
|
||||||
|
authenticate auth.AuthenticationObj
|
||||||
|
log logging.LogrLogger
|
||||||
|
separator string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Capabilities implements v1beta1.Provider.
|
||||||
|
func (*Provider) Capabilities() esv1beta1.SecretStoreCapabilities {
|
||||||
|
return esv1beta1.SecretStoreReadOnly
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close implements v1beta1.SecretsClient.
|
||||||
|
func (*Provider) Close(_ context.Context) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteSecret implements v1beta1.SecretsClient.
|
||||||
|
func (*Provider) DeleteSecret(_ context.Context, _ esv1beta1.PushSecretRemoteRef) error {
|
||||||
|
return fmt.Errorf(errNotImplemented)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetSecretMap implements v1beta1.SecretsClient.
|
||||||
|
func (*Provider) GetSecretMap(_ context.Context, _ esv1beta1.ExternalSecretDataRemoteRef) (map[string][]byte, error) {
|
||||||
|
return make(map[string][]byte), fmt.Errorf(errNotImplemented)
|
||||||
|
}
|
||||||
|
|
||||||
|
// PushSecret implements v1beta1.SecretsClient.
|
||||||
|
func (*Provider) PushSecret(_ context.Context, _ *v1.Secret, _ esv1beta1.PushSecretData) error {
|
||||||
|
return fmt.Errorf(errNotImplemented)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate implements v1beta1.SecretsClient.
|
||||||
|
func (p *Provider) Validate() (esv1beta1.ValidationResult, error) {
|
||||||
|
timeout := 15 * time.Second
|
||||||
|
clientURL := p.apiURL
|
||||||
|
|
||||||
|
if err := esoClient.NetworkValidate(clientURL, timeout); err != nil {
|
||||||
|
ESOLogger.Error(err, "Network Validate", "clientURL:", clientURL)
|
||||||
|
return esv1beta1.ValidationResultError, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return esv1beta1.ValidationResultReady, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*Provider) SecretExists(_ context.Context, _ esv1beta1.PushSecretRemoteRef) (bool, error) {
|
||||||
|
return false, fmt.Errorf(errNotImplemented)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewClient this is where we initialize the SecretClient and return it for the controller to use.
|
||||||
|
func (p *Provider) NewClient(ctx context.Context, store esv1beta1.GenericStore, kube client.Client, namespace string) (esv1beta1.SecretsClient, error) {
|
||||||
|
config := store.GetSpec().Provider.Beyondtrust
|
||||||
|
logger := logging.NewLogrLogger(&ESOLogger)
|
||||||
|
apiURL := config.Server.APIURL
|
||||||
|
certificate := ""
|
||||||
|
certificateKey := ""
|
||||||
|
clientTimeOutInSeconds := 45
|
||||||
|
retryMaxElapsedTimeMinutes := 15
|
||||||
|
separator := "/"
|
||||||
|
|
||||||
|
if config.Server.Separator != "" {
|
||||||
|
separator = config.Server.Separator
|
||||||
|
}
|
||||||
|
|
||||||
|
if config.Server.ClientTimeOutSeconds != 0 {
|
||||||
|
clientTimeOutInSeconds = config.Server.ClientTimeOutSeconds
|
||||||
|
}
|
||||||
|
|
||||||
|
backoffDefinition := backoff.NewExponentialBackOff()
|
||||||
|
backoffDefinition.InitialInterval = 1 * time.Second
|
||||||
|
backoffDefinition.MaxElapsedTime = time.Duration(retryMaxElapsedTimeMinutes) * time.Second
|
||||||
|
backoffDefinition.RandomizationFactor = 0.5
|
||||||
|
|
||||||
|
clientID, err := loadConfigSecret(ctx, config.Auth.ClientID, kube, namespace)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error loading clientID: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
clientSecret, err := loadConfigSecret(ctx, config.Auth.ClientSecret, kube, namespace)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error loading clientSecret: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if config.Auth.Certificate != nil && config.Auth.CertificateKey != nil {
|
||||||
|
loadedCertificate, err := loadConfigSecret(ctx, config.Auth.Certificate, kube, namespace)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error loading Certificate: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
certificate = loadedCertificate
|
||||||
|
|
||||||
|
loadedCertificateKey, err := loadConfigSecret(ctx, config.Auth.CertificateKey, kube, namespace)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error loading Certificate Key: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
certificateKey = loadedCertificateKey
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create an instance of ValidationParams
|
||||||
|
params := utils.ValidationParams{
|
||||||
|
ClientID: clientID,
|
||||||
|
ClientSecret: clientSecret,
|
||||||
|
ApiUrl: &apiURL,
|
||||||
|
ClientTimeOutInSeconds: clientTimeOutInSeconds,
|
||||||
|
Separator: &separator,
|
||||||
|
VerifyCa: config.Server.VerifyCA,
|
||||||
|
Logger: logger,
|
||||||
|
Certificate: certificate,
|
||||||
|
CertificateKey: certificateKey,
|
||||||
|
RetryMaxElapsedTimeMinutes: &retryMaxElapsedTimeMinutes,
|
||||||
|
MaxFileSecretSizeBytes: &maxFileSecretSizeBytes,
|
||||||
|
}
|
||||||
|
|
||||||
|
errorsInInputs := utils.ValidateInputs(params)
|
||||||
|
|
||||||
|
if errorsInInputs != nil {
|
||||||
|
return nil, fmt.Errorf("error in Inputs: %w", errorsInInputs)
|
||||||
|
}
|
||||||
|
|
||||||
|
// creating a http client
|
||||||
|
httpClientObj, err := utils.GetHttpClient(clientTimeOutInSeconds, config.Server.VerifyCA, certificate, certificateKey, logger)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error creating http client: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// instantiating authenticate obj, injecting httpClient object
|
||||||
|
authenticate, _ := auth.Authenticate(*httpClientObj, backoffDefinition, apiURL, clientID, clientSecret, logger, retryMaxElapsedTimeMinutes)
|
||||||
|
|
||||||
|
return &Provider{
|
||||||
|
apiURL: config.Server.APIURL,
|
||||||
|
retrievaltype: config.Server.RetrievalType,
|
||||||
|
authenticate: *authenticate,
|
||||||
|
log: *logger,
|
||||||
|
separator: separator,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadConfigSecret(ctx context.Context, ref *esv1beta1.BeyondTrustProviderSecretRef, kube client.Client, defaultNamespace string) (string, error) {
|
||||||
|
if ref.SecretRef == nil {
|
||||||
|
return ref.Value, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := validateSecretRef(ref); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace := defaultNamespace
|
||||||
|
if ref.SecretRef.Namespace != nil {
|
||||||
|
namespace = *ref.SecretRef.Namespace
|
||||||
|
}
|
||||||
|
|
||||||
|
ESOLogger.Info("using k8s secret", "name:", ref.SecretRef.Name, "namespace:", namespace)
|
||||||
|
objKey := client.ObjectKey{Namespace: namespace, Name: ref.SecretRef.Name}
|
||||||
|
secret := v1.Secret{}
|
||||||
|
err := kube.Get(ctx, objKey, &secret)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
value, ok := secret.Data[ref.SecretRef.Key]
|
||||||
|
if !ok {
|
||||||
|
return "", fmt.Errorf(errNoSuchKeyFmt, ref.SecretRef.Key)
|
||||||
|
}
|
||||||
|
|
||||||
|
return string(value), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func validateSecretRef(ref *esv1beta1.BeyondTrustProviderSecretRef) error {
|
||||||
|
if ref.SecretRef != nil {
|
||||||
|
if ref.Value != "" {
|
||||||
|
return errSecretRefAndValueConflict
|
||||||
|
}
|
||||||
|
if ref.SecretRef.Name == "" {
|
||||||
|
return errMissingSecretName
|
||||||
|
}
|
||||||
|
if ref.SecretRef.Key == "" {
|
||||||
|
return errMissingSecretKey
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Provider) GetAllSecrets(_ context.Context, _ esv1beta1.ExternalSecretFind) (map[string][]byte, error) {
|
||||||
|
return nil, fmt.Errorf("GetAllSecrets not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetSecret reads the secret from the Password Safe server and returns it. The controller uses the value here to
|
||||||
|
// create the Kubernetes secret.
|
||||||
|
func (p *Provider) GetSecret(_ context.Context, ref esv1beta1.ExternalSecretDataRemoteRef) ([]byte, error) {
|
||||||
|
managedAccountType := !strings.EqualFold(p.retrievaltype, "SECRET")
|
||||||
|
|
||||||
|
retrievalPaths := utils.ValidatePaths([]string{ref.Key}, managedAccountType, p.separator, &p.log)
|
||||||
|
|
||||||
|
if len(retrievalPaths) != 1 {
|
||||||
|
return nil, fmt.Errorf(errInvalidRetrievalPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
retrievalPath := retrievalPaths[0]
|
||||||
|
|
||||||
|
_, err := p.authenticate.GetPasswordSafeAuthentication()
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error getting authentication: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
managedFetch := func() (string, error) {
|
||||||
|
ESOLogger.Info("retrieve managed account value", "retrievalPath:", retrievalPath)
|
||||||
|
manageAccountObj, _ := managed_account.NewManagedAccountObj(p.authenticate, &p.log)
|
||||||
|
return manageAccountObj.GetSecret(retrievalPath, p.separator)
|
||||||
|
}
|
||||||
|
unmanagedFetch := func() (string, error) {
|
||||||
|
ESOLogger.Info("retrieve secrets safe value", "retrievalPath:", retrievalPath)
|
||||||
|
secretObj, _ := secrets.NewSecretObj(p.authenticate, &p.log, maxFileSecretSizeBytes)
|
||||||
|
return secretObj.GetSecret(retrievalPath, p.separator)
|
||||||
|
}
|
||||||
|
fetch := unmanagedFetch
|
||||||
|
if managedAccountType {
|
||||||
|
fetch = managedFetch
|
||||||
|
}
|
||||||
|
returnSecret, err := fetch()
|
||||||
|
if err != nil {
|
||||||
|
if serr := p.authenticate.SignOut(); serr != nil {
|
||||||
|
return nil, errors.Join(err, serr)
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("error getting secret/managed account: %w", err)
|
||||||
|
}
|
||||||
|
return []byte(returnSecret), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ValidateStore validates the store configuration to prevent unexpected errors.
|
||||||
|
func (p *Provider) ValidateStore(store esv1beta1.GenericStore) (admission.Warnings, error) {
|
||||||
|
if store == nil {
|
||||||
|
return nil, fmt.Errorf(errNilStore)
|
||||||
|
}
|
||||||
|
|
||||||
|
spec := store.GetSpec()
|
||||||
|
|
||||||
|
if spec == nil {
|
||||||
|
return nil, fmt.Errorf(errMissingStoreSpec)
|
||||||
|
}
|
||||||
|
|
||||||
|
if spec.Provider == nil {
|
||||||
|
return nil, fmt.Errorf(errMissingProvider)
|
||||||
|
}
|
||||||
|
|
||||||
|
provider := spec.Provider.Beyondtrust
|
||||||
|
if provider == nil {
|
||||||
|
return nil, fmt.Errorf(errInvalidProvider, store.GetObjectMeta().String())
|
||||||
|
}
|
||||||
|
|
||||||
|
apiURL, err := url.Parse(provider.Server.APIURL)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf(errInvalidHostURL)
|
||||||
|
}
|
||||||
|
|
||||||
|
if provider.Auth.ClientID.SecretRef != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if provider.Auth.ClientSecret.SecretRef != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if apiURL.Host == "" {
|
||||||
|
return nil, fmt.Errorf(errInvalidHostURL)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// registers the provider object to process on each reconciliation loop.
|
||||||
|
func init() {
|
||||||
|
esv1beta1.Register(&Provider{}, &esv1beta1.SecretStoreProvider{
|
||||||
|
Beyondtrust: &esv1beta1.BeyondtrustProvider{},
|
||||||
|
})
|
||||||
|
}
|
285
pkg/provider/beyondtrust/provider_test.go
Normal file
285
pkg/provider/beyondtrust/provider_test.go
Normal file
|
@ -0,0 +1,285 @@
|
||||||
|
/*
|
||||||
|
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 implieclient.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package beyondtrust
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"k8s.io/client-go/tools/clientcmd"
|
||||||
|
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
|
||||||
|
kubeclient "sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
|
|
||||||
|
esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
errTestCase = "Test case Failed"
|
||||||
|
fakeAPIURL = "https://example.com:443/BeyondTrust/api/public/v3/"
|
||||||
|
clientID = "12345678-25fg-4b05-9ced-35e7dd5093ae"
|
||||||
|
clientSecret = "12345678-25fg-4b05-9ced-35e7dd5093ae"
|
||||||
|
)
|
||||||
|
|
||||||
|
func createMockPasswordSafeClient(t *testing.T) kubeclient.Client {
|
||||||
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
switch r.URL.Path {
|
||||||
|
case "/Auth/SignAppin":
|
||||||
|
_, err := w.Write([]byte(`{"UserId":1, "EmailAddress":"fake@beyondtrust.com"}`))
|
||||||
|
if err != nil {
|
||||||
|
t.Error(errTestCase)
|
||||||
|
}
|
||||||
|
|
||||||
|
case "/Auth/Signout":
|
||||||
|
_, err := w.Write([]byte(``))
|
||||||
|
if err != nil {
|
||||||
|
t.Error(errTestCase)
|
||||||
|
}
|
||||||
|
|
||||||
|
case "/secrets-safe/secrets":
|
||||||
|
_, err := w.Write([]byte(`[{"SecretType": "FILE", "Password": "credential_in_sub_3_password","Id": "12345678-07d6-4955-175a-08db047219ce","Title": "credential_in_sub_3"}]`))
|
||||||
|
if err != nil {
|
||||||
|
t.Error(errTestCase)
|
||||||
|
}
|
||||||
|
|
||||||
|
case "/secrets-safe/secrets/12345678-07d6-4955-175a-08db047219ce/file/download":
|
||||||
|
_, err := w.Write([]byte(`fake_password`))
|
||||||
|
if err != nil {
|
||||||
|
t.Error(errTestCase)
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
http.NotFound(w, r)
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
t.Cleanup(server.Close)
|
||||||
|
|
||||||
|
clientConfig := clientcmd.NewDefaultClientConfig(clientcmdapi.Config{
|
||||||
|
Clusters: map[string]*clientcmdapi.Cluster{
|
||||||
|
"test": {
|
||||||
|
Server: server.URL,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
AuthInfos: map[string]*clientcmdapi.AuthInfo{
|
||||||
|
"test": {
|
||||||
|
Token: "token",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Contexts: map[string]*clientcmdapi.Context{
|
||||||
|
"test": {
|
||||||
|
Cluster: "test",
|
||||||
|
AuthInfo: "test",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
CurrentContext: "test",
|
||||||
|
}, &clientcmd.ConfigOverrides{})
|
||||||
|
|
||||||
|
restConfig, err := clientConfig.ClientConfig()
|
||||||
|
assert.Nil(t, err)
|
||||||
|
c, err := kubeclient.New(restConfig, kubeclient.Options{})
|
||||||
|
assert.Nil(t, err)
|
||||||
|
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNewClient(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
store esv1beta1.SecretStore
|
||||||
|
kube kubeclient.Client
|
||||||
|
provider esv1beta1.Provider
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
nameSpace string
|
||||||
|
args args
|
||||||
|
validateErrorNil bool
|
||||||
|
validateErrorText bool
|
||||||
|
expectedErrorText string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "Client ok",
|
||||||
|
nameSpace: "test",
|
||||||
|
args: args{
|
||||||
|
store: esv1beta1.SecretStore{
|
||||||
|
Spec: esv1beta1.SecretStoreSpec{
|
||||||
|
Provider: &esv1beta1.SecretStoreProvider{
|
||||||
|
Beyondtrust: &esv1beta1.BeyondtrustProvider{
|
||||||
|
Server: &esv1beta1.BeyondtrustServer{
|
||||||
|
APIURL: fakeAPIURL,
|
||||||
|
RetrievalType: "SECRET",
|
||||||
|
},
|
||||||
|
|
||||||
|
Auth: &esv1beta1.BeyondtrustAuth{
|
||||||
|
ClientID: &esv1beta1.BeyondTrustProviderSecretRef{
|
||||||
|
Value: clientID,
|
||||||
|
},
|
||||||
|
ClientSecret: &esv1beta1.BeyondTrustProviderSecretRef{
|
||||||
|
Value: clientSecret,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
kube: createMockPasswordSafeClient(t),
|
||||||
|
provider: &Provider{},
|
||||||
|
},
|
||||||
|
validateErrorNil: true,
|
||||||
|
validateErrorText: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Bad Client Id",
|
||||||
|
nameSpace: "test",
|
||||||
|
args: args{
|
||||||
|
store: esv1beta1.SecretStore{
|
||||||
|
Spec: esv1beta1.SecretStoreSpec{
|
||||||
|
Provider: &esv1beta1.SecretStoreProvider{
|
||||||
|
Beyondtrust: &esv1beta1.BeyondtrustProvider{
|
||||||
|
Server: &esv1beta1.BeyondtrustServer{
|
||||||
|
APIURL: fakeAPIURL,
|
||||||
|
RetrievalType: "SECRET",
|
||||||
|
},
|
||||||
|
|
||||||
|
Auth: &esv1beta1.BeyondtrustAuth{
|
||||||
|
ClientID: &esv1beta1.BeyondTrustProviderSecretRef{
|
||||||
|
Value: "6138d050",
|
||||||
|
},
|
||||||
|
ClientSecret: &esv1beta1.BeyondTrustProviderSecretRef{
|
||||||
|
Value: clientSecret,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
kube: createMockPasswordSafeClient(t),
|
||||||
|
provider: &Provider{},
|
||||||
|
},
|
||||||
|
validateErrorNil: false,
|
||||||
|
validateErrorText: true,
|
||||||
|
expectedErrorText: "error in Inputs: Key: 'UserInputValidaton.ClientId' Error:Field validation for 'ClientId' failed on the 'min' tag",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Bad Client Secret",
|
||||||
|
nameSpace: "test",
|
||||||
|
args: args{
|
||||||
|
store: esv1beta1.SecretStore{
|
||||||
|
Spec: esv1beta1.SecretStoreSpec{
|
||||||
|
Provider: &esv1beta1.SecretStoreProvider{
|
||||||
|
Beyondtrust: &esv1beta1.BeyondtrustProvider{
|
||||||
|
Server: &esv1beta1.BeyondtrustServer{
|
||||||
|
APIURL: fakeAPIURL,
|
||||||
|
RetrievalType: "SECRET",
|
||||||
|
},
|
||||||
|
|
||||||
|
Auth: &esv1beta1.BeyondtrustAuth{
|
||||||
|
ClientSecret: &esv1beta1.BeyondTrustProviderSecretRef{
|
||||||
|
Value: "8i7U0Yulabon8mTc",
|
||||||
|
},
|
||||||
|
ClientID: &esv1beta1.BeyondTrustProviderSecretRef{
|
||||||
|
Value: clientID,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
kube: createMockPasswordSafeClient(t),
|
||||||
|
provider: &Provider{},
|
||||||
|
},
|
||||||
|
validateErrorNil: false,
|
||||||
|
validateErrorText: true,
|
||||||
|
expectedErrorText: "error in Inputs: Key: 'UserInputValidaton.ClientSecret' Error:Field validation for 'ClientSecret' failed on the 'min' tag",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Bad Separator",
|
||||||
|
nameSpace: "test",
|
||||||
|
args: args{
|
||||||
|
store: esv1beta1.SecretStore{
|
||||||
|
Spec: esv1beta1.SecretStoreSpec{
|
||||||
|
Provider: &esv1beta1.SecretStoreProvider{
|
||||||
|
Beyondtrust: &esv1beta1.BeyondtrustProvider{
|
||||||
|
Server: &esv1beta1.BeyondtrustServer{
|
||||||
|
APIURL: fakeAPIURL,
|
||||||
|
Separator: "//",
|
||||||
|
RetrievalType: "SECRET",
|
||||||
|
},
|
||||||
|
Auth: &esv1beta1.BeyondtrustAuth{
|
||||||
|
ClientID: &esv1beta1.BeyondTrustProviderSecretRef{
|
||||||
|
Value: clientID,
|
||||||
|
},
|
||||||
|
ClientSecret: &esv1beta1.BeyondTrustProviderSecretRef{
|
||||||
|
Value: clientSecret,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
kube: createMockPasswordSafeClient(t),
|
||||||
|
provider: &Provider{},
|
||||||
|
},
|
||||||
|
validateErrorNil: false,
|
||||||
|
validateErrorText: true,
|
||||||
|
expectedErrorText: "error in Inputs: Key: 'UserInputValidaton.Separator' Error:Field validation for 'Separator' failed on the 'max' tag",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Time Out",
|
||||||
|
nameSpace: "test",
|
||||||
|
args: args{
|
||||||
|
store: esv1beta1.SecretStore{
|
||||||
|
Spec: esv1beta1.SecretStoreSpec{
|
||||||
|
Provider: &esv1beta1.SecretStoreProvider{
|
||||||
|
Beyondtrust: &esv1beta1.BeyondtrustProvider{
|
||||||
|
Server: &esv1beta1.BeyondtrustServer{
|
||||||
|
APIURL: fakeAPIURL,
|
||||||
|
Separator: "/",
|
||||||
|
ClientTimeOutSeconds: 400,
|
||||||
|
RetrievalType: "SECRET",
|
||||||
|
},
|
||||||
|
Auth: &esv1beta1.BeyondtrustAuth{
|
||||||
|
ClientID: &esv1beta1.BeyondTrustProviderSecretRef{
|
||||||
|
Value: clientID,
|
||||||
|
},
|
||||||
|
ClientSecret: &esv1beta1.BeyondTrustProviderSecretRef{
|
||||||
|
Value: clientSecret,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
kube: createMockPasswordSafeClient(t),
|
||||||
|
provider: &Provider{},
|
||||||
|
},
|
||||||
|
validateErrorNil: false,
|
||||||
|
validateErrorText: true,
|
||||||
|
expectedErrorText: "error in Inputs: Key: 'UserInputValidaton.ClientTimeOutinSeconds' Error:Field validation for 'ClientTimeOutinSeconds' failed on the 'lte' tag",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
_, err := tt.args.provider.NewClient(context.Background(), &tt.args.store, tt.args.kube, tt.nameSpace)
|
||||||
|
if err != nil && tt.validateErrorNil {
|
||||||
|
t.Errorf("ProviderBeyondtrust.NewClient() error = %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil && tt.validateErrorText {
|
||||||
|
assert.Equal(t, err.Error(), tt.expectedErrorText)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -21,6 +21,7 @@ import (
|
||||||
_ "github.com/external-secrets/external-secrets/pkg/provider/alibaba"
|
_ "github.com/external-secrets/external-secrets/pkg/provider/alibaba"
|
||||||
_ "github.com/external-secrets/external-secrets/pkg/provider/aws"
|
_ "github.com/external-secrets/external-secrets/pkg/provider/aws"
|
||||||
_ "github.com/external-secrets/external-secrets/pkg/provider/azure/keyvault"
|
_ "github.com/external-secrets/external-secrets/pkg/provider/azure/keyvault"
|
||||||
|
_ "github.com/external-secrets/external-secrets/pkg/provider/beyondtrust"
|
||||||
_ "github.com/external-secrets/external-secrets/pkg/provider/bitwarden"
|
_ "github.com/external-secrets/external-secrets/pkg/provider/bitwarden"
|
||||||
_ "github.com/external-secrets/external-secrets/pkg/provider/chef"
|
_ "github.com/external-secrets/external-secrets/pkg/provider/chef"
|
||||||
_ "github.com/external-secrets/external-secrets/pkg/provider/conjur"
|
_ "github.com/external-secrets/external-secrets/pkg/provider/conjur"
|
||||||
|
|
Loading…
Reference in a new issue