Addresses comments and makes vault auth pointers

Signed-off-by: JoshVanL <vleeuwenjoshua@gmail.com>
This commit is contained in:
JoshVanL
2019-09-23 13:54:48 +01:00
parent 05b5f44ff6
commit f2f5fccb85
11 changed files with 161 additions and 106 deletions
@@ -1681,7 +1681,11 @@ Appears In:
<td><code>LabelSelector</code></td>
</tr>
</tbody></table>
<<<<<<< HEAD
<p>A label selector is a label query over a set of resources. The result of matchLabels and matchExpressions are ANDed. An empty label selector matches all objects. A null label selector matches no objects.</p>
=======
<p>Authenticate against Vault using a Kubernetes ServiceAccount token stored in a Secret.</p>
>>>>>>> Addresses comments and makes vault auth pointers
<aside class="notice">
Appears In:
@@ -1697,6 +1701,7 @@ Appears In:
</tr>
</thead>
<tbody><tr>
<<<<<<< HEAD
<td><code>matchExpressions</code><br /> *<a href="#labelselectorrequirement-v1">LabelSelectorRequirement</a> array*</td>
<td>matchExpressions is a list of label selector requirements. The requirements are ANDed.</td>
</tr>
@@ -1746,6 +1751,18 @@ Appears In:
<tr>
<td><code>values</code><br /> <em>string array</em></td>
<td>values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.</td>
=======
<td><code>mountPath</code><br /> <em>string</em></td>
<td>The kubernetes mount path to be used when authenticating (/v1/auth/%s/login). If unspecified, the default value &#34;kubernetes&#34; will be used.</td>
</tr>
<tr>
<td><code>role</code><br /> <em>string</em></td>
<td>A required field containing the Vault Role to assume. A Role binds a Kubernetes ServiceAccount with a set of Vault policies.</td>
</tr>
<tr>
<td><code>secretRef</code><br /> *<a href="#secretkeyselector-v1alpha1">SecretKeySelector</a>*</td>
<td>The required Secret field containing a Kubernetes ServiceAccount JWT used for authenticating with Vault. Use of &#39;ambient credentials&#39; is not supported.</td>
>>>>>>> Addresses comments and makes vault auth pointers
</tr>
</tbody></table>
<h2 id="localobjectreference-v1">LocalObjectReference v1</h2>
@@ -2538,6 +2555,7 @@ Appears In:
<td><code>VaultAppRole</code></td>
</tr>
</tbody></table>
<p>Authenticate against Vault using an AppRole that is stored in a Secret.</p>
<aside class="notice">
Appears In:
@@ -2601,7 +2619,11 @@ Appears In:
<td>This Secret contains a AppRole and Secret</td>
</tr>
<tr>
<<<<<<< HEAD
<td><code>kubernetes</code><br /> *<a href="#vaultkubernetesauth-v1alpha2">VaultKubernetesAuth</a>*</td>
=======
<td><code>kubernetes</code><br /> *<a href="#kubernetesauth-v1alpha1">KubernetesAuth</a>*</td>
>>>>>>> Addresses comments and makes vault auth pointers
<td>This contains a Role and Secret with a ServiceAccount token to authenticate with vault.</td>
</tr>
<tr>
+9
View File
@@ -31,3 +31,12 @@ const (
// Default duration before certificate expiration if Issuer.spec.renewBefore is not set
DefaultRenewBefore = time.Hour * 24 * 30
)
const (
// Default index key for the Secret reference for Token authentication
DefaultVaultTokenAuthSecretKey = "token"
// Default mount path location for Kubernetes ServiceAccount authentication
// (/v1/auth/kubernetes/login)
DefaultVaultKubernetesAuthMountPath = "kubernetes"
)
@@ -179,7 +179,7 @@ func TestSign(t *testing.T) {
CertManagerObjects: []runtime.Object{baseCR.DeepCopy(),
gen.IssuerFrom(baseIssuer, gen.SetIssuerVault(cmapi.VaultIssuer{
Auth: cmapi.VaultAuth{
TokenSecretRef: cmmeta.SecretKeySelector{
TokenSecretRef: &cmapi.SecretKeySelector{
Key: "secret-key",
LocalObjectReference: cmmeta.LocalObjectReference{
"non-existing-secret",
@@ -215,7 +215,7 @@ func TestSign(t *testing.T) {
CertManagerObjects: []runtime.Object{baseCR.DeepCopy(), gen.IssuerFrom(baseIssuer,
gen.SetIssuerVault(cmapi.VaultIssuer{
Auth: cmapi.VaultAuth{
AppRole: cmapi.VaultAppRole{
AppRole: &cmapi.VaultAppRole{
RoleId: "my-role-id",
SecretRef: cmmeta.SecretKeySelector{
Key: "secret-key",
@@ -254,7 +254,7 @@ func TestSign(t *testing.T) {
CertManagerObjects: []runtime.Object{baseCR.DeepCopy(), gen.IssuerFrom(baseIssuer,
gen.SetIssuerVault(cmapi.VaultIssuer{
Auth: cmapi.VaultAuth{
TokenSecretRef: cmmeta.SecretKeySelector{
TokenSecretRef: &cmapi.SecretKeySelector{
Key: "my-token-key",
LocalObjectReference: cmmeta.LocalObjectReference{
"token-secret",
@@ -292,7 +292,7 @@ func TestSign(t *testing.T) {
CertManagerObjects: []runtime.Object{baseCR.DeepCopy(), gen.IssuerFrom(baseIssuer,
gen.SetIssuerVault(cmapi.VaultIssuer{
Auth: cmapi.VaultAuth{
AppRole: cmapi.VaultAppRole{
AppRole: &cmapi.VaultAppRole{
RoleId: "my-role-id",
SecretRef: cmmeta.SecretKeySelector{
LocalObjectReference: cmmeta.LocalObjectReference{
@@ -333,7 +333,7 @@ func TestSign(t *testing.T) {
CertManagerObjects: []runtime.Object{baseCR.DeepCopy(), gen.IssuerFrom(baseIssuer,
gen.SetIssuerVault(cmapi.VaultIssuer{
Auth: cmapi.VaultAuth{
TokenSecretRef: cmmeta.SecretKeySelector{
TokenSecretRef: &cmapi.SecretKeySelector{
Key: "my-token-key",
LocalObjectReference: cmmeta.LocalObjectReference{
"token-secret",
@@ -372,7 +372,7 @@ func TestSign(t *testing.T) {
CertManagerObjects: []runtime.Object{baseCR.DeepCopy(), gen.IssuerFrom(baseIssuer,
gen.SetIssuerVault(cmapi.VaultIssuer{
Auth: cmapi.VaultAuth{
AppRole: cmapi.VaultAppRole{
AppRole: &cmapi.VaultAppRole{
RoleId: "my-role-id",
SecretRef: cmmeta.SecretKeySelector{
LocalObjectReference: cmmeta.LocalObjectReference{
@@ -158,6 +158,8 @@ type VaultIssuer struct {
// - With a secret containing a token. Cert-manager is using this token as-is.
// - With a secret containing a AppRole. This AppRole is used to authenticate to
// Vault and retrieve a token.
// - With a secret containing a Kubernetes ServiceAccount JWT. This JWT is used
// to authenticate with Vault and retrieve a token.
type VaultAuth struct {
// This Secret contains the Vault token key
// +optional
@@ -173,6 +175,7 @@ type VaultAuth struct {
Kubernetes *VaultKubernetesAuth `json:"kubernetes,omitempty"`
}
// Authenticate against Vault using an AppRole that is stored in a Secret.
type VaultAppRole struct {
// Where the authentication path is mounted in Vault.
Path string `json:"path"`
@@ -2095,15 +2095,9 @@ func Convert_certmanager_VaultAppRole_To_v1alpha1_VaultAppRole(in *certmanager.V
}
func autoConvert_v1alpha1_VaultAuth_To_certmanager_VaultAuth(in *v1alpha1.VaultAuth, out *certmanager.VaultAuth, s conversion.Scope) error {
if err := Convert_v1alpha1_SecretKeySelector_To_certmanager_SecretKeySelector(&in.TokenSecretRef, &out.TokenSecretRef, s); err != nil {
return err
}
if err := Convert_v1alpha1_VaultAppRole_To_certmanager_VaultAppRole(&in.AppRole, &out.AppRole, s); err != nil {
return err
}
if err := Convert_v1alpha1_KubernetesAuth_To_certmanager_KubernetesAuth(&in.Kubernetes, &out.Kubernetes, s); err != nil {
return err
}
out.TokenSecretRef = (*certmanager.SecretKeySelector)(unsafe.Pointer(in.TokenSecretRef))
out.AppRole = (*certmanager.VaultAppRole)(unsafe.Pointer(in.AppRole))
out.Kubernetes = (*certmanager.KubernetesAuth)(unsafe.Pointer(in.Kubernetes))
return nil
}
@@ -2113,15 +2107,9 @@ func Convert_v1alpha1_VaultAuth_To_certmanager_VaultAuth(in *v1alpha1.VaultAuth,
}
func autoConvert_certmanager_VaultAuth_To_v1alpha1_VaultAuth(in *certmanager.VaultAuth, out *v1alpha1.VaultAuth, s conversion.Scope) error {
if err := Convert_certmanager_SecretKeySelector_To_v1alpha1_SecretKeySelector(&in.TokenSecretRef, &out.TokenSecretRef, s); err != nil {
return err
}
if err := Convert_certmanager_VaultAppRole_To_v1alpha1_VaultAppRole(&in.AppRole, &out.AppRole, s); err != nil {
return err
}
if err := Convert_certmanager_KubernetesAuth_To_v1alpha1_KubernetesAuth(&in.Kubernetes, &out.Kubernetes, s); err != nil {
return err
}
out.TokenSecretRef = (*v1alpha1.SecretKeySelector)(unsafe.Pointer(in.TokenSecretRef))
out.AppRole = (*v1alpha1.VaultAppRole)(unsafe.Pointer(in.AppRole))
out.Kubernetes = (*v1alpha1.KubernetesAuth)(unsafe.Pointer(in.Kubernetes))
return nil
}
@@ -50,8 +50,8 @@ var (
PrivateKey: validSecretKeyRef,
}
validVaultIssuer = v1alpha2.VaultIssuer{
Auth: v1alpha2.VaultAuth{
TokenSecretRef: validSecretKeyRef,
Auth: v1alpha1.VaultAuth{
TokenSecretRef: &validSecretKeyRef,
},
Server: "something",
Path: "a/b/c",
+12 -15
View File
@@ -22,6 +22,7 @@ import (
"fmt"
"net/http"
"path"
"path/filepath"
"strings"
"time"
@@ -33,10 +34,6 @@ import (
"github.com/jetstack/cert-manager/pkg/util/pki"
)
const (
defaultKubernetesAuthMountPath = "kubernetes"
)
var _ Interface = &Vault{}
type VaultClientBuilder func(namespace string, secretsLister corelisters.SecretLister,
@@ -147,7 +144,7 @@ func (v *Vault) Sign(csrPEM []byte, duration time.Duration) (cert []byte, ca []b
func (v *Vault) setToken(client Client) error {
tokenRef := v.issuer.GetSpec().Vault.Auth.TokenSecretRef
if tokenRef.Name != "" {
if tokenRef != nil {
token, err := v.tokenRef(tokenRef.Name, v.namespace, tokenRef.Key)
if err != nil {
return err
@@ -158,8 +155,8 @@ func (v *Vault) setToken(client Client) error {
}
appRole := v.issuer.GetSpec().Vault.Auth.AppRole
if appRole.RoleId != "" {
token, err := v.requestTokenWithAppRoleRef(client, &appRole)
if appRole != nil {
token, err := v.requestTokenWithAppRoleRef(client, appRole)
if err != nil {
return err
}
@@ -169,8 +166,8 @@ func (v *Vault) setToken(client Client) error {
}
kubernetesAuth := v.issuer.GetSpec().Vault.Auth.Kubernetes
if kubernetesAuth.Role != "" {
token, err := v.requestTokenWithKubernetesAuth(client, &kubernetesAuth)
if kubernetesAuth != nil {
token, err := v.requestTokenWithKubernetesAuth(client, kubernetesAuth)
if err != nil {
return fmt.Errorf("error reading Kubernetes service account token from %s: %s", kubernetesAuth.SecretRef.Name, err.Error())
}
@@ -208,7 +205,7 @@ func (v *Vault) tokenRef(name, namespace, key string) (string, error) {
}
if key == "" {
key = "token"
key = v1alpha2.DefaultVaultTokenAuthSecretKey
}
keyBytes, ok := secret.Data[key]
@@ -293,7 +290,7 @@ func (v *Vault) requestTokenWithAppRoleRef(client Client, appRole *v1alpha2.Vaul
return token, nil
}
func (v *Vault) requestTokenWithKubernetesAuth(client Client, kubernetesAuth *v1alpha1.KubernetesAuth) (string, error) {
func (v *Vault) requestTokenWithKubernetesAuth(client Client, kubernetesAuth *v1alpha2.VaultKubernetesAuth) (string, error) {
secret, err := v.secretsLister.Secrets(v.namespace).Get(kubernetesAuth.SecretRef.Name)
if err != nil {
return "", err
@@ -301,12 +298,12 @@ func (v *Vault) requestTokenWithKubernetesAuth(client Client, kubernetesAuth *v1
key := kubernetesAuth.SecretRef.Key
if key == "" {
key = "token"
key = v1alpha2.DefaultVaultTokenAuthSecretKey
}
keyBytes, ok := secret.Data[key]
if !ok {
return "", fmt.Errorf("no data for %q in secret '%s/%s'", key, kubernetesAuth.SecretRef.Name, v.namespace)
return "", fmt.Errorf("no data for %q in secret '%s/%s'", key, v.namespace, kubernetesAuth.SecretRef.Name)
}
jwt := string(keyBytes)
@@ -318,10 +315,10 @@ func (v *Vault) requestTokenWithKubernetesAuth(client Client, kubernetesAuth *v1
mountPath := kubernetesAuth.Path
if mountPath == "" {
mountPath = defaultKubernetesAuthMountPath
mountPath = v1alpha2.DefaultVaultKubernetesAuthMountPath
}
url := fmt.Sprintf("/v1/auth/%s/login", mountPath)
url := filepath.Join("/v1/auth", mountPath, "login")
request := client.NewRequest("POST", url)
err = request.SetJSONBody(parameters)
if err != nil {
+30 -30
View File
@@ -228,8 +228,8 @@ func TestSetToken(t *testing.T) {
gen.SetIssuerVault(v1alpha2.VaultIssuer{
CABundle: []byte(testCertBundle),
Auth: v1alpha2.VaultAuth{
TokenSecretRef: cmmeta.SecretKeySelector{
LocalObjectReference: cmmeta.LocalObjectReference{
TokenSecretRef: &v1alpha2.SecretKeySelector{
LocalObjectReference: v1alpha2.LocalObjectReference{
Name: "secret-ref-name",
},
},
@@ -249,8 +249,8 @@ func TestSetToken(t *testing.T) {
gen.SetIssuerVault(v1alpha2.VaultIssuer{
CABundle: []byte(testCertBundle),
Auth: v1alpha2.VaultAuth{
TokenSecretRef: cmmeta.SecretKeySelector{
LocalObjectReference: cmmeta.LocalObjectReference{
TokenSecretRef: &v1alpha2.SecretKeySelector{
LocalObjectReference: v1alpha2.LocalObjectReference{
Name: "secret-ref-name",
},
Key: "my-token-key",
@@ -271,7 +271,7 @@ func TestSetToken(t *testing.T) {
gen.SetIssuerVault(v1alpha2.VaultIssuer{
CABundle: []byte(testCertBundle),
Auth: v1alpha2.VaultAuth{
AppRole: v1alpha2.VaultAppRole{
AppRole: &v1alpha2.VaultAppRole{
RoleId: "my-role-id",
SecretRef: cmmeta.SecretKeySelector{
LocalObjectReference: cmmeta.LocalObjectReference{
@@ -296,7 +296,7 @@ func TestSetToken(t *testing.T) {
gen.SetIssuerVault(v1alpha2.VaultIssuer{
CABundle: []byte(testCertBundle),
Auth: v1alpha2.VaultAuth{
AppRole: v1alpha2.VaultAppRole{
AppRole: &v1alpha2.VaultAppRole{
RoleId: "my-role-id",
SecretRef: cmmeta.SecretKeySelector{
LocalObjectReference: cmmeta.LocalObjectReference{
@@ -325,13 +325,13 @@ func TestSetToken(t *testing.T) {
"if kubernetes role auth set but reference secret doesn't exist return error": {
issuer: gen.Issuer("vault-issuer",
gen.SetIssuerVault(v1alpha1.VaultIssuer{
gen.SetIssuerVault(v1alpha2.VaultIssuer{
CABundle: []byte(testCertBundle),
Auth: v1alpha1.VaultAuth{
Kubernetes: v1alpha1.KubernetesAuth{
Auth: v1alpha2.VaultAuth{
Kubernetes: &v1alpha2.KubernetesAuth{
Role: "kube-vault-role",
SecretRef: v1alpha1.SecretKeySelector{
LocalObjectReference: v1alpha1.LocalObjectReference{
SecretRef: v1alpha2.SecretKeySelector{
LocalObjectReference: v1alpha2.LocalObjectReference{
Name: "secret-ref-name",
},
Key: "my-kube-key",
@@ -350,13 +350,13 @@ func TestSetToken(t *testing.T) {
"if kubernetes role auth set but reference secret doesn't contain data at key error": {
issuer: gen.Issuer("vault-issuer",
gen.SetIssuerVault(v1alpha1.VaultIssuer{
gen.SetIssuerVault(v1alpha2.VaultIssuer{
CABundle: []byte(testCertBundle),
Auth: v1alpha1.VaultAuth{
Kubernetes: v1alpha1.KubernetesAuth{
Auth: v1alpha2.VaultAuth{
Kubernetes: &v1alpha2.KubernetesAuth{
Role: "kube-vault-role",
SecretRef: v1alpha1.SecretKeySelector{
LocalObjectReference: v1alpha1.LocalObjectReference{
SecretRef: v1alpha2.SecretKeySelector{
LocalObjectReference: v1alpha2.LocalObjectReference{
Name: "secret-ref-name",
},
Key: "my-kube-key",
@@ -370,18 +370,18 @@ func TestSetToken(t *testing.T) {
),
fakeClient: vaultfake.NewFakeClient(),
expectedToken: "",
expectedErr: errors.New(`error reading Kubernetes service account token from secret-ref-name: no data for "my-kube-key" in secret 'secret-ref-name/test-namespace'`),
expectedErr: errors.New(`error reading Kubernetes service account token from secret-ref-name: no data for "my-kube-key" in secret 'test-namespace/secret-ref-name'`),
},
"if kubernetes role auth set but errors with a raw request should error": {
issuer: gen.Issuer("vault-issuer",
gen.SetIssuerVault(v1alpha1.VaultIssuer{
gen.SetIssuerVault(v1alpha2.VaultIssuer{
CABundle: []byte(testCertBundle),
Auth: v1alpha1.VaultAuth{
Kubernetes: v1alpha1.KubernetesAuth{
Auth: v1alpha2.VaultAuth{
Kubernetes: &v1alpha2.KubernetesAuth{
Role: "kube-vault-role",
SecretRef: v1alpha1.SecretKeySelector{
LocalObjectReference: v1alpha1.LocalObjectReference{
SecretRef: v1alpha2.SecretKeySelector{
LocalObjectReference: v1alpha2.LocalObjectReference{
Name: "secret-ref-name",
},
Key: "my-kube-key",
@@ -400,13 +400,13 @@ func TestSetToken(t *testing.T) {
"foo": {
issuer: gen.Issuer("vault-issuer",
gen.SetIssuerVault(v1alpha1.VaultIssuer{
gen.SetIssuerVault(v1alpha2.VaultIssuer{
CABundle: []byte(testCertBundle),
Auth: v1alpha1.VaultAuth{
Kubernetes: v1alpha1.KubernetesAuth{
Auth: v1alpha2.VaultAuth{
Kubernetes: &v1alpha2.KubernetesAuth{
Role: "kube-vault-role",
SecretRef: v1alpha1.SecretKeySelector{
LocalObjectReference: v1alpha1.LocalObjectReference{
SecretRef: v1alpha2.SecretKeySelector{
LocalObjectReference: v1alpha2.LocalObjectReference{
Name: "secret-ref-name",
},
Key: "my-kube-key",
@@ -435,7 +435,7 @@ func TestSetToken(t *testing.T) {
gen.SetIssuerVault(v1alpha2.VaultIssuer{
CABundle: []byte(testCertBundle),
Auth: v1alpha2.VaultAuth{
AppRole: v1alpha2.VaultAppRole{
AppRole: &v1alpha2.VaultAppRole{
RoleId: "my-role-id",
SecretRef: cmmeta.SecretKeySelector{
LocalObjectReference: cmmeta.LocalObjectReference{
@@ -444,8 +444,8 @@ func TestSetToken(t *testing.T) {
Key: "my-role-key",
},
},
TokenSecretRef: cmmeta.SecretKeySelector{
LocalObjectReference: cmmeta.LocalObjectReference{
TokenSecretRef: &v1alpha2.SecretKeySelector{
LocalObjectReference: v1alpha2.LocalObjectReference{
Name: "secret-ref-name",
},
Key: "my-token-key",
+19 -20
View File
@@ -58,43 +58,42 @@ func (v *Vault) Setup(ctx context.Context) error {
return nil
}
tokenAuth := v.issuer.GetSpec().Vault.Auth.TokenSecretRef
appRoleAuth := v.issuer.GetSpec().Vault.Auth.AppRole
kubeAuth := v.issuer.GetSpec().Vault.Auth.Kubernetes
// check if at least one auth method is specified.
if v.issuer.GetSpec().Vault.Auth.TokenSecretRef.Name == "" &&
v.issuer.GetSpec().Vault.Auth.AppRole.RoleId == "" &&
v.issuer.GetSpec().Vault.Auth.AppRole.SecretRef.Name == "" &&
v.issuer.GetSpec().Vault.Auth.Kubernetes.Role == "" &&
v.issuer.GetSpec().Vault.Auth.Kubernetes.SecretRef.Name == "" {
if tokenAuth == nil && appRoleAuth == nil && kubeAuth == nil {
klog.Infof("%s: %s", v.issuer.GetObjectMeta().Name, messsageAuthFieldsRequired)
apiutil.SetIssuerCondition(v.issuer, v1alpha2.IssuerConditionReady, cmmeta.ConditionFalse, errorVault, messsageAuthFieldsRequired)
return nil
}
// check if only token auth method is set.
if v.issuer.GetSpec().Vault.Auth.TokenSecretRef.Name != "" &&
(v.issuer.GetSpec().Vault.Auth.AppRole.RoleId != "" ||
v.issuer.GetSpec().Vault.Auth.AppRole.SecretRef.Name != "" ||
v.issuer.GetSpec().Vault.Auth.Kubernetes.Role != "") {
// check only one auth method set
if (tokenAuth != nil && appRoleAuth != nil) ||
(tokenAuth != nil && kubeAuth != nil) ||
(appRoleAuth != nil && kubeAuth != nil) {
klog.Infof("%s: %s", v.issuer.GetObjectMeta().Name, messageAuthFieldRequired)
apiutil.SetIssuerCondition(v.issuer, v1alpha1.IssuerConditionReady, v1alpha1.ConditionFalse, errorVault, messageAuthFieldRequired)
return nil
}
// check if all mandatory Vault Token fields are set.
if tokenAuth != nil && len(tokenAuth.Name) == 0 {
klog.Infof("%s: %s", v.issuer.GetObjectMeta().Name, messageAuthFieldRequired)
apiutil.SetIssuerCondition(v.issuer, v1alpha2.IssuerConditionReady, cmmeta.ConditionFalse, errorVault, messageAuthFieldRequired)
return nil
}
// check if all mandatory Vault appRole fields are set.
if v.issuer.GetSpec().Vault.Auth.TokenSecretRef.Name == "" &&
v.issuer.GetSpec().Vault.Auth.Kubernetes.Role == "" &&
(v.issuer.GetSpec().Vault.Auth.AppRole.RoleId == "" ||
v.issuer.GetSpec().Vault.Auth.AppRole.SecretRef.Name == "") {
if appRoleAuth != nil && (len(appRoleAuth.RoleId) == 0 || len(appRoleAuth.SecretRef.Name) == 0) {
klog.Infof("%s: %s", v.issuer.GetObjectMeta().Name, messageAuthFieldRequired)
apiutil.SetIssuerCondition(v.issuer, v1alpha2.IssuerConditionReady, cmmeta.ConditionFalse, errorVault, messageAuthFieldRequired)
return nil
}
// check if all mandatory Kubernetes Auth fields are set.
if v.issuer.GetSpec().Vault.Auth.Kubernetes.Role != "" &&
v.issuer.GetSpec().Vault.Auth.Kubernetes.SecretRef.Name != "" &&
(v.issuer.GetSpec().Vault.Auth.AppRole.RoleId != "" ||
v.issuer.GetSpec().Vault.Auth.AppRole.SecretRef.Name != "" ||
v.issuer.GetSpec().Vault.Auth.TokenSecretRef.Name != "") {
// check if all mandatory Vault Kubernetes fields are set.
if kubeAuth != nil && (len(kubeAuth.SecretRef.Name) == 0 || len(kubeAuth.Role) == 0) {
klog.Infof("%s: %s", v.issuer.GetObjectMeta().Name, messageAuthFieldRequired)
apiutil.SetIssuerCondition(v.issuer, v1alpha1.IssuerConditionReady, v1alpha1.ConditionFalse, errorVault, messageAuthFieldRequired)
return nil
+47 -10
View File
@@ -65,14 +65,36 @@ func NewVaultServiceAccount(name string) *v1.ServiceAccount {
}
}
func NewVaultServiceAccountRoleBinding(namespace, subject string) *rbacv1.ClusterRoleBinding {
return &rbacv1.ClusterRoleBinding{
func NewVaultServiceAccountRole(namespace string) *rbacv1.Role {
return &rbacv1.Role{
ObjectMeta: metav1.ObjectMeta{
Name: fmt.Sprintf("%s:%s:auth-delegator", namespace, subject),
Name: "auth-delegator",
Namespace: namespace,
},
Rules: []rbacv1.PolicyRule{
{
APIGroups: []string{"authentication.k8s.io"},
Resources: []string{"tokenreviews"},
Verbs: []string{"create"},
},
{
APIGroups: []string{"authorization.k8s.io"},
Resources: []string{"subjectaccessreviews"},
Verbs: []string{"create"},
},
},
}
}
func NewVaultServiceAccountRoleBinding(namespace, subject string) *rbacv1.RoleBinding {
return &rbacv1.RoleBinding{
ObjectMeta: metav1.ObjectMeta{
Name: fmt.Sprintf("%s:auth-delegator", subject),
Namespace: namespace,
},
RoleRef: rbacv1.RoleRef{
APIGroup: "rbac.authorization.k8s.io",
Kind: "ClusterRole",
Kind: "Role",
Name: "system:auth-delegator",
},
Subjects: []rbacv1.Subject{
@@ -203,7 +225,7 @@ func (v *VaultInitializer) Setup() error {
return err
}
if err := v.setupKubernetes(); err != nil {
if err := v.setupKubernetesBasedAuth(); err != nil {
return err
}
@@ -397,7 +419,7 @@ func (v *VaultInitializer) setupRole() error {
return nil
}
func (v *VaultInitializer) setupKubernetes() error {
func (v *VaultInitializer) setupKubernetesBasedAuth() error {
if len(v.APIServerURL) == 0 {
// skip initialization if not provided
return nil
@@ -441,11 +463,17 @@ func (v *VaultInitializer) CreateKubernetesRole(client kubernetes.Interface, nam
return fmt.Errorf("error creating ServiceAccount for Kubernetes auth: %s", err.Error())
}
role := NewVaultServiceAccountRole(namespace)
_, err = client.RbacV1().Roles(namespace).Create(role)
if err != nil {
return fmt.Errorf("error creating Role for Kubernetes auth ServiceAccount: %s", err.Error())
}
roleBinding := NewVaultServiceAccountRoleBinding(namespace, serviceAccountName)
_, err = client.RbacV1().ClusterRoleBindings().Create(roleBinding)
_, err = client.RbacV1().RoleBindings(namespace).Create(roleBinding)
if err != nil {
return fmt.Errorf("error creating ClusterRoleBinding for Kubernetes auth ServiceAccount: %s", err.Error())
return fmt.Errorf("error creating RoleBinding for Kubernetes auth ServiceAccount: %s", err.Error())
}
// vault write auth/kubernetes/role/<roleName>
@@ -466,8 +494,17 @@ func (v *VaultInitializer) CreateKubernetesRole(client kubernetes.Interface, nam
// CleanKubernetesRole cleans up the ClusterRoleBinding and ServiceAccount for Kubernetes auth delegation
func (v *VaultInitializer) CleanKubernetesRole(client kubernetes.Interface, namespace, roleName, serviceAccountName string) error {
client.RbacV1().ClusterRoleBindings().Delete(fmt.Sprintf("%s:%s:auth-delegator", namespace, serviceAccountName), nil)
client.CoreV1().ServiceAccounts(namespace).Delete(serviceAccountName, nil)
if err := client.RbacV1().RoleBindings(namespace).Delete(fmt.Sprintf("%s:auth-delegator", serviceAccountName), nil); err != nil {
return err
}
if err := client.RbacV1().Roles(namespace).Delete("auth-delegator", nil); err != nil {
return err
}
if err := client.CoreV1().ServiceAccounts(namespace).Delete(serviceAccountName, nil); err != nil {
return err
}
// vault delete auth/kubernetes/role/<roleName>
url := path.Join(fmt.Sprintf("/v1/auth/%s/role", v.KubernetesAuthPath), roleName)
+5 -5
View File
@@ -472,7 +472,7 @@ func NewCertManagerVaultIssuerToken(name, vaultURL, vaultPath, vaultSecretToken,
Path: vaultPath,
CABundle: caBundle,
Auth: v1alpha2.VaultAuth{
TokenSecretRef: cmmeta.SecretKeySelector{
TokenSecretRef: &cmmeta.SecretKeySelector{
Key: "secretkey",
LocalObjectReference: cmmeta.LocalObjectReference{
Name: vaultSecretToken,
@@ -497,7 +497,7 @@ func NewCertManagerVaultIssuerAppRole(name, vaultURL, vaultPath, roleId, vaultSe
Path: vaultPath,
CABundle: caBundle,
Auth: v1alpha2.VaultAuth{
AppRole: v1alpha2.VaultAppRole{
AppRole: &v1alpha2.VaultAppRole{
Path: authPath,
RoleId: roleId,
SecretRef: cmmeta.SecretKeySelector{
@@ -526,11 +526,11 @@ func NewCertManagerVaultIssuerKubernetes(name, vaultURL, vaultPath, vaultSecretS
Path: vaultPath,
CABundle: caBundle,
Auth: v1alpha2.VaultAuth{
Kubernetes: v1alpha2.KubernetesAuth{
Kubernetes: &v1alpha2.VaultKubernetesAuth{
Path: authPath,
SecretRef: v1alpha2.SecretKeySelector{
SecretRef: cmmeta.SecretKeySelector{
Key: "token",
LocalObjectReference: v1alpha2.LocalObjectReference{
LocalObjectReference: cmmeta.LocalObjectReference{
Name: vaultSecretServiceAccount,
},
},