more changes
This commit is contained in:
@@ -17,11 +17,11 @@ limitations under the License.
|
||||
package controller
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"slices"
|
||||
"time"
|
||||
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
@@ -30,6 +30,7 @@ import (
|
||||
logf "sigs.k8s.io/controller-runtime/pkg/log"
|
||||
|
||||
dnsv1 "stinnesbeck.com/dns/api/v1"
|
||||
v1 "stinnesbeck.com/dns/api/v1"
|
||||
)
|
||||
|
||||
// ResolutionReconciler reconciles a Resolution object
|
||||
@@ -68,16 +69,31 @@ func (r *ResolutionReconciler) Reconcile(ctx context.Context, req ctrl.Request)
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
|
||||
resolver := net.DefaultResolver
|
||||
|
||||
// check if a resolver was given
|
||||
if resolution.Spec.Resolver != nil {
|
||||
customResolver, err := r.getResolver(ctx, req, &resolution)
|
||||
if err != nil {
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
|
||||
resolution.Status.Resolver = resolution.Spec.Resolver
|
||||
resolver = customResolver
|
||||
}
|
||||
|
||||
// Snapshot before mutation
|
||||
patchBase := resolution.DeepCopy()
|
||||
|
||||
addrs, err := net.LookupHost(resolution.Spec.Address)
|
||||
var addrs []string
|
||||
|
||||
addrs, err := resolver.LookupHost(ctx, resolution.Spec.Address)
|
||||
if err != nil {
|
||||
log.Error(err, "error while resolving resolution")
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
|
||||
// Build new desired status (IMPORTANT: no append)
|
||||
// Build new desired status
|
||||
var ips []net.IP
|
||||
for _, addr := range addrs {
|
||||
if ip := net.ParseIP(addr); ip != nil {
|
||||
@@ -85,24 +101,11 @@ func (r *ResolutionReconciler) Reconcile(ctx context.Context, req ctrl.Request)
|
||||
}
|
||||
}
|
||||
|
||||
slices.SortStableFunc(ips, func(a, b net.IP) int {
|
||||
for i := range 15 {
|
||||
if a[i] < b[i] {
|
||||
return -1
|
||||
}
|
||||
|
||||
if a[i] > b[i] {
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
return 0
|
||||
})
|
||||
// sort to make states comparable
|
||||
slices.SortStableFunc(ips, stableSortIPs)
|
||||
|
||||
// check if both ip address slices are the same
|
||||
if slices.EqualFunc(patchBase.Status.IPAddresses, ips, func(s1, s2 net.IP) bool {
|
||||
return bytes.Equal(s1, s2)
|
||||
}) {
|
||||
if slices.EqualFunc(patchBase.Status.IPAddresses, ips, equalIPs) {
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
|
||||
@@ -111,30 +114,70 @@ func (r *ResolutionReconciler) Reconcile(ctx context.Context, req ctrl.Request)
|
||||
resolution.Status.IPAddresses = ips
|
||||
|
||||
// Only patch status (clean + minimal diff)
|
||||
if err := r.Status().Patch(
|
||||
ctx,
|
||||
&resolution,
|
||||
client.MergeFrom(patchBase),
|
||||
); err != nil {
|
||||
if err := r.Status().Patch(ctx, &resolution, client.MergeFrom(patchBase)); err != nil {
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
|
||||
// if err := r.Patch(ctx, &resolution, client.Merge); err != nil {
|
||||
func (r *ResolutionReconciler) getResolver(ctx context.Context, req ctrl.Request, resolution *v1.Resolution) (*net.Resolver, error) {
|
||||
var resolver v1.Resolver
|
||||
|
||||
resolverFQDN := client.ObjectKey{
|
||||
Namespace: req.Namespace,
|
||||
Name: *resolution.Spec.Resolver,
|
||||
}
|
||||
|
||||
if err := r.Get(ctx, resolverFQDN, &resolver); err != nil {
|
||||
// retrieval of resolver failed
|
||||
return nil, err
|
||||
}
|
||||
|
||||
netResolver := net.Resolver{
|
||||
PreferGo: true,
|
||||
Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
|
||||
d := net.Dialer{
|
||||
Timeout: 3 * time.Second,
|
||||
}
|
||||
return d.DialContext(ctx, network, fmt.Sprintf("%s:%d", resolver.Spec.IPAddress, resolver.Spec.Port))
|
||||
},
|
||||
}
|
||||
|
||||
return &netResolver, nil
|
||||
|
||||
// // Snapshot before mutation
|
||||
// patchBase := resolution.DeepCopy()
|
||||
|
||||
// ip, _ := netResolver.LookupHost(context.Background(), resolution.Spec.Address)
|
||||
|
||||
// if err := r.Status().Patch(ctx, resolution, client.MergeFrom(patchBase)); err != nil {
|
||||
// return ctrl.Result{}, err
|
||||
// }
|
||||
|
||||
// r := &net.Resolver{
|
||||
// PreferGo: true,
|
||||
// Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
|
||||
// d := net.Dialer{
|
||||
// Timeout: time.Millisecond * time.Duration(10000),
|
||||
// }
|
||||
// return d.DialContext(ctx, network, "8.8.8.8:53")
|
||||
// },
|
||||
// }
|
||||
// ip, _ := r.LookupHost(context.Background(), "www.google.com")
|
||||
// return ctrl.Result{}, nil
|
||||
}
|
||||
|
||||
func equalIPs(a, b net.IP) bool {
|
||||
return a.Equal(b)
|
||||
}
|
||||
|
||||
func stableSortIPs(a, b net.IP) int {
|
||||
if len(a) != len(b) {
|
||||
a, b = a.To16(), b.To16()
|
||||
}
|
||||
|
||||
for i := range a {
|
||||
if a[i] < b[i] {
|
||||
return -1
|
||||
}
|
||||
|
||||
if a[i] > b[i] {
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
// SetupWithManager sets up the controller with the Manager.
|
||||
|
||||
@@ -69,7 +69,6 @@ func (r *ResolverReconciler) Reconcile(ctx context.Context, req ctrl.Request) (c
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
|
||||
// TODO(user): your logic here
|
||||
switch {
|
||||
case len(resolver.Spec.IPAddress) == 0:
|
||||
// IPAddress is not a valid IP
|
||||
@@ -81,6 +80,17 @@ func (r *ResolverReconciler) Reconcile(ctx context.Context, req ctrl.Request) (c
|
||||
// IP is IPv6
|
||||
}
|
||||
|
||||
// exit loop here if port was provided
|
||||
if resolver.Spec.Port != 0 {
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
|
||||
// set defaults and patch it back to k8s
|
||||
resolver.Spec.Port = 53
|
||||
if err := r.Patch(ctx, &resolver, client.Merge); err != nil {
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user