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

Azure / aks-app-routing-operator / 22185616992

19 Feb 2026 02:21PM UTC coverage: 79.077% (-0.005%) from 79.082%
22185616992

push

github

OliverMKing
add msi externaldns e2e test

4286 of 5420 relevant lines covered (79.08%)

24.39 hits per line

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

73.68
/pkg/controller/dns/external_dns.go
1
package dns
2

3
import (
4
        "fmt"
5
        "time"
6

7
        "github.com/Azure/aks-app-routing-operator/pkg/config"
8
        "github.com/Azure/aks-app-routing-operator/pkg/controller/common"
9
        "github.com/Azure/aks-app-routing-operator/pkg/controller/controllername"
10
        "github.com/Azure/aks-app-routing-operator/pkg/manifests"
11
        "github.com/Azure/aks-app-routing-operator/pkg/util"
12
        "github.com/Azure/azure-sdk-for-go/sdk/azcore/to"
13
        corev1 "k8s.io/api/core/v1"
14
        "k8s.io/apimachinery/pkg/runtime/schema"
15
        ctrl "sigs.k8s.io/controller-runtime"
16
        "sigs.k8s.io/controller-runtime/pkg/client"
17
)
18

19
const (
20
        reconcileInterval = time.Minute * 3
21
)
22

23
// addExternalDnsReconciler creates a reconciler that manages external dns resources
24
func addExternalDnsReconciler(manager ctrl.Manager, resources []client.Object) error {
2✔
25
        return common.NewResourceReconciler(manager, controllername.New("external", "dns", "reconciler"), resources, reconcileInterval)
2✔
26
}
2✔
27

28
func addExternalDnsCleaner(manager ctrl.Manager, instances []instance) error {
2✔
29
        return nil // disable cleaner until we have better test coverage
2✔
30

2✔
31
        objs := cleanObjs(instances)
2✔
32
        retriever := common.RetrieverEmpty()
2✔
33
        for _, obj := range objs {
2✔
34
                retriever = retriever.Add(common.RetrieverFromObjs(obj.resources, obj.labels)) // clean up entire unused external dns applications
×
35
        }
×
36
        for _, instance := range instances {
×
37
                labels := util.MergeMaps(instance.config.Labels(), manifests.GetTopLevelLabels())
×
38
                retriever = retriever.Add(common.RetrieverFromGk(labels, manifests.OldExternalDnsGks...)) // clean up unused types from previous versions of app routing
×
39
        }
×
40

41
        retriever = retriever.Remove(common.RetrieverFromGk(
×
42
                nil, // our compare strat is ignore labels
×
43
                schema.GroupKind{
×
44
                        Group: corev1.GroupName,
×
45
                        Kind:  "Namespace",
×
46
                }),
×
47
                common.RemoveOpt{
×
48
                        CompareStrat: common.IgnoreLabels, // ignore labels, we never want to clean namespaces
×
49
                })
×
50

×
51
        return common.NewCleaner(manager, controllername.New("external", "dns", "cleaner"), retriever)
×
52
}
53

54
// NewExternalDns starts all resources required for external dns
55
func NewExternalDns(manager ctrl.Manager, conf *config.Config) error {
1✔
56
        instances, err := instances(conf)
1✔
57
        if err != nil {
1✔
58
                return fmt.Errorf("failed to create instances: %w", err)
×
59
        }
×
60

61
        deployInstances := filterAction(instances, deploy)
1✔
62
        deployRes := getResources(deployInstances)
1✔
63
        if err := addExternalDnsReconciler(manager, deployRes); err != nil {
1✔
64
                return err
×
65
        }
×
66

67
        if err := addExternalDnsCleaner(manager, instances); err != nil {
1✔
68
                return err
×
69
        }
×
70

71
        if conf.EnabledWorkloadIdentity || conf.EnableDefaultDomain {
1✔
72
                if err := newClusterExternalDNSController(manager, conf); err != nil {
×
73
                        return fmt.Errorf("adding cluster external dns controller: %w", err)
×
74
                }
×
75
        }
76

77
        if conf.EnabledWorkloadIdentity {
1✔
78
                if err := newExternalDNSCRDController(manager, *conf); err != nil {
×
79
                        return fmt.Errorf("setting up namespaced external DNS controller: %w", err)
×
80
                }
×
81
        }
82

83
        if conf.EnableDefaultDomain {
1✔
84
                if err := NewDefaultDomainDNSReconciler(manager, conf); err != nil {
×
85
                        return fmt.Errorf("adding default domain cluster external dns controller: %w", err)
×
86
                }
×
87
        }
88

89
        return nil
1✔
90
}
91

92
func instances(conf *config.Config) ([]instance, error) {
17✔
93
        // public
17✔
94
        publicCfg, err := publicConfigForIngress(conf)
17✔
95
        if err != nil {
17✔
96
                return nil, err
×
97
        }
×
98

99
        publicAction := actionFromConfig(publicCfg)
17✔
100
        publicResources := publicCfg.Resources()
17✔
101

17✔
102
        // private
17✔
103
        privateCfg, err := privateConfigForIngress(conf)
17✔
104
        if err != nil {
17✔
105
                return nil, err
×
106
        }
×
107

108
        privateAction := actionFromConfig(privateCfg)
17✔
109
        privateResources := privateCfg.Resources()
17✔
110

17✔
111
        return []instance{
17✔
112
                {
17✔
113
                        config:    publicCfg,
17✔
114
                        resources: publicResources,
17✔
115
                        action:    publicAction,
17✔
116
                },
17✔
117
                {
17✔
118
                        config:    privateCfg,
17✔
119
                        resources: privateResources,
17✔
120
                        action:    privateAction,
17✔
121
                },
17✔
122
        }, nil
17✔
123
}
124

125
func publicConfigForIngress(conf *config.Config) (*manifests.ExternalDnsConfig, error) {
19✔
126
        publicconfig, err := manifests.NewExternalDNSConfig(
19✔
127
                conf,
19✔
128
                manifests.InputExternalDNSConfig{
19✔
129
                        TenantId:           conf.TenantID,
19✔
130
                        ClientId:           conf.MSIClientID,
19✔
131
                        Namespace:          conf.NS,
19✔
132
                        IdentityType:       manifests.IdentityTypeMSI,
19✔
133
                        ResourceTypes:      map[manifests.ResourceType]struct{}{manifests.ResourceTypeIngress: {}},
19✔
134
                        DnsZoneresourceIDs: util.Keys(conf.PublicZoneConfig.ZoneIds),
19✔
135
                        Provider:           to.Ptr(manifests.PublicProvider),
19✔
136
                })
19✔
137
        if err != nil {
19✔
138
                return nil, err
×
139
        }
×
140
        return publicconfig, nil
19✔
141
}
142

143
func privateConfigForIngress(conf *config.Config) (*manifests.ExternalDnsConfig, error) {
19✔
144
        privateconfig, err := manifests.NewExternalDNSConfig(
19✔
145
                conf,
19✔
146
                manifests.InputExternalDNSConfig{
19✔
147
                        TenantId:           conf.TenantID,
19✔
148
                        ClientId:           conf.MSIClientID,
19✔
149
                        Namespace:          conf.NS,
19✔
150
                        IdentityType:       manifests.IdentityTypeMSI,
19✔
151
                        ResourceTypes:      map[manifests.ResourceType]struct{}{manifests.ResourceTypeIngress: {}},
19✔
152
                        DnsZoneresourceIDs: util.Keys(conf.PrivateZoneConfig.ZoneIds),
19✔
153
                        Provider:           to.Ptr(manifests.PrivateProvider),
19✔
154
                },
19✔
155
        )
19✔
156
        if err != nil {
19✔
157
                return nil, err
×
158
        }
×
159
        return privateconfig, nil
19✔
160
}
161

162
func filterAction(instances []instance, action action) []instance {
13✔
163
        var ret []instance
13✔
164
        for _, i := range instances {
39✔
165
                if i.action == action {
38✔
166
                        ret = append(ret, i)
12✔
167
                }
12✔
168
        }
169

170
        return ret
13✔
171
}
172

173
func getResources(instances []instance) []client.Object {
4✔
174
        var ret []client.Object
4✔
175
        for _, i := range instances {
6✔
176
                ret = append(ret, i.resources...)
2✔
177
        }
2✔
178
        return ret
4✔
179
}
180

181
func getLabels(instances ...instance) map[string]string {
8✔
182
        l := map[string]string{}
8✔
183
        for k, v := range manifests.GetTopLevelLabels() {
24✔
184
                l[k] = v
16✔
185
        }
16✔
186

187
        for _, i := range instances {
16✔
188
                for k, v := range i.config.Labels() {
16✔
189
                        l[k] = v
8✔
190
                }
8✔
191
        }
192

193
        return l
8✔
194
}
195

196
func cleanObjs(instances []instance) []cleanObj {
4✔
197
        var cleanObjs []cleanObj
4✔
198
        for _, instance := range filterAction(instances, clean) {
8✔
199
                obj := cleanObj{
4✔
200
                        resources: instance.resources,
4✔
201
                        labels:    getLabels(instance),
4✔
202
                }
4✔
203
                cleanObjs = append(cleanObjs, obj)
4✔
204
        }
4✔
205

206
        return cleanObjs
4✔
207
}
208

209
func actionFromConfig(conf *manifests.ExternalDnsConfig) action {
37✔
210
        if len(conf.DnsZoneResourceIds()) == 0 {
57✔
211
                return clean
20✔
212
        }
20✔
213

214
        return deploy
17✔
215
}
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