Skip to content

Commit

Permalink
Merge pull request #135 from Kuadrant/gh-82
Browse files Browse the repository at this point in the history
add watch and ns config
  • Loading branch information
maleck13 authored May 21, 2024
2 parents b21e57a + a3951b2 commit 8c236b7
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 8 deletions.
26 changes: 22 additions & 4 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@ package main
import (
"flag"
"os"
"strings"
"time"

"k8s.io/apimachinery/pkg/runtime"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
_ "k8s.io/client-go/plugin/pkg/client/auth"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/cache"
"sigs.k8s.io/controller-runtime/pkg/healthz"
"sigs.k8s.io/controller-runtime/pkg/log/zap"
metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"
Expand Down Expand Up @@ -79,17 +81,33 @@ func main() {
}
opts.BindFlags(flag.CommandLine)
flag.Parse()
logger := zap.New(zap.UseFlagOptions(&opts))
ctrl.SetLogger(logger)

ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts)))

mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
var watchNamespaces = "WATCH_NAMESPACES"
defaultOptions := ctrl.Options{
Scheme: scheme,
Metrics: metricsserver.Options{BindAddress: metricsAddr},
WebhookServer: webhook.NewServer(webhook.Options{Port: 9443}),
HealthProbeBindAddress: probeAddr,
LeaderElection: enableLeaderElection,
LeaderElectionID: "a3f98d6c.kuadrant.io",
})
}

if watch := os.Getenv(watchNamespaces); watch != "" {
namespaces := strings.Split(watch, ",")
logger.Info("watching namespaces set ", watchNamespaces, namespaces)
cacheOpts := cache.Options{
DefaultNamespaces: map[string]cache.Config{},
}
for _, ns := range namespaces {
cacheOpts.DefaultNamespaces[ns] = cache.Config{}
}
defaultOptions.Cache = cacheOpts

}

mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), defaultOptions)
if err != nil {
setupLog.Error(err, "unable to start manager")
os.Exit(1)
Expand Down
18 changes: 18 additions & 0 deletions internal/controller/dnsrecord_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
"sigs.k8s.io/controller-runtime/pkg/handler"
"sigs.k8s.io/controller-runtime/pkg/log"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
externaldnsendpoint "sigs.k8s.io/external-dns/endpoint"
Expand Down Expand Up @@ -186,6 +187,23 @@ func (r *DNSRecordReconciler) SetupWithManager(mgr ctrl.Manager, requeueIn, vali

return ctrl.NewControllerManagedBy(mgr).
For(&v1alpha1.DNSRecord{}).
Watches(&v1alpha1.ManagedZone{}, handler.EnqueueRequestsFromMapFunc(func(ctx context.Context, o client.Object) []reconcile.Request {
logger := log.FromContext(ctx)
toReconcile := []reconcile.Request{}
// list dns records in the maanagedzone namespace as they will be in the same namespace as the zone
records := &v1alpha1.DNSRecordList{}
if err := mgr.GetClient().List(ctx, records, &client.ListOptions{Namespace: o.GetNamespace()}); err != nil {
logger.Error(err, "failed to list dnsrecords ", "namespace", o.GetNamespace())
return toReconcile
}
for _, record := range records.Items {
if record.Spec.ManagedZoneRef.Name == o.GetName() {
logger.Info("managed zone updated", "managedzone", o.GetNamespace()+"/"+o.GetName(), "enqueuing dnsrecord ", record.GetName())
toReconcile = append(toReconcile, reconcile.Request{NamespacedName: client.ObjectKeyFromObject(&record)})
}
}
return toReconcile
})).
Complete(r)
}

Expand Down
75 changes: 73 additions & 2 deletions internal/controller/dnsrecord_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,19 @@ var _ = Describe("DNSRecordReconciler", func() {
var dnsRecord2 *v1alpha1.DNSRecord
var dnsProviderSecret *v1.Secret
var managedZone *v1alpha1.ManagedZone
var brokenZone *v1alpha1.ManagedZone
var testNamespace string

BeforeEach(func() {
CreateNamespace(&testNamespace)

dnsProviderSecret = testBuildInMemoryCredentialsSecret("inmemory-credentials", testNamespace)
managedZone = testBuildManagedZone("mz-example-com", testNamespace, "example.com", dnsProviderSecret.Name)
brokenZone = testBuildManagedZone("mz-fix-com", testNamespace, "fix.com", "not-there")

Expect(k8sClient.Create(ctx, dnsProviderSecret)).To(Succeed())
Expect(k8sClient.Create(ctx, managedZone)).To(Succeed())
Expect(k8sClient.Create(ctx, brokenZone)).To(Succeed())
Eventually(func(g Gomega) {
err := k8sClient.Get(ctx, client.ObjectKeyFromObject(managedZone), managedZone)
g.Expect(err).NotTo(HaveOccurred())
Expand All @@ -61,6 +64,18 @@ var _ = Describe("DNSRecordReconciler", func() {
)
}, TestTimeoutMedium, time.Second).Should(Succeed())

Eventually(func(g Gomega) {
err := k8sClient.Get(ctx, client.ObjectKeyFromObject(brokenZone), brokenZone)
g.Expect(err).NotTo(HaveOccurred())
g.Expect(brokenZone.Status.Conditions).To(
ContainElement(MatchFields(IgnoreExtras, Fields{
"Type": Equal(string(v1alpha1.ConditionTypeReady)),
"Status": Equal(metav1.ConditionFalse),
"ObservedGeneration": Equal(brokenZone.Generation),
})),
)
}, TestTimeoutMedium, time.Second).Should(Succeed())

dnsRecord = &v1alpha1.DNSRecord{
ObjectMeta: metav1.ObjectMeta{
Name: "foo.example.com",
Expand All @@ -72,7 +87,7 @@ var _ = Describe("DNSRecordReconciler", func() {
ManagedZoneRef: &v1alpha1.ManagedZoneReference{
Name: managedZone.Name,
},
Endpoints: getTestEndpoints(),
Endpoints: getTestEndpoints("foo.example.com"),
},
}
})
Expand All @@ -90,6 +105,62 @@ var _ = Describe("DNSRecordReconciler", func() {
err := k8sClient.Delete(ctx, managedZone)
Expect(client.IgnoreNotFound(err)).ToNot(HaveOccurred())
}
if brokenZone != nil {
err := k8sClient.Delete(ctx, brokenZone)
Expect(client.IgnoreNotFound(err)).ToNot(HaveOccurred())
}
})

It("dns records are reconciled once zone is fixed", func(ctx SpecContext) {
dnsRecord = &v1alpha1.DNSRecord{
ObjectMeta: metav1.ObjectMeta{
Name: "foo.fix.com",
Namespace: testNamespace,
},
Spec: v1alpha1.DNSRecordSpec{
OwnerID: "owner1",
RootHost: "foo.fix.com",
ManagedZoneRef: &v1alpha1.ManagedZoneReference{
Name: brokenZone.Name,
},
Endpoints: getTestEndpoints("foo.fix.com"),
HealthCheck: nil,
},
}
Expect(k8sClient.Create(ctx, dnsRecord)).To(Succeed())
Eventually(func(g Gomega) {
err := k8sClient.Get(ctx, client.ObjectKeyFromObject(dnsRecord), dnsRecord)
g.Expect(err).NotTo(HaveOccurred())
g.Expect(dnsRecord.Status.Conditions).To(
ContainElement(MatchFields(IgnoreExtras, Fields{
"Type": Equal(string(v1alpha1.ConditionTypeReady)),
"Status": Equal(metav1.ConditionFalse),
"Reason": Equal("ProviderError"),
"Message": ContainSubstring("The DNS provider failed to ensure the record"),
"ObservedGeneration": Equal(dnsRecord.Generation),
})),
)
g.Expect(dnsRecord.Finalizers).To(ContainElement(DNSRecordFinalizer))
}, TestTimeoutMedium, time.Second).Should(Succeed())

fixedZone := brokenZone.DeepCopy()
fixedZone.Spec.SecretRef.Name = dnsProviderSecret.Name
Expect(k8sClient.Update(ctx, fixedZone)).NotTo(HaveOccurred())

Eventually(func(g Gomega) {
err := k8sClient.Get(ctx, client.ObjectKeyFromObject(dnsRecord), dnsRecord)
g.Expect(err).NotTo(HaveOccurred())
g.Expect(dnsRecord.Status.Conditions).To(
ContainElement(MatchFields(IgnoreExtras, Fields{
"Type": Equal(string(v1alpha1.ConditionTypeReady)),
"Status": Equal(metav1.ConditionTrue),
"Reason": Equal("ProviderSuccess"),
"Message": Equal("Provider ensured the dns record"),
"ObservedGeneration": Equal(dnsRecord.Generation),
})),
)
g.Expect(dnsRecord.Finalizers).To(ContainElement(DNSRecordFinalizer))
}, TestTimeoutMedium, time.Second).Should(Succeed())
})

It("can delete a record with an invalid managed zone", func(ctx SpecContext) {
Expand All @@ -104,7 +175,7 @@ var _ = Describe("DNSRecordReconciler", func() {
ManagedZoneRef: &v1alpha1.ManagedZoneReference{
Name: "doesnotexist",
},
Endpoints: getTestEndpoints(),
Endpoints: getTestEndpoints("foo.example.com"),
HealthCheck: nil,
},
}
Expand Down
4 changes: 2 additions & 2 deletions internal/controller/helper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,10 @@ func testBuildInMemoryCredentialsSecret(name, ns string) *v1.Secret {
}
}

func getTestEndpoints() []*externaldnsendpoint.Endpoint {
func getTestEndpoints(dnsName string) []*externaldnsendpoint.Endpoint {
return []*externaldnsendpoint.Endpoint{
{
DNSName: "foo.example.com",
DNSName: dnsName,
Targets: []string{
"127.0.0.1",
},
Expand Down

0 comments on commit 8c236b7

Please sign in to comment.