Skip to content

Commit

Permalink
Merge pull request #29 from ctrought/feat-subject-annotations
Browse files Browse the repository at this point in the history
Additional support for subject annotations
  • Loading branch information
jetstack-bot committed Jan 25, 2024
2 parents 950aeac + e1cc7e6 commit 5b9f2b3
Show file tree
Hide file tree
Showing 5 changed files with 594 additions and 49 deletions.
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,15 @@ metadata:
cert-manager.io/uri-sans: "spiffe://trustdomain/workload" # Optional, no default
cert-manager.io/private-key-algorithm: "ECDSA" # Optional, defaults to RSA
cert-manager.io/private-key-size: "384" # Optional, defaults to 265 for ECDSA and 2048 for RSA
cert-manager.io/email-sans: "me@example.com,you@example.com" # Optional, no default
cert-manager.io/subject-organizations: "company" # Optional, no default
cert-manager.io/subject-organizationalunits: "company division" # Optional, no default
cert-manager.io/subject-countries: "My Country" # Optional, no default
cert-manager.io/subject-provinces: "My Province" # Optional, no default
cert-manager.io/subject-localities: "My City" # Optional, no default
cert-manager.io/subject-postalcodes: "123ABC" # Optional, no default
cert-manager.io/subject-streetaddresses: "1 Example St" # Optional, no default
cert-manager.io/subject-serialnumber: "123456" # Optional, no default
spec:
host: app.service.clustername.domain.com # will be added to the Subject Alternative Names of the CertificateRequest
port:
Expand Down
34 changes: 29 additions & 5 deletions internal/controller/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,30 @@ type Route struct {
log logr.Logger
}

func shouldSync(log logr.Logger, route *routev1.Route) bool {
if len(route.ObjectMeta.OwnerReferences) > 0 {
for _, o := range route.ObjectMeta.OwnerReferences {
if o.Kind == "Ingress" {
log.V(5).Info("Route is owned by an Ingress")
return false
}
}
}

if metav1.HasAnnotation(route.ObjectMeta, cmapi.IssuerNameAnnotationKey) {
log.V(5).Info("Route has the annotation %s=%s", cmapi.IssuerNameAnnotationKey, route.Annotations[cmapi.IssuerNameAnnotationKey])
return true
}

if metav1.HasAnnotation(route.ObjectMeta, cmapi.IngressIssuerNameAnnotationKey) {
log.V(5).Info("Route has the annotation %s=%s", cmapi.IngressIssuerNameAnnotationKey, route.Annotations[cmapi.IngressIssuerNameAnnotationKey])
return true
}

log.V(5).Info("Route does not have the cert-manager issuer annotation")
return false
}

func (r *Route) Reconcile(ctx context.Context, req reconcile.Request) (reconcile.Result, error) {
log := r.log.WithValues("object", req.NamespacedName)
log.V(5).Info("started reconciling")
Expand All @@ -54,12 +78,12 @@ func (r *Route) Reconcile(ctx context.Context, req reconcile.Request) (reconcile
return reconcile.Result{}, err
}
log.V(5).Info("retrieved route")
if metav1.HasAnnotation(route.ObjectMeta, cmapi.IssuerNameAnnotationKey) {
log.V(5).Info("route has cert-manager annotation, reconciling", cmapi.IssuerNameAnnotationKey, route.Annotations[cmapi.IssuerNameAnnotationKey])
return r.sync(ctx, req, route.DeepCopy())

if !shouldSync(log, route) {
return reconcile.Result{}, nil
}
log.V(5).Info("ignoring route without cert-manager issuer name annotation")
return reconcile.Result{}, nil

return r.sync(ctx, req, route.DeepCopy())
}

func New(base logr.Logger, config *rest.Config, recorder record.EventRecorder) (*Route, error) {
Expand Down
85 changes: 85 additions & 0 deletions internal/controller/controller_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/*
Copyright 2022 The cert-manager Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package controller

import (
"testing"

"github.com/go-logr/logr"
routev1 "github.com/openshift/api/route/v1"
"github.com/stretchr/testify/assert"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

func Test_shouldReconcile(t *testing.T) {
tests := []struct {
name string
given *routev1.Route
want bool
}{
{
name: "should reconcile with cert-manager.io/issuer-name annotation",
given: &routev1.Route{ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
"cert-manager.io/issuer-name": "test",
}},
},
want: true,
},
{
name: "should sync with cert-manager.io/issuer annotation",
given: &routev1.Route{ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
"cert-manager.io/issuer": "test",
}},
},
want: true,
},
{
name: "should not sync when Route owned by Ingress",
given: &routev1.Route{ObjectMeta: metav1.ObjectMeta{
OwnerReferences: []metav1.OwnerReference{
{
Kind: "Ingress",
},
}},
},
want: false,
},
{
name: "should not sync when Route owned by Ingress",
given: &routev1.Route{ObjectMeta: metav1.ObjectMeta{
OwnerReferences: []metav1.OwnerReference{
{
Kind: "Ingress",
},
}},
},
want: false,
},
{
name: "should not sync when no annotation is found",
given: &routev1.Route{ObjectMeta: metav1.ObjectMeta{}},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := shouldSync(logr.Discard(), tt.given)
assert.Equal(t, tt.want, got)
})
}
}

0 comments on commit 5b9f2b3

Please sign in to comment.