Skip to content

Commit

Permalink
chore(secret): Add config to values.yaml to configure how reconciler …
Browse files Browse the repository at this point in the history
…searches for secret
  • Loading branch information
m8rmclaren committed Dec 5, 2023
1 parent 6b3b2b1 commit 8fcd8a5
Show file tree
Hide file tree
Showing 10 changed files with 154 additions and 97 deletions.
76 changes: 48 additions & 28 deletions deploy/charts/ejbca-cert-manager-issuer/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,50 +25,70 @@ helm repo update

### Install Chart

```bash
helm install ejbca-cert-manager-issuer ejbca-issuer/ejbca-cert-manager-issuer
```shell
helm install ejbca-cert-manager-issuer ejbca-issuer/ejbca-cert-manager-issuer \
--namespace ejbca-issuer-system \
--create-namespace \
--set image.repository=<your container registry>/keyfactor/ejbca-cert-manager-issuer \
--set image.tag=<tag>
# --set image.pullPolicy=Never # Only required if using a local image
```

Modifications can be made by overriding the default values in the `values.yaml` file with the `--set` flag. For example, to override the `replicaCount` value, run the following ejbca:
```bash
Modifications can be made by overriding the default values in the `values.yaml` file with the `--set` flag. For example, to override the `secretConfig.useClusterRoleForSecretAccess` to configure the chart to use a cluster role for secret access, run the following command:

```shell
helm install ejbca-cert-manager-issuer ejbca-issuer/ejbca-cert-manager-issuer \
--namespace ejbca-issuer-system \
--create-namespace \
--set image.repository=<your container registry>/keyfactor/ejbca-cert-manager-issuer \
--set image.tag=<tag>
--set replicaCount=2
```

Modifications can also be made by modifying the `values.yaml` file directly. For example, to override the `replicaCount` value, modify the `replicaCount` value in the `values.yaml` file:
Modifications can also be made by modifying the `values.yaml` file directly. For example, to override the `secretConfig.useClusterRoleForSecretAccess` value to configure the chart to use a cluster role for secret access, modify the `secretConfig.useClusterRoleForSecretAccess` value in the `values.yaml` file by creating an override file:

```yaml
cat <<EOF > override.yaml
replicaCount: 2
image:
repository: <your container registry>/keyfactor/ejbca-cert-manager-issuer
pullPolicy: Never
tag: "latest"
secretConfig:
useClusterRoleForSecretAccess: true
EOF
```

Then, use the `-f` flag to specify the `values.yaml` file:
```bash

```shell
helm install ejbca-cert-manager-issuer ejbca-issuer/ejbca-cert-manager-issuer \
--namespace command-issuer-system \
-f override.yaml
```

## Configuration

The following table lists the configurable parameters of the `ejbca-cert-manager-issuer` chart and their default values.

| Parameter | Description | Default |
|-----------------------------------|-----------------------------------------------------|--------------------------------------------------------------|
| `replicaCount` | Number of replica ejbca-cert-manager-issuers to run | `1` |
| `image.repository` | Image repository | `m8rmclarenkf/ejbca-cert-manager-external-issuer-controller` |
| `image.pullPolicy` | Image pull policy | `IfNotPresent` |
| `image.tag` | Image tag | `v1.3.1` |
| `imagePullSecrets` | Image pull secrets | `[]` |
| `nameOverride` | Name override | `""` |
| `fullnameOverride` | Full name override | `""` |
| `crd.create` | Specifies if CRDs will be created | `true` |
| `crd.annotations` | Annotations to add to the CRD | `{}` |
| `serviceAccount.create` | Specifies if a service account should be created | `true` |
| `serviceAccount.annotations` | Annotations to add to the service account | `{}` |
| `serviceAccount.name` | Name of the service account to use | `""` (uses the fullname template if `create` is true) |
| `podAnnotations` | Annotations for the pod | `{}` |
| `podSecurityContext.runAsNonRoot` | Run pod as non-root | `true` |
| `securityContext` | Security context for the pod | `{}` (with commented out options) |
| `secureMetrics.enabled` | Enable secure metrics via the Kube RBAC Proy | `false` |
| `resources` | CPU/Memory resource requests/limits | `{}` (with commented out options) |
| `nodeSelector` | Node labels for pod assignment | `{}` |
| `tolerations` | Tolerations for pod assignment | `[]` |
| Parameter | Description | Default |
|----------------------------------------------|-----------------------------------------------------------------------------------------------------|--------------------------------------------------------------|
| `replicaCount` | Number of replica ejbca-cert-manager-issuers to run | `1` |
| `image.repository` | Image repository | `m8rmclarenkf/ejbca-cert-manager-external-issuer-controller` |
| `image.pullPolicy` | Image pull policy | `IfNotPresent` |
| `image.tag` | Image tag | `v1.3.1` |
| `imagePullSecrets` | Image pull secrets | `[]` |
| `nameOverride` | Name override | `""` |
| `fullnameOverride` | Full name override | `""` |
| `crd.create` | Specifies if CRDs will be created | `true` |
| `crd.annotations` | Annotations to add to the CRD | `{}` |
| `serviceAccount.create` | Specifies if a service account should be created | `true` |
| `serviceAccount.annotations` | Annotations to add to the service account | `{}` |
| `serviceAccount.name` | Name of the service account to use | `""` (uses the fullname template if `create` is true) |
| `podAnnotations` | Annotations for the pod | `{}` |
| `podSecurityContext.runAsNonRoot` | Run pod as non-root | `true` |
| `securityContext` | Security context for the pod | `{}` (with commented out options) |
| `secureMetrics.enabled` | Enable secure metrics via the Kube RBAC Proy | `false` |
| `resources` | CPU/Memory resource requests/limits | `{}` (with commented out options) |
| `nodeSelector` | Node labels for pod assignment | `{}` |
| `tolerations` | Tolerations for pod assignment | `[]` |
| `secretConfig.useClusterRoleForSecretAccess` | Specifies if the ServiceAccount should be granted access to the Secret resource using a ClusterRole | `false` |
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ spec:
- --health-probe-bind-address=:8081
- --metrics-bind-address=127.0.0.1:8080
- --leader-elect
{{- if .Values.secretConfig.useClusterRoleForSecretAccess}}
- --secret-access-granted-at-cluster-level
{{- end}}
command:
- /manager
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
Expand Down
10 changes: 10 additions & 0 deletions deploy/charts/ejbca-cert-manager-issuer/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,16 @@ fullnameOverride: ""
secureMetrics:
enabled: false

secretConfig:
# If true, when using Issuer resources, the credential secret must be created in the same namespace as the
# Issuer resource. This access is facilitated by granting the ServiceAccount [get, list, watch] for the secret
# API at the cluster level.
#
# If false, both Issuer and ClusterIssuer must reference a secret in the same namespace as the chart/reconciler.
# This access is facilitated by granting the ServiceAccount [get, list, watch] for the secret API only for the
# namespace the chart is deployed in.
useClusterRoleForSecretAccess: false

crd:
# Specifies whether CRDs will be created
create: true
Expand Down
2 changes: 1 addition & 1 deletion docs/config_usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
The cert-manager external issuer for Keyfactor EJBCA can be used to issue certificates from Keyfactor EJBCA using cert-manager.

### Authentication
Authentication to the EJBCA platform is done using a client certificate and key. The client certificate and key must be provided as a Kubernetes secret.
Authentication to the EJBCA platform is done using a client certificate and key. The client certificate and key must be provided as a Kubernetes secret. If the Helm chart was deployed with the `--set "secretConfig.useClusterRoleForSecretAccess=true"` flag, the secret must be created in the same namespace as any Issuer resources deployed. Otherwise, the secret must be created in the same namespace as the controller.

Create a K8s TLS secret containing the client certificate and key to authenticate with EJBCA:
```shell
Expand Down
68 changes: 33 additions & 35 deletions docs/install.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,55 +53,53 @@ The cert-manager external issuer for Keyfactor EJBCA can also be installed using

1. Add the Helm repository:

```bash
```shell
helm repo add ejbca-issuer https://keyfactor.github.io/ejbca-cert-manager-issuer
helm repo update
```

2. Then, install the chart:

```bash
helm install ejbca-cert-manager-issuer ejbca-issuer/ejbca-cert-manager-issuer \
--namespace ejbca-issuer-system \
--create-namespace \
--set image.repository=<your container registry>/keyfactor/ejbca-cert-manager-issuer \
--set image.tag=<tag>
# --set image.pullPolicy=Never # Only required if using a local image
```

a. Modifications can be made by overriding the default values in the `values.yaml` file with the `--set` flag. For example, to override the `replicaCount` value, run the following command:

```shell
helm install ejbca-cert-manager-issuer ejbca-issuer/ejbca-cert-manager-issuer \
--namespace ejbca-issuer-system \
--create-namespace \
--set image.repository=<your container registry>/keyfactor/ejbca-cert-manager-issuer \
--set image.tag=<tag>
--set replicaCount=2
```

b. Modifications can also be made by modifying the `values.yaml` file directly. For example, to override the
`replicaCount` value, modify the `replicaCount` value in the `values.yaml` file:

```yaml
cat <<EOF > override.yaml
image:
repository: <your container registry>/keyfactor/ejbca-cert-manager-issuer
pullPolicy: Never
tag: "latest"
replicaCount: 2
EOF
# --set image.pullPolicy=Never # Only required if using a local image
```

Then, use the `-f` flag to specify the `values.yaml` file:

```yaml
helm install ejbca-cert-manager-issuer ejbca-issuer/ejbca-cert-manager-issuer \
-f override.yaml
```
1. Modifications can be made by overriding the default values in the `values.yaml` file with the `--set` flag. For example, to override the `secretConfig.useClusterRoleForSecretAccess` to configure the chart to use a cluster role for secret access, run the following command:

```shell
helm install ejbca-cert-manager-issuer ejbca-issuer/ejbca-cert-manager-issuer \
--namespace ejbca-issuer-system \
--create-namespace \
--set image.repository=<your container registry>/keyfactor/ejbca-cert-manager-issuer \
--set image.tag=<tag>
--set replicaCount=2
```

2. Modifications can also be made by modifying the `values.yaml` file directly. For example, to override the `secretConfig.useClusterRoleForSecretAccess` value to configure the chart to use a cluster role for secret access, modify the `secretConfig.useClusterRoleForSecretAccess` value in the `values.yaml` file by creating an override file:

```yaml
cat <<EOF > override.yaml
image:
repository: <your container registry>/keyfactor/ejbca-cert-manager-issuer
pullPolicy: Never
tag: "latest"
secretConfig:
useClusterRoleForSecretAccess: true
EOF
```

Then, use the `-f` flag to specify the `values.yaml` file:

```shell
helm install ejbca-cert-manager-issuer ejbca-issuer/ejbca-cert-manager-issuer \
--namespace command-issuer-system \
-f override.yaml
```

Next, complete the [Usage](config_usage.md) steps to configure the cert-manager external issuer for Keyfactor EJBCA.




10 changes: 8 additions & 2 deletions internal/controllers/certificaterequest_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,9 @@ type CertificateRequestReconciler struct {
SignerBuilder signer.EjbcaSignerBuilder
ClusterResourceNamespace string

Clock clock.Clock
CheckApprovedCondition bool
Clock clock.Clock
CheckApprovedCondition bool
SecretAccessGrantedAtClusterLevel bool
}

// +kubebuilder:rbac:groups=cert-manager.io,resources=certificaterequests,verbs=get;list;watch
Expand Down Expand Up @@ -177,6 +178,11 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
return ctrl.Result{}, nil
}

// If SecretAccessGrantedAtClusterLevel is false, we always look for the Secret in the same namespace as the Issuer
if !r.SecretAccessGrantedAtClusterLevel {
secretNamespace = r.ClusterResourceNamespace
}

// Get the Issuer or ClusterIssuer
if err := r.Get(ctx, issuerName, issuer); err != nil {
return ctrl.Result{}, fmt.Errorf("%w: %v", errGetIssuer, err)
Expand Down
13 changes: 7 additions & 6 deletions internal/controllers/certificaterequest_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -605,12 +605,13 @@ func TestCertificateRequestReconcile(t *testing.T) {
WithObjects(tc.objects...).
Build()
controller := CertificateRequestReconciler{
Client: fakeClient,
Scheme: scheme,
ClusterResourceNamespace: tc.clusterResourceNamespace,
SignerBuilder: tc.Builder,
CheckApprovedCondition: true,
Clock: fixedClock,
Client: fakeClient,
Scheme: scheme,
ClusterResourceNamespace: tc.clusterResourceNamespace,
SignerBuilder: tc.Builder,
CheckApprovedCondition: true,
Clock: fixedClock,
SecretAccessGrantedAtClusterLevel: true,
}
result, err := controller.Reconcile(
ctrl.LoggerInto(context.TODO(), logrtesting.NewTestLogger(t)),
Expand Down
14 changes: 10 additions & 4 deletions internal/controllers/issuer_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,11 @@ var (
// IssuerReconciler reconciles a Issuer object
type IssuerReconciler struct {
client.Client
Kind string
Scheme *runtime.Scheme
ClusterResourceNamespace string
HealthCheckerBuilder signer.HealthCheckerBuilder
Kind string
Scheme *runtime.Scheme
ClusterResourceNamespace string
HealthCheckerBuilder signer.HealthCheckerBuilder
SecretAccessGrantedAtClusterLevel bool
}

//+kubebuilder:rbac:groups=ejbca-issuer.keyfactor.com,resources=issuers;clusterissuers,verbs=get;list;watch
Expand Down Expand Up @@ -124,6 +125,11 @@ func (r *IssuerReconciler) Reconcile(ctx context.Context, req ctrl.Request) (res
return ctrl.Result{}, nil
}

// If SecretAccessGrantedAtClusterLevel is false, we always look for the Secret in the same namespace as the Issuer
if !r.SecretAccessGrantedAtClusterLevel {
secretName.Namespace = r.ClusterResourceNamespace
}

var authSecret corev1.Secret
if err := r.Get(ctx, secretName, &authSecret); err != nil {
return ctrl.Result{}, fmt.Errorf("%w, secret name: %s, reason: %v", errGetAuthSecret, secretName, err)
Expand Down
11 changes: 6 additions & 5 deletions internal/controllers/issuer_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -251,11 +251,12 @@ func TestIssuerReconcile(t *testing.T) {
tc.kind = "Issuer"
}
controller := IssuerReconciler{
Kind: tc.kind,
Client: fakeClient,
Scheme: scheme,
HealthCheckerBuilder: tc.healthCheckerBuilder,
ClusterResourceNamespace: tc.clusterResourceNamespace,
Kind: tc.kind,
Client: fakeClient,
Scheme: scheme,
HealthCheckerBuilder: tc.healthCheckerBuilder,
ClusterResourceNamespace: tc.clusterResourceNamespace,
SecretAccessGrantedAtClusterLevel: true,
}
result, err := controller.Reconcile(
ctrl.LoggerInto(context.TODO(), logrtesting.NewTestLogger(t)),
Expand Down
Loading

0 comments on commit 8fcd8a5

Please sign in to comment.