Coder Social home page Coder Social logo

redhat-cop / cert-utils-operator Goto Github PK

View Code? Open in Web Editor NEW
89.0 18.0 36.0 15.85 MB

Set of functionalities around certificates packaged in a Kubernetes operator

License: Apache License 2.0

Dockerfile 0.80% Go 78.32% Makefile 14.55% Smarty 4.19% Mustache 1.44% Python 0.69%
k8s-operator container-cop

cert-utils-operator's Introduction

Cert-utils-operator

build status Go Report Card GitHub go.mod Go version

Cert utils operator is a set of functionalities around certificates packaged in a Kubernetes operator.

Certificates are assumed to be available in a secret of type kubernetes.io/tls (other types of secrets are ignored by this operator). By convention this type of secrets have three optional entries:

  1. tls.key: the private key of the certificate.
  2. tls.crt: the actual certificate.
  3. ca.crt: the CA bundle that validates the certificate.

The functionalities are the following:

  1. Ability to populate route certificates
  2. Ability to create java keystore and truststore from the certificates
  3. Ability to show info regarding the certificates
  4. Ability to alert when a certificate is about to expire
  5. Ability to inject ca bundles in Secrets, ConfigMaps, ValidatingWebhookConfiguration, MutatingWebhookConfiguration CustomResourceDefinition and APIService objects

All these feature are activated via opt-in annotations.

Populating route certificates

This feature works on secure routes with edge or reencrypt type of termination.

This feature is activated with the following annotation on a route: cert-utils-operator.redhat-cop.io/certs-from-secret: "<secret-name>". Routes that are not secured (tls.termination field initialized to either edge or reencrypt) will be ignored even if they have the annotation.

The following fields of the route will be updated:

  1. key with the content of tls.key.
  2. certificate with the content of tls.crt.
  3. caCertificate with the content of ca.crt.

It is possible to control whether the caCertificate field should be injected via the following annotations cert-utils-operator.redhat-cop.io/inject-CA: "[true|false]". The default is true. This can be useful if the certificate also contains the ca in ca.crt in its certificate chain. In this case the OpenShift route validation will fail.

The destinationCACertificate can also be injected. To activate this feature use the following annotation: cert-utils-operator.redhat-cop.io/destinationCA-from-secret: "<secret-name>". The following field will be updated:

  1. destinationCACertificate with the content of ca.crt.

Note that the two annotations can point to different secrets.

Creating java keystore and truststore

Secrets

This feature is activated with the following annotation on a kubernetes.io/tls secret: cert-utils-operator.redhat-cop.io/generate-java-keystores: "true".

When this annotation is set two more entries are added to the secret:

  1. keystore.jks: this Java keystore contains the tls.crt and tls.key certificate.
  2. trustsstore.jks: this Java keystore contains the ca.crt certificate.

Note that Java Keystore require the key to be in PKCS#8 format. It is a responsibility of the certificate provisioner to make sure the key is in this format. No validation is currently performed by the cert-utils operator.

A such annotated secret looks like the following:

keystore

The default password for these keystores is changeme. The password can be changed by adding the following optional annotation: cert-utils-operator.redhat-cop.io/java-keystore-password: <password>. The alias of the certificate inside the keystore is alias.

ConfigMaps

This feature is activated with the following annotation on a configmap: cert-utils-operator.redhat-cop.io/generate-java-truststore: "true".

When this annotation is the following entry is added to the configmap as binaryData:

  1. truststore.jks: this Java keystore contains the ca-bundle.crt certificate.

Note that Java Keystore require the key to be in PKCS#8 format. It is a responsibility of the certificate provisioner to make sure the key is in this format. No validation is currently performed by the cert-utils operator.

The default password for these keystores is changeit. The password can be changed by adding the following optional annotation: cert-utils-operator.redhat-cop.io/java-keystore-password: <password>. The alias of the certificate inside the keystore is alias.

Annotation Default Description
cert-utils-operator.redhat-cop.io/java-keystore-password changeit The password to use when consuming the JKS trust store
cert-utils-operator.redhat-cop.io/generate-java-truststore false Should the JKS file be generated and attached to the configmap
cert-utils-operator.redhat-cop.io/source-ca-key ca-bundle.crt The key in the configmap which will be read to generate the truststore.jks

Showing info on the certificates

This feature is activated with the following annotation on a kubernetes.io/tls secret: cert-utils-operator.redhat-cop.io/generate-cert-info: "true".

When this annotation is set two more entries are added to the secret:

  1. tls.crt.info: this entries contains a textual representation of tls.crt the certificates in a similar notation to openssl.
  2. ca.crt.info: this entries contains a textual representation of ca.crt the certificates in a similar notation to openssl.

A such annotated secret looks like the following:

certinfo

Alerting when a certificate is about to expire

This operator can generate Prometheus alerts and/or Kubernetes events when a certifciate is about to expire.

Generating prometheus alerts

Prometheus alerts are generated for all certificates. In order for the certifciate metrics to be collected and the alerts be generated the Prometheus CRs deployed with this operator must be honored by a Prometheus operator. If you are running on OpenShift just add the label openshift.io/cluster-monitoring="true" to the namespace containing the operator.

The following metrics will be collected for every tls secret:

Metric Name Description
certutils_certificate_issue_time time at which the certificate was created in seconds from from January 1, 1970 UTC
certutils_certificate_expiry_time time at which the certificate expires in seconds from from January 1, 1970 UTC
cert:validity_duration:sec duration of the certificate validity in seconds
cert:time_to_expiration:sec time left to expiration in seconds

Alerts will be generated at 85% and 95% of the certifciate lifetime. Alerts are generated for all certificates including certifciate that are possibly automatically rotated. This is intentional as the automation that rotates the certificates may be non-functioning.

If these alerts are not useful in your deployment, you can be silenced them in alert-manager as described here.

Generating Kubernetes events

This feature is activated with the following annotation on a kubernetes.io/tls secret: cert-utils-operator.redhat-cop.io/generate-cert-expiry-alert: "true".

When this annotation is set the secret will generate a Kubernetes Warning Event if the certificate is about to expire.

This feature is useful when the certificates are not renewed by an automatic system.

The timing of this alerting mechanism can be controller with the following annotations:

Annotation Default Description
cert-utils-operator.redhat-cop.io/cert-expiry-check-frequency 7 days with which frequency should the system check is a certificate is expiring
cert-utils-operator.redhat-cop.io/cert-soon-to-expire-check-frequency 1 hour with which frequency should the system check is a certificate is expired, once it's close to expiring
cert-utils-operator.redhat-cop.io/cert-soon-to-expire-threshold 90 days what is the interval of time below which we consider the certificate close to expiry

Here is an example of a certificate soon-to-expiry event:

cert-expiry

CA Injection

ValidatingWebhookConfiguration, MutatingWebhokConfiguration CustomResourceDefinition and APIService types of objects (and possibly in the future others) need the master API process to connect to trusted servers to perform their function. In order to do so over an encrypted connection, a CA bundle needs to be configured. In these objects the CA bundle is passed as part of the CR and not as a secret, and that is fine because the CA bundles are public info. However it may be difficult at deploy time to know what the correct CA bundle should be. Often the CA bundle needs to be discovered as a piece on information owned by some other objects of the cluster.

This feature allows you to inject the ca bundle from either a kubernetes.io/tls secret or from the service_ca.crt file mounted in every pod. The latter is useful if you are protecting your webhook with a certificate generated with the service service certificate secret feature.

This feature is activated by the following annotation:

  1. cert-utils-operator.redhat-cop.io/injectca-from-secret: <secret namespace>/<secret name>

In addition to those objects, it is also possible to inject ca bundles from secrets to secrets and configmaps:

  1. secrets: the secret must of type: kubernetes.io/tls. These types of secret must contain the tls.crt and tls.key keys, but is this case those keys are going to be presumably empty. So it is recommended to create these secrets as follows:
apiVersion: v1
kind: Secret
metadata:
  annotations:
    cert-utils-operator.redhat-cop.io/injectca-from-secret: test-cert-utils/test1
  name: test-inject-ca
  namespace: test-cert-utils
type: kubernetes.io/tls
stringData:
  tls.crt: ""
  tls.key: ""
  1. confimaps: the ca bundle will be injected in this key ca.crt, here is an example:
apiVersion: v1
kind: ConfigMap
metadata:
  annotations:
    cert-utils-operator.redhat-cop.io/injectca-from-secret: test-cert-utils/test1
  name: test-inject-ca-cm
  namespace: test-cert-utils

Projected volumes can be used to merge the caBundle with other pieces of configuration and or change the key name.

Metrics

Prometheus compatible metrics are exposed by the Operator and can be integrated into OpenShift's default cluster monitoring. To enable OpenShift cluster monitoring, label the namespace the operator is deployed in with the label openshift.io/cluster-monitoring="true".

oc label namespace <namespace> openshift.io/cluster-monitoring="true"

Testing metrics

export operatorNamespace=cert-utils-operator-local # or cert-utils-operator
oc label namespace ${operatorNamespace} openshift.io/cluster-monitoring="true"
oc rsh -n openshift-monitoring -c prometheus prometheus-k8s-0 /bin/bash
export operatorNamespace=cert-utils-operator-local # or cert-utils-operator
curl -v -s -k -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" https://cert-utils-operator-controller-manager-metrics.${operatorNamespace}.svc.cluster.local:8443/metrics
exit

Deploying the Operator

This is a cluster-level operator that you can deploy in any namespace, cert-utils-operator is recommended.

It is recommended to deploy this operator via OperatorHub, but you can also deploy it using Helm.

Multiarch Support

Arch Support
amd64
arm64
ppc64le
s390x

Deploying from OperatorHub

Note: This operator supports being installed disconnected environments

If you want to utilize the Operator Lifecycle Manager (OLM) to install this operator, you can do so in two ways: from the UI or the CLI.

Deploying from OperatorHub UI

  • If you would like to launch this operator from the UI, you'll need to navigate to the OperatorHub tab in the console. Before starting, make sure you've created the namespace that you want to install this operator to with the following:
oc new-project cert-utils-operator
  • Once there, you can search for this operator by name: cert utils operator. This will then return an item for our operator and you can select it to get started. Once you've arrived here, you'll be presented with an option to install, which will begin the process.
  • After clicking the install button, you can then select the namespace that you would like to install this to as well as the installation strategy you would like to proceed with (Automatic or Manual).
  • Once you've made your selection, you can select Subscribe and the installation will begin. After a few moments you can go ahead and check your namespace and you should see the operator running.

Cert Utils Operator

Deploying from OperatorHub using CLI

If you'd like to launch this operator from the command line, you can use the manifests contained in this repository by running the following:

oc new-project cert-utils-operator

oc apply -f config/operatorhub -n cert-utils-operator

This will create the appropriate OperatorGroup and Subscription and will trigger OLM to launch the operator in the specified namespace.

Deploying with Helm

Here are the instructions to install the latest release with Helm.

oc new-project cert-utils-operator
helm repo add cert-utils-operator https://redhat-cop.github.io/cert-utils-operator
helm repo update
helm install cert-utils-operator cert-utils-operator/cert-utils-operator

This can later be updated with the following commands:

helm repo update
helm upgrade cert-utils-operator cert-utils-operator/cert-utils-operator

Development

Running the operator locally

Note: this operator build process is tested with podman, but some of the build files (Makefile specifically) use docker because they are generated automatically by operator-sdk. It is recommended remap the docker command to the podman command.

export repo=raffaelespazzoli
docker login quay.io/$repo
oc new-project cert-utils-operator
oc project cert-utils-operator
oc label namespace cert-utils-operator openshift.io/cluster-monitoring="true"
envsubst < config/local-development/tilt/env-replace-image.yaml > config/local-development/tilt/replace-image.yaml
tilt up

Test helm chart locally

Define an image and tag. For example...

export imageRepository="quay.io/redhat-cop/cert-utils-operator"
export imageTag="$(git -c 'versionsort.suffix=-' ls-remote --exit-code --refs --sort='version:refname' --tags https://github.com/redhat-cop/cert-utils-operator.git '*.*.*' | tail --lines=1 | cut --delimiter='/' --fields=3)"

Deploy chart...

make helmchart IMG=${imageRepository} VERSION=${imageTag}
helm upgrade -i cert-utils-operator-local charts/cert-utils-operator -n cert-utils-operator-local --create-namespace

Delete...

helm delete cert-utils-operator-local -n cert-utils-operator-local
kubectl delete -f charts/cert-utils-operator/crds/crds.yaml

Building/Pushing the operator image

export repo=raffaelespazzoli #replace with yours
docker login quay.io/$repo
make docker-build IMG=quay.io/$repo/cert-utils-operator:latest
make docker-push IMG=quay.io/$repo/cert-utils-operator:latest

Deploy to OLM via bundle

make manifests
make bundle IMG=quay.io/$repo/cert-utils-operator:latest
operator-sdk bundle validate ./bundle --select-optional name=operatorhub
make bundle-build BUNDLE_IMG=quay.io/$repo/cert-utils-operator-bundle:latest
docker push quay.io/$repo/cert-utils-operator-bundle:latest
operator-sdk bundle validate quay.io/$repo/cert-utils-operator-bundle:latest --select-optional name=operatorhub
oc new-project cert-utils-operator
oc label namespace cert-utils-operator openshift.io/cluster-monitoring="true"
operator-sdk cleanup cert-utils-operator -n cert-utils-operator
operator-sdk run bundle --install-mode AllNamespaces -n cert-utils-operator quay.io/$repo/cert-utils-operator-bundle:latest

Releasing

git tag -a "<tagname>" -m "<commit message>"
git push upstream <tagname>

If you need to remove a release:

git tag -d <tagname>
git push upstream --delete <tagname>

If you need to "move" a release to the current main

git tag -f <tagname>
git push upstream -f <tagname>

Cleaning up

operator-sdk cleanup cert-utils-operator -n cert-utils-operator
oc delete operatorgroup operator-sdk-og
oc delete catalogsource cert-utils-operator-catalog

cert-utils-operator's People

Contributors

cnuland avatar davgordo avatar garethahealy avatar mathianasj avatar milosgajdos avatar ochienged avatar raffaelespazzoli avatar renovate[bot] avatar sabre1041 avatar trevorbox avatar vinzent avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cert-utils-operator's Issues

"level":"error","ts":1596025413.503453"

I am not sure if I can use this tool separately from operator-sdk.

However, after deploying with helm, I get Back-off restarting failed container error.
Logs:
{"level":"error","ts":1596025413.503453,"logger":"cmd","msg":"","error":"no such file or directory","stacktrace":"github.com/go-logr/zapr.(*zapLogger).Error\n\t/home/travis/gopath/pkg/mod/github.com/go-logr/[email protected]/zapr.go:128\nmain.main\n\t/home/travis/gopath/src/github.com/redhat-cop/cert-utils-operator/cmd/manager/main.go:146\nruntime.main\n\t/home/travis/.gimme/versions/go1.13.linux.amd64/src/runtime/proc.go:203"}

What should I do about that?

Refactor Duplicate Code

As we have added new controllers we have had a tendency to just copy-paste generic functions such as get ca from secret for instance. We should got back and pull out duplicate functionality and put it in the generalized util files for instance.

Duplicated CA certs cause "ExtendedValidationFailed"

Venafi issues a certificate which includes the CA cert in spec.tls.certificate. After enabling cert-utils-operator.redhat-cop.io/certs-from-secret on a route, it causes a validation error (ExtendedValidationFailed) since there are now two CA certs in the chain.

As a work round, we would have to manually disable cert-utils-operator.redhat-cop.io/certs-from-secret and remove spec.tls.caCertificate, then the route works fine.

cert-utils operator should either a) remove spec.tls.caCertificate if it exists or b) move the CA cert from spec.tls.certificate to spec.tls.caCertificate.

Operator will not start missing v1.CustomResourceDefinition

When I try to start the operator against a 4.3.13 cluster locally I get the following error

Manager exited non-zero","error":"no kind is registered for the type v1.CustomResourceDefinition in scheme "pkg/runtime/scheme.go:101

If I switch to register the v1 instead of v1beta1 it works.

Inject ca from configmap bundle

Instead of taking the approach to make the truststore for java in the configmap, which causes it to not work because you cannot store binary in a configmap (closes #52). This will allow to inject the ca bundle from the configmap and use the traditional way of creating the truststore.

no matches for kind CustomResourceDefinition

The operator is faling after deploy:

{"level":"info","ts":1592146919.6765954,"logger":"cmd","msg":"Go Version: go1.13"}
{"level":"info","ts":1592146919.6768084,"logger":"cmd","msg":"Go OS/Arch: linux/amd64"}
{"level":"info","ts":1592146919.6768417,"logger":"cmd","msg":"Version of operator-sdk: v0.16.0"}
{"level":"info","ts":1592146919.6770298,"logger":"leader","msg":"Trying to become the leader."}
{"level":"info","ts":1592146920.3141868,"logger":"leader","msg":"Found existing lock with my name. I was likely restarted."}
{"level":"info","ts":1592146920.3143566,"logger":"leader","msg":"Continuing as the leader."}
{"level":"info","ts":1592146920.9364574,"logger":"controller-runtime.metrics","msg":"metrics server is starting to listen","addr":"0.0.0.0:8383"}
{"level":"info","ts":1592146920.938475,"logger":"cmd","msg":"Registering Components."}
{"level":"info","ts":1592146920.9487975,"logger":"cmd","msg":"Starting the Cmd."}
{"level":"info","ts":1592146920.9498603,"logger":"controller-runtime.manager","msg":"starting metrics server","path":"/metrics"}
{"level":"info","ts":1592146920.9500117,"logger":"controller-runtime.controller","msg":"Starting EventSource","controller":"secretinfo_controller","source":"kind source: /, Kind=Secret"}
{"level":"info","ts":1592146920.9501426,"logger":"controller-runtime.controller","msg":"Starting EventSource","controller":"mutatingwebhookconfiguration-controller","source":"kind source: /, Kind=MutatingWebhookConfiguration"}
{"level":"info","ts":1592146920.9507418,"logger":"controller-runtime.controller","msg":"Starting EventSource","controller":"certexpiryalert_controller","source":"kind source: /, Kind=Secret"}
{"level":"info","ts":1592146920.95138,"logger":"controller-runtime.controller","msg":"Starting EventSource","controller":"secret_ca_injection_controller","source":"kind source: /, Kind=Secret"}
{"level":"info","ts":1592146920.9515507,"logger":"controller-runtime.controller","msg":"Starting EventSource","controller":"configmap-ca-injection-controller","source":"kind source: /, Kind=ConfigMap"}
{"level":"info","ts":1592146920.9517112,"logger":"controller-runtime.controller","msg":"Starting EventSource","controller":"webhook_ca_injection_controller","source":"kind source: /, Kind=ValidatingWebhookConfiguration"}
{"level":"info","ts":1592146920.951926,"logger":"controller-runtime.controller","msg":"Starting EventSource","controller":"secret_to_keystore_controller","source":"kind source: /, Kind=Secret"}
{"level":"info","ts":1592146920.9520652,"logger":"controller-runtime.controller","msg":"Starting EventSource","controller":"route_controller","source":"kind source: /, Kind=Route"}
{"level":"info","ts":1592146920.9521673,"logger":"controller-runtime.controller","msg":"Starting EventSource","controller":"crd_controller","source":"kind source: /, Kind=CustomResourceDefinition"}
{"level":"info","ts":1592146920.9527025,"logger":"controller-runtime.controller","msg":"Starting Controller","controller":"secretinfo_controller"}
{"level":"info","ts":1592146920.9527133,"logger":"controller-runtime.controller","msg":"Starting Controller","controller":"certexpiryalert_controller"}
{"level":"info","ts":1592146920.9527533,"logger":"controller-runtime.controller","msg":"Starting Controller","controller":"secret_to_keystore_controller"}
{"level":"info","ts":1592146920.9529667,"logger":"controller-runtime.controller","msg":"Starting EventSource","controller":"configmap-ca-injection-controller","source":"kind source: /, Kind=secret"}
{"level":"info","ts":1592146920.952994,"logger":"controller-runtime.controller","msg":"Starting EventSource","controller":"secret_ca_injection_controller","source":"kind source: /, Kind=Secret"}
{"level":"error","ts":1592146923.021014,"logger":"controller-runtime.source","msg":"if kind is a CRD, it should be installed before calling Start","kind":"CustomResourceDefinition.apiextensions.k8s.io","error":"no matches for kind \"CustomResourceDefinition\" in version \"apiextensions.k8s.io/v1\"","stacktrace":"github.com/go-logr/zapr.(*zapLogger).Error\n\t/home/travis/gopath/pkg/mod/github.com/go-logr/[email protected]/zapr.go:128\nsigs.k8s.io/controller-runtime/pkg/source.(*Kind).Start\n\t/home/travis/gopath/pkg/mod/sigs.k8s.io/[email protected]/pkg/source/source.go:88\nsigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).Start.func1\n\t/home/travis/gopath/pkg/mod/sigs.k8s.io/[email protected]/pkg/internal/controller/controller.go:165\nsigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).Start\n\t/home/travis/gopath/pkg/mod/sigs.k8s.io/[email protected]/pkg/internal/controller/controller.go:198\nsigs.k8s.io/controller-runtime/pkg/manager.(*controllerManager).startLeaderElectionRunnables.func1\n\t/home/travis/gopath/pkg/mod/sigs.k8s.io/[email protected]/pkg/manager/internal.go:477"}
{"level":"error","ts":1592146923.02135,"logger":"cmd","msg":"Manager exited non-zero","error":"no matches for kind \"CustomResourceDefinition\" in version \"apiextensions.k8s.io/v1\"","stacktrace":"github.com/go-logr/zapr.(*zapLogger).Error\n\t/home/travis/gopath/pkg/mod/github.com/go-logr/[email protected]/zapr.go:128\nmain.main\n\t/home/travis/gopath/src/github.com/redhat-cop/cert-utils-operator/cmd/manager/main.go:135\nruntime.main\n\t/home/travis/.gimme/versions/go1.13.linux.amd64/src/runtime/proc.go:203"}

Automate Helm Chart Templates

I would like to automate a process where you can generate the helm chart templates from the contents of the deploy folder

Improve docs to better describe how the CA Injector works with CRDs

It is not clear in the docs how the CA Injector works with CRDs? For the Webhooks, it is clear the injection is done to the WebhookClientConfig.caBundle. This is not the case for CRDs. How is the CA Injector intended to work with CRDs?

I would like to use the CA Injector with Rook/Ceph RGW as briefly described here: rook/rook#3016 (comment). My client application intends to use an ObjectBucketClaim to interact with an SSL-enabled Rook/Ceph RGW S3 endpoint. I would like to use the CA Injector to get the CABundle from the rook-ceph-rgw-cert Secret. Of course my client runs in a different namespace from rook-ceph. My client app is operator-managed and has a CR. I would like to inject the CA bundle somewhere where it is accessible to either my operator or my client app. How is this intended to work?

Note my client app is written in Java so I would also like to use the cert-utils-operator to convert the injected CA bundle into a truststore.jks. Have you considered such a use case in your design? I was thinking my operator could put the injected CA bundle into a kubernetes.io/tls secret with the cert-utils-operator.redhat-cop.io/generate-java-keystores: "true" annotation in order to make it available as a truststore.jks. Thoughts?

'ca.crt' is removed from 'kubernetes.io/tls' secret after a while

I have cert-manager deployed in latest 1.0.3 version in Openshift 3.11, I deployed also cert-utils-operator in version 0.1.0 - newer versions do not work unfortunately in this environment (it would be good to look at it).
So having cert utils operator in place while creating a new certificate from self-signed Issuer I can see 3 keys there, so: tls.key, tls.crt and ca.crt. After a few minutes, the related Secret is updated and ca.crt is removed completely which is not good as it is useless later in my use case.
I found cert utils operator is somehow responsible for this because when I remove it then this does not happen anymore later.
I tried to use newer operator versions but it is not possible in Openshift 3.11 as they do not work.

Java truststore only adds last ca bundle entry

The java truststore creation only adds the last entry in a ca bundle file to the jks truststore. I found where the issue is the counter to increment the alias never gets incremented and always adds to the 0 key. I should have a PR shortly to resolve the issue.

re-enable ca injection tests

cert-manager seems to not be creating the ca.crt entries for generated certificates.
some of the ca injection test.
We need to come up with another mechanism to populate the ca.crt field. Or alternatively understand if the upstream convention for ca.crt has changed.

cert-utils-operator will not insert destinationCACertificate in a Route managed by openshift-controller-manager

I have an issue where I need an Ingress with reencrypt (with a cert-manager issued certificate) however this mandates the presence of destinationCACertificate in the Route that openshift-controller-manager will create since there is no way to specify this CA in the Ingress (see openshift/openshift-controller-manager#153 ) I wanted to test injecting the destinationCACertificate using cert-utils-operator.
This however does not work at all, silently doing nothing, and sometimes logging a Warning about concurrent modifications of the object like this:

2021-08-24T16:54:03.391Z	DEBUG	controller-runtime.manager.events	Warning	{"object": {"kind":"Route","namespace":"vault","name":"vault-test","uid":"ef41618e-2990-46c3-97e3-1e346fc76a59","apiVersion":"route.openshift.io/v1","resourceVersion":"319883959"}, "reason": "ProcessingError", "message": "Operation cannot be fulfilled on routes.route.openshift.io \"vault-test\": the object has been modified; please apply your changes to the latest version and try again"}

For completeness I put here all the objects involved:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    banzaicloud.com/last-applied: <redacted>
    cert-manager.io/cluster-issuer: freeipa-acme
    cert-utils-operator.redhat-cop.io/destinationCA-from-secret: vault-tls-2
    cert-utils-operator.redhat-cop.io/inject-CA: "true"
    ingress.kubernetes.io/protocol: https
    ingress.kubernetes.io/secure-backends: "true"
    kubernetes.io/tls-acme: "true"
    nginx.ingress.kubernetes.io/backend-protocol: HTTPS
    route.openshift.io/termination: reencrypt
  creationTimestamp: "2021-08-21T12:14:39Z"
  generation: 2
  labels:
    app.kubernetes.io/name: vault
    vault_cr: vault
  managedFields:
  - apiVersion: networking.k8s.io/v1
    fieldsType: FieldsV1
    fieldsV1:
      f:metadata:
        f:annotations:
          .: {}
          f:banzaicloud.com/last-applied: {}
          f:cert-manager.io/cluster-issuer: {}
          f:cert-utils-operator.redhat-cop.io/inject-CA: {}
          f:ingress.kubernetes.io/protocol: {}
          f:ingress.kubernetes.io/secure-backends: {}
          f:kubernetes.io/tls-acme: {}
          f:nginx.ingress.kubernetes.io/backend-protocol: {}
          f:route.openshift.io/termination: {}
        f:labels:
          .: {}
          f:app.kubernetes.io/name: {}
          f:vault_cr: {}
        f:ownerReferences:
          .: {}
          k:{"uid":"66c053c5-bb4a-40b6-b4f3-da923539f4e8"}:
            .: {}
            f:apiVersion: {}
            f:blockOwnerDeletion: {}
            f:controller: {}
            f:kind: {}
            f:name: {}
            f:uid: {}
      f:spec:
        f:rules: {}
        f:tls: {}
    manager: vault-operator
    operation: Update
    time: "2021-08-24T16:50:49Z"
  - apiVersion: networking.k8s.io/v1
    fieldsType: FieldsV1
    fieldsV1:
      f:metadata:
        f:annotations:
          f:cert-utils-operator.redhat-cop.io/destinationCA-from-secret: {}
    manager: oc
    operation: Update
    time: "2021-08-24T16:50:59Z"
  name: vault
  namespace: vault
  ownerReferences:
  - apiVersion: vault.banzaicloud.com/v1alpha1
    blockOwnerDeletion: true
    controller: true
    kind: Vault
    name: vault
    uid: 66c053c5-bb4a-40b6-b4f3-da923539f4e8
  resourceVersion: "319882336"
  selfLink: /apis/networking.k8s.io/v1/namespaces/vault/ingresses/vault
  uid: 74f39dc2-b146-4043-af47-54e3ab76ac17
spec:
  rules:
  - host: vault.apps.okd4.os.aelia.ch
    http:
      paths:
      - backend:
          service:
            name: vault
            port:
              name: api-port
        path: /
        pathType: ImplementationSpecific
  tls:
  - hosts:
    - vault.apps.okd4.os.aelia.ch
    secretName: vault-ui-certificate
status:
  loadBalancer:
    ingress:
    - hostname: apps.okd4.os.aelia.ch
apiVersion: v1
data:
  ca.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURhekNDQWxPZ0F3SUJBZ0lRZUhFUUhMMGtrNW1zbk1LQnJJVFpyekFOQmdrcWhraUc5dzBCQVFzRkFEQkEKTVJVd0V3WURWUVFLRXd4Q1lXNTZZV2tnUTJ4dmRXUXhKekFsQmdOVkJBTVRIa0poYm5waGFTQkRiRzkxWkNCSApaVzVsY21GMFpXUWdVbTl2ZENCRFFUQWVGdzB5TVRBNE1qRXhNakUwTXpGYUZ3MHlNakE0TWpFeE1qRTBNekZhCk1FQXhGVEFUQmdOVkJBb1RERUpoYm5waGFTQkRiRzkxWkRFbk1DVUdBMVVFQXhNZVFtRnVlbUZwSUVOc2IzVmsKSUVkbGJtVnlZWFJsWkNCU2IyOTBJRU5CTUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQwpBUUVBc1hUZ1BCWEhqczNVRThjUnBFaGNtYzBIbnRNMHJvQ3o2d3ZWam9TYzQrQnU1S095MmMrTVVhYlBOQllsCk4wMko3ZDJabnoyU3dKa2R6aERMczBQWFVDcCtaTGpQcnZ0MFkyNVJDM2JMVEZUeXBGQy9qUDVoQS9Yd01wb00KbUpNeW4zcCtOdm9vSW00ZjdiODdPRE5FSzVjYVBzbEV2b2Y2bUNkWVdNOW5xdkROK1ZCZnJseFFjRDVFUG1POAo4STFWZTNMQ1o5MU5qcFBIcUVtRFAxbnU4b1dlYUZONnRZREN3Kzh1UVBhY3JGQ2kvOHdEVHljWk5wRktwQ1BmCkdYNDlYWjFTVWJSdFhKVmZaY3dwYU1zaUpzcWxzbDljM09WemdXaml5OVB5cXRsUkkva0RWM2ZaNGVRMjZydC8KZ25IL0JIY3M1aHIwYm5vbkIyMDNCdnFXNlFJREFRQUJvMkV3WHpBT0JnTlZIUThCQWY4RUJBTUNBZ1F3SFFZRApWUjBsQkJZd0ZBWUlLd1lCQlFVSEF3RUdDQ3NHQVFVRkJ3TUNNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdIUVlEClZSME9CQllFRkR2cFhUUkR6cFA3VGtBcFpoSUlKTXEwZ1p0L01BMEdDU3FHU0liM0RRRUJDd1VBQTRJQkFRQUMKSkE3c0hYdnJacEVlTUM5TjJBdmxjVW00eGRCTHV3VGVLdzg3ZW5PZXVkcFRjMkJkWE9qdGtMdzNJZXZPVCswVQpMUTlOZVhpM3duRHMra3FGYjBCM3pYakFDclFaT0RhdTZncElhbXo1R2IyN0YvL29rQTgrTkZwMDh1U2NBTkV5Cjhlb3Fka0RlNEtucHZMbmFld1haejgwK1JRdGhmT1RPR2krUW93QlpmZnNDTVpQQmVjdjRXRnU1c0FEWjFuTWsKL2hNZ3Uwc0F4Q2dIYTF6bnJlQkZVWis2SVFIZVR1eDBUN0xoWEZTSFZ0ajNWRlFaK2ordkdYaHNIWjhZVTc5KwpVTFBLK1oyY1BzclQxVGU0NWVWbC9saEd1emNxRjc3QjhBOS93RGFXeE5ZT1MwRFR4L1d6NFJpdHVIRUdoZk5lClBsM0xodmg3bXlseTB0MmRNYnR0Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
  tls.crt: ""
  tls.key: ""
kind: Secret
metadata:
  creationTimestamp: "2021-08-24T16:41:27Z"
  managedFields:
  - apiVersion: v1
    fieldsType: FieldsV1
    fieldsV1:
      f:data:
        .: {}
        f:ca.crt: {}
        f:tls.crt: {}
        f:tls.key: {}
      f:type: {}
    manager: oc
    operation: Update
    time: "2021-08-24T16:41:27Z"
  name: vault-tls-2
  namespace: vault
  resourceVersion: "319876995"
  selfLink: /api/v1/namespaces/vault/secrets/vault-tls-2
  uid: 45aa8d74-e3e5-4492-8a23-87b413eb2f3e
type: kubernetes.io/tls

The final route:

items:
- apiVersion: route.openshift.io/v1
  kind: Route
  metadata:
    annotations:
      banzaicloud.com/last-applied: <redacted>
      cert-manager.io/cluster-issuer: freeipa-acme
      cert-utils-operator.redhat-cop.io/destinationCA-from-secret: vault-tls-2
      cert-utils-operator.redhat-cop.io/inject-CA: "true"
      ingress.kubernetes.io/protocol: https
      ingress.kubernetes.io/secure-backends: "true"
      kubernetes.io/tls-acme: "true"
      nginx.ingress.kubernetes.io/backend-protocol: HTTPS
      route.openshift.io/termination: reencrypt
    creationTimestamp: "2021-08-24T16:31:07Z"
    labels:
      app.kubernetes.io/name: vault
      vault_cr: vault
    managedFields:
    - apiVersion: route.openshift.io/v1
      fieldsType: FieldsV1
      fieldsV1:
        f:status:
          f:ingress: {}
      manager: openshift-router
      operation: Update
      time: "2021-08-24T16:31:07Z"
    - apiVersion: route.openshift.io/v1
      fieldsType: FieldsV1
      fieldsV1:
        f:metadata:
          f:annotations:
            .: {}
            f:banzaicloud.com/last-applied: {}
            f:cert-manager.io/cluster-issuer: {}
            f:cert-utils-operator.redhat-cop.io/destinationCA-from-secret: {}
            f:cert-utils-operator.redhat-cop.io/inject-CA: {}
            f:ingress.kubernetes.io/protocol: {}
            f:ingress.kubernetes.io/secure-backends: {}
            f:kubernetes.io/tls-acme: {}
            f:nginx.ingress.kubernetes.io/backend-protocol: {}
            f:route.openshift.io/termination: {}
          f:labels:
            .: {}
            f:app.kubernetes.io/name: {}
            f:vault_cr: {}
          f:ownerReferences:
            .: {}
            k:{"uid":"74f39dc2-b146-4043-af47-54e3ab76ac17"}:
              .: {}
              f:apiVersion: {}
              f:controller: {}
              f:kind: {}
              f:name: {}
              f:uid: {}
        f:spec:
          f:host: {}
          f:path: {}
          f:port:
            .: {}
            f:targetPort: {}
          f:tls:
            .: {}
            f:certificate: {}
            f:insecureEdgeTerminationPolicy: {}
            f:key: {}
            f:termination: {}
          f:to:
            f:kind: {}
            f:name: {}
            f:weight: {}
          f:wildcardPolicy: {}
      manager: openshift-controller-manager
      operation: Update
      time: "2021-08-24T16:51:06Z"
    name: vault-tg98b
    namespace: vault
    ownerReferences:
    - apiVersion: networking.k8s.io/v1beta1
      controller: true
      kind: Ingress
      name: vault
      uid: 74f39dc2-b146-4043-af47-54e3ab76ac17
    resourceVersion: "319882339"
    uid: 6351aeb6-eb4f-4527-9fd8-071c00a392ce
  spec:
    host: vault.apps.okd4.os.aelia.ch
    path: /
    port:
      targetPort: api-port
    tls:
      certificate: <redacted>
      insecureEdgeTerminationPolicy: Redirect
      key: <redacted>
      termination: reencrypt
    to:
      kind: Service
      name: vault
      weight: 100
    wildcardPolicy: None
  status:
    ingress:
    - conditions:
      - lastTransitionTime: "2021-08-24T16:31:07Z"
        status: "True"
        type: Admitted
      host: vault.apps.okd4.os.aelia.ch
      routerCanonicalHostname: apps.okd4.os.aelia.ch
      routerName: default
      wildcardPolicy: None
kind: List
metadata:
  resourceVersion: ""
  selfLink: ""

If I create a route myself with the same annotations, the destinationCACertificate is updated example:

apiVersion: route.openshift.io/v1
kind: Route
metadata:
  annotations:
    banzaicloud.com/last-applied:  <redacted>
    cert-utils-operator.redhat-cop.io/destinationCA-from-secret: vault-tls-2
    cert-utils-operator.redhat-cop.io/inject-CA: "true"
    cert-manager.io/cluster-issuer: freeipa-acme
    kubernetes.io/tls-acme: "true"
    ingress.kubernetes.io/protocol: https
    ingress.kubernetes.io/secure-backends: "true"
    nginx.ingress.kubernetes.io/backend-protocol: HTTPS
    route.openshift.io/termination: reencrypt
  name: vault-test
  namespace: vault
spec:
  host: test.apps.okd4.os.aelia.ch
  path: /
  port:
    targetPort: api-port
  tls:
    insecureEdgeTerminationPolicy: Redirect
    termination: reencrypt
  to:
    kind: Service
    name: vault
    weight: 100
  wildcardPolicy: None

configmap injection seems to be generating a large number of events

investigate why configmap injection controller seems to be receiving an unlimited number of events.
when adding logs to the event filter:

	isAnnotatedConfigMap := predicate.Funcs{
		UpdateFunc: func(e event.UpdateEvent) bool {
			oldSecret, _ := e.MetaOld.GetAnnotations()[certAnnotationSecret]
			newSecret, _ := e.MetaNew.GetAnnotations()[certAnnotationSecret]
			log.V(1).Info("update func", "config map", e.MetaNew.GetName(), "annotation old", oldSecret, "annotation new", newSecret)
			return oldSecret != newSecret
		},
		CreateFunc: func(e event.CreateEvent) bool {
			_, ok1 := e.Meta.GetAnnotations()[certAnnotationSecret]
			log.V(1).Info("create func", "config map", e.Meta.GetName(), "has annotation", ok1)
			return ok1
		},
	}

the operator seems to be entering an infinite loop in which all it does is printing those statements and discard the event.

Opaque secrets

It would be beneficial to have the cert-utils-operator to inject a JKS from an Opaque secret. Here's the use case:

  1. Deploy Elastic Cloud for Kubernetes (ECK) Operator into the cluster
  2. Create a CR elasticsearch.k8s.elastic.co/v1/elasticsearch named nxelastic
  3. ECK Operator creates an ElasticSearch cluster and also creates opaque secret named nxelastic-es-http-certs-public
  4. Create a secret my-elasticsearch-binding annotated to have cert-utils-operator inject the CA from nxelastic-es-http-certs-public into it
  5. Mount secret my-elasticsearch-binding into a Deployment that runs a Java app to allow that deployment to connect to ElasticSearch using TLS

It appears based on the README - "Certificates are assumed to be available in a secret of type kubernetes.io/tls (other types of secrets are ignored by this operator)" - and experimentation - that this use case is intentionally not supported. Do you see a benefit from implementing this capability?

Automatic upgrade to 1.0.6 failing

Upgrading from 1.0.5 via automatic strategy seems to be failing. Relevant event is:

install strategy failed: Deployment.apps "cert-utils-operator-controller-manager" is invalid: spec.selector: Invalid value: v1.LabelSelector{MatchLabels:map[string]string{"operator":"cert-utils-operator"}, MatchExpressions:[]v1.LabelSelectorRequirement(nil)}: field is immutable

no error posted to route

I just installed the cert-manager along with the cert-utils-operator and received field is immutable, spec.tls.key: Invalid value: when the cert-utils-operator and was trying to attach the certificate.

I went into the route to see if there was an error message attached to some metadata but my route was left in the same state as before. Basically, this just leaves the operator in a constant state of looking at my route annotation and trying to apply the cert to the route.

Use of PrometheusRule for "Certificate soon to expire event" to create OpenShift Altert would be great

Thanks for this operator. Did not yet check all features but those I tried since yesterday work as documented! :)

I especially like the feature to be informed if a certificiate is soon to expire.

However, on a large platform with a lot of projects/namespaces it is not really practical to manually look into the project to see the "soon to expire events". It is possible to create a job which sends an email to alert somebody based on "oc get events" of course. However, it would be perfect if a metric would be available that can be used for a PrometheusRule and send the Alter via the OpenShift Cluster Monitoring (Alertmanager).

I searched vi Google to find a way to get an Alert for a Kubernetes Event but didn't find a solution yet.
It seems that we have to go the Job-way. Anyway, better than implementing a solution on our own.

cert-utils-operator cannot list routes at cluster scope

Hi,

I have deployed the cert-operator. However, I am getting a constant error like this below.

sigs.k8s.io/controller-runtime/pkg/cache/internal/informers_map.go:126: Failed to list *v1.Route: routes.route.openshift.io is forbidden: User "system:serviceaccount:cert-manager:cert-utils-operator" cannot list routes.route.openshift.io at the cluster scope: User "system:serviceaccount:cert-manager:cert-utils-operator" cannot list all routes.route.openshift.io in the cluster

Some outputs:

$ oc get sa cert-utils-operator
NAME                  SECRETS   AGE
cert-utils-operator   2         3h

$ oc get role
NAME
cert-utils-operator

$ oc get rolebinding cert-utils-operator
NAME                  ROLE                               USERS     GROUPS    SERVICE ACCOUNTS      SUBJECTS
cert-utils-operator   cert-manager/cert-utils-operator                       cert-utils-operator 

Broken in OpenShift 4.5

We were using this wonderful operator to automatically inject TLS certs generated by cert- manager into routes, but after upgrade to 4.5 we started noticing the following errors in the logs:

E0729 15:30:02.323442       1 reflector.go:178] pkg/mod/k8s.io/[email protected]/tools/cache/reflector.go:125: Failed to list *v1.APIService: apiservices.apiregistration.k8s.io is forbidden: User "system:serviceaccount:cert-utils-operator:cert-utils-operator" cannot list resource "apiservices" in API group "apiregistration.k8s.io" at the cluster scope
E0729 15:30:23.831148       1 reflector.go:178] pkg/mod/k8s.io/[email protected]/tools/cache/reflector.go:125: Failed to list *v1.APIService: apiservices.apiregistration.k8s.io is forbidden: User "system:serviceaccount:cert-utils-operator:cert-utils-operator" cannot list resource "apiservices" in API group "apiregistration.k8s.io" at the cluster scope

We install the operator using Helm chart, I think it's missing the following rules in the clusterrole:

- apiGroups:
  - apiregistration.k8s.io
  resources:
  - apiservices
  verbs:
  - '*'

Possibly with fine-tuned verbs.

Artifacthub

Folks - do you have plans to publish your Helm chart on ArtifactHub?

ability to inject ca_bundles from configmap

ca_bundles are public info and there is a trend now make them available in configmaps rather than secrets. Cert-uitls should support injecting ca_bundles from configmaps.
A single configmap to secret injector should suffice as all other injector support secret as source.

Race Condition with Secrets

When you have a secret that includes a CA entry there is no check to make sure it is annotated on update events.

oc apply without clone

If you cut a release, it would be nice to deploy the cert-utils-operator without cloning the repo... something like oc apply --validate=false -f https://github.com/redhat-cop/cert-utils-operator/releases/download/v0.1.0/cert-manager-utils.yaml

Invalid secret name causes crash

If you do not specify a secret with namespace/secret the controller will crash.

E0427 14:40:52.174434 56565 runtime.go:78] Observed a panic: runtime.boundsError{x:-1, y:8, signed:true, code:0x1} (runtime error: slice bounds out of range [:-1])

Base image need to be updated or Rebuild from latest need to be updated on Quay.

source: quay.io/redhat-cop/cert-utils-operator:latest
Quay Security Scanner has detected 52 vulnerabilities.
Patches are available for 52 vulnerabilities.
8 High vulnerabilities.
33 Medium vulnerabilities.
11 Low vulnerabilities.

Its also affecting OCP operator provide in OCP 4.5.11
Container security is flagging the image.

That would be interesting to receive an email or webhook from Quay when scanner detect CVE.

Latest version of cert-utils-operator does not support OpenShift 3.11

With the change from 0.1.0 to 0.1.1, the cert-utils-operator does not support OpenShift 3.11. The operator uses k8s.io/appextensions-apiserver/pkg/apis/apiextensions/v1. But:

$ oc version
oc v3.11.188
kubernetes v1.11.0
openshift v3.11.146

And

$ oc api-versions | grep apie
apiextensions.k8s.io/v1beta1

Do you see value in supporting the v1 CRD as well as the v1beta1 CRD for OpenShift 3.11 compatibility. If not, users can only use cert-utils-operator v0.1.0 until they upgrade their OpenShift cluster.

Cert utils operator cannot list apiservices SA

Steps to reproduce
Installation from helm as readme reflects

What's the issue

User "system:serviceaccount:cert-utils-operator:cert-utils-operator" cannot list resource "apiservices" in API group "apiregistration.k8s.io" at the cluster scope

oc logs -f --tail=10 cert-utils-operator-fbbfb578d-grlqm -n cert-utils-operator
{"level":"info","ts":1596735297.409486,"logger":"controller-runtime.controller","msg":"Starting EventSource","controller":"webhook_ca_injection_controller","source":"kind source: /, Kind=secret"}
{"level":"info","ts":1596735297.4096828,"logger":"controller-runtime.controller","msg":"Starting EventSource","controller":"mutatingwebhookconfiguration-controller","source":"kind source: /, Kind=Secret"}
{"level":"info","ts":1596735297.6113288,"logger":"controller-runtime.controller","msg":"Starting Controller","controller":"certexpiryalert_controller"}
{"level":"info","ts":1596735297.6128588,"logger":"controller-runtime.controller","msg":"Starting Controller","controller":"secretinfo_controller"}
{"level":"info","ts":1596735297.614202,"logger":"controller-runtime.controller","msg":"Starting Controller","controller":"secret_to_keystore_controller"}
{"level":"info","ts":1596735297.6157625,"logger":"controller-runtime.controller","msg":"Starting EventSource","controller":"secret_ca_injection_controller","source":"kind source: /, Kind=Secret"}
E0806 17:34:58.661664       1 reflector.go:178] pkg/mod/k8s.io/[email protected]/tools/cache/reflector.go:125: Failed to list *v1.APIService: apiservices.apiregistration.k8s.io is forbidden: User "system:serviceaccount:cert-utils-operator:cert-utils-operator" cannot list resource "apiservices" in API group "apiregistration.k8s.io" at the cluster scope
{"level":"error","ts":1596735299.3580818,"logger":"controller-runtime.source","msg":"if kind is a CRD, it should be installed before calling Start","kind":"CustomResourceDefinition.apiextensions.k8s.io","error":"no matches for kind \"CustomResourceDefinition\" in version \"apiextensions.k8s.io/v1\"","stacktrace":"github.com/go-logr/zapr.(*zapLogger).Error\n\t/home/travis/gopath/pkg/mod/github.com/go-logr/[email protected]/zapr.go:128\nsigs.k8s.io/controller-runtime/pkg/source.(*Kind).Start\n\t/home/travis/gopath/pkg/mod/sigs.k8s.io/[email protected]/pkg/source/source.go:105\nsigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).Start.func1\n\t/home/travis/gopath/pkg/mod/sigs.k8s.io/[email protected]/pkg/internal/controller/controller.go:165\nsigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).Start\n\t/home/travis/gopath/pkg/mod/sigs.k8s.io/[email protected]/pkg/internal/controller/controller.go:198\nsigs.k8s.io/controller-runtime/pkg/manager.(*controllerManager).startLeaderElectionRunnables.func1\n\t/home/travis/gopath/pkg/mod/sigs.k8s.io/[email protected]/pkg/manager/internal.go:514"}
{"level":"error","ts":1596735299.3581717,"logger":"cmd","msg":"Manager exited non-zero","error":"no matches for kind \"CustomResourceDefinition\" in version \"apiextensions.k8s.io/v1\"","stacktrace":"github.com/go-logr/zapr.(*zapLogger).Error\n\t/home/travis/gopath/pkg/mod/github.com/go-logr/[email protected]/zapr.go:128\nmain.main\n\t/home/travis/gopath/src/github.com/redhat-cop/cert-utils-operator/cmd/manager/main.go:157\nruntime.main\n\t/home/travis/.gimme/versions/go1.13.linux.amd64/src/runtime/proc.go:203"}
{"level":"error","ts":1596735299.3581867,"logger":"controller-runtime.controller","msg":"Could not wait for Cache to sync","controller":"secretinfo_controller","error":"failed to wait for secretinfo_controller caches to sync","stacktrace":"github.com/go-logr/zapr.(*zapLogger).Error\n\t/home/travis/gopath/pkg/mod/github.com/go-logr/[email protected]/zapr.go:128\nsigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).Start.func1\n\t/home/travis/gopath/pkg/mod/sigs.k8s.io/[email protected]/pkg/internal/controller/controller.go:181\nsigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).Start\n\t/home/travis/gopath/pkg/mod/sigs.k8s.io/[email protected]/pkg/internal/controller/controller.go:198\nsigs.k8s.io/controller-runtime/pkg/manager.(*controllerManager).startLeaderElectionRunnables.func1\n\t/home/travis/gopath/pkg/mod/sigs.k8s.io/[email protected]/pkg/manager/internal.go:514"}

specify java keystore filename

Would like to see the ability to specify the filename of the java keystore, some operators require a custom filename this would be beneficial for consumption in such cases.

Java Truststore from ConfigMap

I would like to be able to generate a java truststore from a configmap so I can utilize the "config.openshift.io/inject-trusted-cabundle" label. This will enable me to consume the ca trusts that are configured at a cluster level for an environment and pass them on to Java applications and remove the need to create custom images for trust.

add support for ca injection

ca_bundles are used by ValidatingAdmissionWebhook and MutatingAdmissionWebhook (and other objects potentially).
ca_bundles are difficult to discover (ironically given that they are public info), and when creating template force ugly solutions.
this injector should allow to annotate a webhook and let the operator discover the ca_bundle and inject it into the right field.
Two discovery modes are supported:

  1. service serving certificate ca bundle. this is the OCP system-wide ca_bundle for certificate created with the service_ca
  2. tls secret. If certificates are created in some other way, then the expectation is that the ca_bundle will be in the ca.crt field of a tls secret.

Populating route certificates from secrets in another namespace

Hi, I was looking trough the documentation to setup cert manager with let's encrypt on a openshift cluster and I came across this operator. I have a situation where I need to create a wildcard Let's encrypt certificate and use it in routes defined in 4-5 namespaces.

I saw that the annotation cert-utils-operator.redhat-cop.io/certs-from-secret: "<secret-name>" can load from a secret and that functionality works very well but cannot load the secret from another namespace as it assumes it to be in the same namespace as the route,

I saw that this is possibile for the annotation cert-utils-operator.redhat-cop.io/injectca-from-secret: <secret namespace>/<secret name>.

Is this a limitation or a necessary choice due to the way kubernetes work or the operator could be modified to allow it to specify a namespace for the secrets?

Refactor file watching

Right now we have almost copy/paste duplication of the file watcher for the systemCAFilename in

apiservice_controller.go
customresourcedefinition_controller.go
mutatingwebhookconfiguration_controller.go
validationwebhookconfiguration_controller.go

I would like to see this functionality abstracted out of these files and placed in a shared location.

Documentation error

This LINE shows the command:

export cert_utils_chart_version=$(helm search cert-utils-operator/cert-utils-operator | grep cert-utils-operator/cert-utils-operator | awk '{print $2}')

But the command is missing an argument and needs to be changed to:

export cert_utils_chart_version=$(helm search repo cert-utils-operator/cert-utils-operator | grep cert-utils-operator/cert-utils-operator | awk '{print $2}')

The helm search needs the repo argument with Helm v3.1.2

injectca-from-service_ca not working for configmaps

Hi,
I'm trying to generate configmap with a truststore containing the ocp service ca and the injectca-from-service_ca doesn't seem to be working.
I'm using the following configmap :

apiVersion: v1
kind: ConfigMap
metadata:
  annotations:
    cert-utils-operator.redhat-cop.io/injectca-from-service_ca: "true"
    cert-utils-operator.redhat-cop.io/generate-java-truststore: "true"
  name: test-inject-ca-cm3

Upon creation the comfigmap is empty with neither the certs or the truststore present.

Conflict when installing cert-utils-operator with other redhat-cop operators ?

I've noticed that having this operator installed with other redhat-cop operators like https://github.com/redhat-cop/resource-locker-operator in the same cluster is causing problems to OLM. The other operators seems to be stuck in Pending state.
Maybe because the SA used is default ? I've noticed that this issue doesn't happen with https://github.com/redhat-cop/namespace-configuration-operator since some days ago the have changed the SA name.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.