• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Azure / aks-app-routing-operator / 20963014024

13 Jan 2026 03:46PM UTC coverage: 78.962% (-0.5%) from 79.448%
20963014024

push

github

jaiveerk
improve flakiness

4275 of 5414 relevant lines covered (78.96%)

71.65 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

81.67
/pkg/controller/defaultdomaincert/default_domain_cert_controller.go
1
package defaultdomaincert
2

3
import (
4
        "context"
5
        "errors"
6
        "fmt"
7
        "time"
8

9
        approutingv1alpha1 "github.com/Azure/aks-app-routing-operator/api/v1alpha1"
10
        defaultdomain "github.com/Azure/aks-app-routing-operator/pkg/clients/default-domain"
11
        "github.com/Azure/aks-app-routing-operator/pkg/config"
12
        "github.com/Azure/aks-app-routing-operator/pkg/controller/controllername"
13
        "github.com/Azure/aks-app-routing-operator/pkg/controller/metrics"
14
        "github.com/Azure/aks-app-routing-operator/pkg/manifests"
15
        "github.com/Azure/aks-app-routing-operator/pkg/tls"
16
        "github.com/Azure/aks-app-routing-operator/pkg/util"
17
        corev1 "k8s.io/api/core/v1"
18
        apierrors "k8s.io/apimachinery/pkg/api/errors"
19
        metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
20
        "k8s.io/client-go/tools/record"
21
        ctrl "sigs.k8s.io/controller-runtime"
22
        "sigs.k8s.io/controller-runtime/pkg/client"
23
        "sigs.k8s.io/controller-runtime/pkg/log"
24
)
25

26
var name = controllername.New("default", "domain", "cert", "reconciler")
27

28
// defaultDomainClient is an interface for fetching TLS certificates from the default domain service
29
type defaultDomainClient interface {
30
        GetTLSCertificate(ctx context.Context) (*defaultdomain.TLSCertificate, error)
31
}
32

33
type defaultDomainCertControllerReconciler struct {
34
        client              client.Client
35
        events              record.EventRecorder
36
        conf                *config.Config
37
        defaultDomainClient defaultDomainClient
38
}
39

40
func NewReconciler(conf *config.Config, mgr ctrl.Manager, defaultDomainClient *defaultdomain.CachedClient) error {
×
41
        metrics.InitControllerMetrics(name)
×
42

×
43
        reconciler := &defaultDomainCertControllerReconciler{
×
44
                client:              mgr.GetClient(),
×
45
                events:              mgr.GetEventRecorderFor("aks-app-routing-operator"),
×
46
                conf:                conf,
×
47
                defaultDomainClient: defaultDomainClient,
×
48
        }
×
49

×
50
        if err := name.AddToController(
×
51
                ctrl.NewControllerManagedBy(mgr).
×
52
                        For(&approutingv1alpha1.DefaultDomainCertificate{}).
×
53
                        Owns(&corev1.Secret{}),
×
54
                mgr.GetLogger(),
×
55
        ).Complete(reconciler); err != nil {
×
56
                return fmt.Errorf("building the controller: %w", err)
×
57
        }
×
58

59
        return nil
×
60
}
61

62
func (d *defaultDomainCertControllerReconciler) Reconcile(ctx context.Context, req ctrl.Request) (res ctrl.Result, err error) {
36✔
63
        start := time.Now()
36✔
64
        lgr := log.FromContext(ctx, "name", req.Name, "namespace", req.Namespace)
36✔
65
        ctx = log.IntoContext(ctx, lgr)
36✔
66

36✔
67
        lgr.Info("reconciling DefaultDomainCertificate")
36✔
68
        defer func() {
72✔
69
                lgr.Info("reconcile finished", "latency", time.Since(start))
36✔
70
        }()
36✔
71

72
        defaultDomainCertificate := &approutingv1alpha1.DefaultDomainCertificate{}
36✔
73
        if err := d.client.Get(ctx, req.NamespacedName, defaultDomainCertificate); err != nil {
42✔
74
                if apierrors.IsNotFound(err) { // object was deleted
9✔
75
                        lgr.Info("DefaultDomainCertificate not found")
3✔
76
                        return ctrl.Result{}, nil
3✔
77
                }
3✔
78

79
                lgr.Error(err, "unable to get DefaultDomainCertificate")
3✔
80
                return ctrl.Result{}, err
3✔
81
        }
82

83
        if defaultDomainCertificate.Spec.Target.Secret == nil {
33✔
84
                err := errors.New("DefaultDomainCertificate has no target secret specified")
3✔
85
                lgr.Error(err, "DefaultDomainCertificate has no target specified, this should be blocked by CRD CEL validation")
3✔
86
                return ctrl.Result{}, err
3✔
87
        }
3✔
88

89
        lgr = lgr.WithValues("secretTarget", *defaultDomainCertificate.Spec.Target.Secret)
27✔
90
        ctx = log.IntoContext(ctx, lgr)
27✔
91

27✔
92
        lgr.Info("upserting Secret for DefaultDomainCertificate")
27✔
93
        secret, err := d.generateSecret(ctx, defaultDomainCertificate)
27✔
94
        if err != nil {
33✔
95
                if util.IsNotFound(err) {
9✔
96
                        lgr.Info("Default domain certificate not found")
3✔
97
                        defaultDomainCertificate.SetCondition(metav1.Condition{
3✔
98
                                Type:    approutingv1alpha1.DefaultDomainCertificateConditionTypeAvailable,
3✔
99
                                Status:  metav1.ConditionFalse,
3✔
100
                                Reason:  "CertificateNotReady",
3✔
101
                                Message: "Certificate not ready yet, waiting for it to be issued",
3✔
102
                        })
3✔
103
                        if err := d.client.Status().Update(ctx, defaultDomainCertificate); err != nil {
3✔
104
                                lgr.Error(err, "failed to update status for DefaultDomainCertificate")
×
105
                                return ctrl.Result{}, err
×
106
                        }
×
107

108
                        // we use a Jitter here to avoid thundering herd issues if many DefaultDomainCertificates are waiting for certs
109
                        return ctrl.Result{RequeueAfter: util.Jitter(30*time.Second, 0.25)}, nil
3✔
110
                }
111

112
                err := fmt.Errorf("generating Secret for DefaultDomainCertificate: %w", err)
3✔
113
                lgr.Error(err, "failed to generate Secret for DefaultDomainCertificate")
3✔
114
                return ctrl.Result{}, err
3✔
115
        }
116

117
        if err := util.Upsert(ctx, d.client, secret); err != nil {
27✔
118
                d.events.Eventf(defaultDomainCertificate, corev1.EventTypeWarning, "ApplyingCertificateSecretFailed", "Failed to apply Secret for DefaultDomainCertificate: %s", err.Error())
6✔
119
                lgr.Error(err, "failed to upsert Secret for DefaultDomainCertificate")
6✔
120
                return ctrl.Result{}, err
6✔
121
        }
6✔
122

123
        // Update the status of the DefaultDomainCertificate
124
        defaultDomainCertificate.SetCondition(metav1.Condition{
15✔
125
                Type:    approutingv1alpha1.DefaultDomainCertificateConditionTypeAvailable,
15✔
126
                Status:  metav1.ConditionTrue,
15✔
127
                Reason:  "CertificateSecretApplied",
15✔
128
                Message: fmt.Sprintf("Secret %s/%s successfully applied for DefaultDomainCertificate", secret.Namespace, secret.Name),
15✔
129
        })
15✔
130
        if err := d.client.Status().Update(ctx, defaultDomainCertificate); err != nil {
18✔
131
                lgr.Error(err, "failed to update status for DefaultDomainCertificate")
3✔
132
                return ctrl.Result{}, err
3✔
133
        }
3✔
134

135
        return ctrl.Result{}, nil
12✔
136
}
137

138
func (d *defaultDomainCertControllerReconciler) generateSecret(ctx context.Context, defaultDomainCertificate *approutingv1alpha1.DefaultDomainCertificate) (*corev1.Secret, error) {
54✔
139
        cert, key, err := d.getAndVerifyCertAndKeyFromClient(ctx)
54✔
140
        if err != nil {
78✔
141
                return nil, fmt.Errorf("getting and verifying cert and key: %w", err)
24✔
142
        }
24✔
143

144
        secret := &corev1.Secret{
30✔
145
                ObjectMeta: metav1.ObjectMeta{
30✔
146
                        Name:      *defaultDomainCertificate.Spec.Target.Secret,
30✔
147
                        Namespace: defaultDomainCertificate.Namespace,
30✔
148
                        Labels:    manifests.GetTopLevelLabels(),
30✔
149
                },
30✔
150
                TypeMeta: metav1.TypeMeta{
30✔
151
                        Kind:       "Secret",
30✔
152
                        APIVersion: corev1.SchemeGroupVersion.String(),
30✔
153
                },
30✔
154
                Type: corev1.SecretTypeTLS,
30✔
155
                Data: map[string][]byte{
30✔
156
                        "tls.crt": cert,
30✔
157
                        "tls.key": key,
30✔
158
                },
30✔
159
        }
30✔
160

30✔
161
        owner := manifests.GetOwnerRefs(defaultDomainCertificate, true)
30✔
162
        secret.SetOwnerReferences(owner)
30✔
163

30✔
164
        return secret, nil
30✔
165
}
166

167
func (d *defaultDomainCertControllerReconciler) getAndVerifyCertAndKeyFromClient(ctx context.Context) ([]byte, []byte, error) {
66✔
168
        tlsCert, err := d.defaultDomainClient.GetTLSCertificate(ctx)
66✔
169
        if err != nil {
72✔
170
                return nil, nil, fmt.Errorf("failed to get TLS certificate from client: %w", err)
6✔
171
        }
6✔
172

173
        if tlsCert.Key == nil || len(tlsCert.Key) == 0 {
69✔
174
                return nil, nil, fmt.Errorf("TLS certificate key is empty")
9✔
175
        }
9✔
176

177
        if tlsCert.Cert == nil || len(tlsCert.Cert) == 0 {
60✔
178
                return nil, nil, fmt.Errorf("TLS certificate cert is empty")
9✔
179
        }
9✔
180

181
        if _, err := tls.ParseTLSCertificate(tlsCert.Cert, tlsCert.Key); err != nil {
51✔
182
                return nil, nil, fmt.Errorf("validating cert and key: %w", err)
9✔
183
        }
9✔
184

185
        return tlsCert.Cert, tlsCert.Key, nil
33✔
186
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc