-
Notifications
You must be signed in to change notification settings - Fork 1
/
privatedns.go
155 lines (123 loc) · 5.35 KB
/
privatedns.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
package privatedns
import (
"context"
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/privatedns/armprivatedns"
"golang.org/x/exp/slices"
"k8s.io/utils/pointer"
"sigs.k8s.io/controller-runtime/pkg/log"
"github.com/giantswarm/microerror"
"github.com/giantswarm/dns-operator-azure/v2/azure"
"github.com/giantswarm/dns-operator-azure/v2/azure/scope"
"github.com/giantswarm/dns-operator-azure/v2/pkg/metrics"
capzazure "sigs.k8s.io/cluster-api-provider-azure/azure"
)
type Service struct {
scope scope.PrivateDNSScope
privateDNSClient Client
}
func New(scope scope.PrivateDNSScope) (*Service, error) {
privateDNSClient, err := newPrivateDNSClient(scope)
if err != nil {
return nil, microerror.Mask(err)
}
return &Service{
scope: scope,
privateDNSClient: privateDNSClient,
}, nil
}
func (s *Service) Reconcile(ctx context.Context) error {
log := log.FromContext(ctx).WithName("azure-private-dns-create")
clusterZoneName := s.scope.ClusterDomain()
managementClusterResourceGroup := s.scope.ManagementClusterResourceGroup()
log.Info("Reconcile privateDNS", "privateDNSZone", clusterZoneName)
metrics.ZoneInfo.WithLabelValues(
clusterZoneName, // label: zone
metrics.ZoneTypePrivate, // label: type
managementClusterResourceGroup, // label: resource_group
s.scope.ManagementClusterTenantID(), // label: tenant_id
s.scope.ManagementClusterSubscriptionID(), // label: subscription_id
).Set(1)
privateClusterRecordSets, err := s.privateDNSClient.ListPrivateRecordSets(ctx, managementClusterResourceGroup, clusterZoneName)
if err != nil && !azure.IsParentResourceNotFound(err) {
return microerror.Mask(err)
} else if azure.IsParentResourceNotFound(err) {
log.V(1).Info("cluster specific private DNS zone not found, creating a new one")
err = s.privateDNSClient.CreateOrUpdatePrivateZone(ctx, managementClusterResourceGroup, clusterZoneName, armprivatedns.PrivateZone{
Name: &clusterZoneName,
Location: pointer.String(capzazure.Global),
})
if err != nil {
return microerror.Mask(err)
}
}
log.Info("list virtualNetworkLinks")
networkLinks, err := s.privateDNSClient.ListVirtualNetworkLink(ctx, managementClusterResourceGroup, clusterZoneName)
if err != nil {
return microerror.Mask(err)
}
log.V(1).Info("list of all network links", "virtualNetworkLinks", networkLinks)
vnetLinkName := virtualNetworkLinkName(managementClusterResourceGroup)
operatorGeneratedVirtualNetworkLinkIndex := slices.IndexFunc(networkLinks, func(virtualNetworkLink *armprivatedns.VirtualNetworkLink) bool {
return *virtualNetworkLink.Name == *pointer.String(vnetLinkName) ||
*virtualNetworkLink.ID == s.scope.ManagementClusterClientID()
})
if operatorGeneratedVirtualNetworkLinkIndex == -1 {
// Check if there is an existing link to the virtual network
existingVirtualNetworkLinkIndex := slices.IndexFunc(networkLinks, func(virtualNetworkLink *armprivatedns.VirtualNetworkLink) bool {
return *virtualNetworkLink.Properties.VirtualNetwork.ID == s.scope.ManagementClusterVnetID()
})
if existingVirtualNetworkLinkIndex >= 0 {
log.V(1).Info("found a link to the same virtual network with a different name, deleting it")
existingVirtualNetworkLink := networkLinks[existingVirtualNetworkLinkIndex]
err = s.privateDNSClient.DeleteVirtualNetworkLink(ctx, managementClusterResourceGroup, clusterZoneName, *existingVirtualNetworkLink.Name)
if err != nil {
return microerror.Mask(err)
}
}
log.V(1).Info("virtual network link not found, creating a new one")
err = s.privateDNSClient.CreateOrUpdateVirtualNetworkLink(
ctx,
managementClusterResourceGroup,
clusterZoneName,
s.scope.ClusterName(),
s.scope.ManagementClusterVnetID(),
vnetLinkName,
)
if err != nil {
return microerror.Mask(err)
}
}
log.V(1).Info("get privateDNSZone Object", "privateDNSZone", clusterZoneName)
privateZones, err := s.privateDNSClient.GetPrivateZone(ctx, s.scope.ManagementClusterResourceGroup(), clusterZoneName)
if err != nil {
log.V(1).Info("new error", "error", err.Error())
}
// dns_operator_zone_records_sum
metrics.ClusterZoneRecords.WithLabelValues(
clusterZoneName,
metrics.ZoneTypePrivate,
).Set(float64(*privateZones.Properties.NumberOfRecordSets))
log.V(1).Info("current known private Zones in management cluster", "privateZones", privateZones)
if err := s.updateARecords(ctx, privateClusterRecordSets); err != nil {
return microerror.Mask(err)
}
if err = s.updateCnameRecords(ctx, privateClusterRecordSets); err != nil {
return microerror.Mask(err)
}
return nil
}
func (s *Service) ReconcileDelete(ctx context.Context) error {
log := log.FromContext(ctx).WithName("azure-private-dns-delete")
clusterZoneName := s.scope.ClusterDomain()
log.Info("Reconcile DNS deletion", "privateDNSZone", clusterZoneName)
mcResourceGroup := s.scope.ManagementClusterResourceGroup()
vnetLinkName := virtualNetworkLinkName(s.scope.ManagementClusterResourceGroup())
if err := s.privateDNSClient.DeleteVirtualNetworkLink(ctx, mcResourceGroup, clusterZoneName, vnetLinkName); err != nil {
return microerror.Mask(err)
}
if err := s.privateDNSClient.DeletePrivateZone(ctx, s.scope.ManagementClusterResourceGroup(), clusterZoneName); err != nil {
return microerror.Mask(err)
}
log.Info("Successfully reconciled DNS", "privateDNSZone", clusterZoneName)
return nil
}