Coder Social home page Coder Social logo

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

View Code? Open in Web Editor NEW
92.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 Issues

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])

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.

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.

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.

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.

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.

'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.

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

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

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

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

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.

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?

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.

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.

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.

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.

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.

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

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.

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"}

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.

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.

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.

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?

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 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 

"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?

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?

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.

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.

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.

Artifacthub

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

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.

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.