Skip to content

Commit

Permalink
feat(domain): add option to set controller domain (#52)
Browse files Browse the repository at this point in the history
* Add new command line flag for a controller domain
* Update docs
  • Loading branch information
akosveres authored Nov 15, 2024
1 parent 5366d89 commit b308dea
Show file tree
Hide file tree
Showing 13 changed files with 102 additions and 58 deletions.
30 changes: 19 additions & 11 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,13 @@ func main() {
var metricsAddr string
var enableLeaderElection bool
var probeAddr string
var controllerDomain string
flag.StringVar(&metricsAddr, "metrics-bind-address", ":8080", "The address the metric endpoint binds to.")
flag.StringVar(&probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.")
flag.BoolVar(&enableLeaderElection, "leader-elect", false,
"Enable leader election for controller manager. "+
"Enabling this will ensure there is only one active controller manager.")
flag.StringVar(&controllerDomain, "controller-domain", "k8s.checklyhq.com", "Domain to use for annotations and finalizers.")
opts := zap.Options{
Development: true,
}
Expand All @@ -70,6 +72,8 @@ func main() {

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

setupLog.Info("Controller domain setup", "value", controllerDomain)

mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
Scheme: scheme,
Metrics: metricsserver.Options{
Expand Down Expand Up @@ -107,32 +111,36 @@ func main() {
client.SetAccountId(accountId)

if err = (&networkingcontrollers.IngressReconciler{
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),
ControllerDomain: controllerDomain,
}).SetupWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "Ingress")
os.Exit(1)
}
if err = (&checklycontrollers.ApiCheckReconciler{
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),
ApiClient: client,
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),
ApiClient: client,
ControllerDomain: controllerDomain,
}).SetupWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "ApiCheck")
os.Exit(1)
}
if err = (&checklycontrollers.GroupReconciler{
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),
ApiClient: client,
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),
ApiClient: client,
ControllerDomain: controllerDomain,
}).SetupWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "Group")
os.Exit(1)
}
if err = (&checklycontrollers.AlertChannelReconciler{
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),
ApiClient: client,
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),
ApiClient: client,
ControllerDomain: controllerDomain,
}).SetupWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "AlertChannel")
os.Exit(1)
Expand Down
1 change: 1 addition & 0 deletions config/manager/manager.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ spec:
- /manager
args:
- --leader-elect
- --controller-domain=k8s.checklyhq.com
image: controller:latest
name: manager
env:
Expand Down
8 changes: 7 additions & 1 deletion docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ If you just want to try out the checkly-operator, you need a local kubernetes in
First we'll download the provided `install.yaml` files, please change the version number accordingly, we might have newer [releases](https://github.com/checkly/checkly-operator/releases) since we've written these docs.

```bash
export CHECKLY_OPERATOR_RELEASE=v1.4.1
export CHECKLY_OPERATOR_RELEASE=v1.7.0
wget "https://github.com/checkly/checkly-operator/releases/download/$CHECKLY_OPERATOR_RELEASE/install-$CHECKLY_OPERATOR_RELEASE.yaml" -O install.yaml
unset CHECKLY_OPERATOR_RELEASE
```
Expand All @@ -53,6 +53,12 @@ You can apply the `install.yaml`, this will create the namespace, we need this t
kubectl apply -f install.yaml
```

#### Controller Domain

We're using a domain name for finalizers and annotations, the default value is `k8s.checklyhq.com`, but it can be changed by supplying the `--controller-domain=other.domain.tld` runtime option.

This option allows you to run multiple independent deployments of the operator and each would handle different resources based on the controller domain configuration.

### Create secret

Grab your [checklyhq.com](checklyhq.com) API key and Account ID, [the official docs](https://www.checklyhq.com/docs/integrations/pulumi/#define-your-checkly-account-id-and-api-key) can help you get this information. Substitute the values into the below command:
Expand Down
8 changes: 5 additions & 3 deletions internal/controller/checkly/alertchannel_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package checkly

import (
"context"
"fmt"

corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
Expand All @@ -36,8 +37,9 @@ import (
// AlertChannelReconciler reconciles a AlertChannel object
type AlertChannelReconciler struct {
client.Client
Scheme *runtime.Scheme
ApiClient checkly.Client
Scheme *runtime.Scheme
ApiClient checkly.Client
ControllerDomain string
}

//+kubebuilder:rbac:groups=k8s.checklyhq.com,resources=alertchannels,verbs=get;list;watch;create;update;patch;delete
Expand All @@ -55,7 +57,7 @@ func (r *AlertChannelReconciler) Reconcile(ctx context.Context, req ctrl.Request

logger.Info("Reconciler started")

acFinalizer := "k8s.checklyhq.com/finalizer"
acFinalizer := fmt.Sprintf("%s/finalizer", r.ControllerDomain)

ac := &checklyv1alpha1.AlertChannel{}

Expand Down
10 changes: 7 additions & 3 deletions internal/controller/checkly/alertchannel_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,11 +115,15 @@ var _ = Describe("ApiCheck Controller", func() {
Eventually(func() bool {
f := &checklyv1alpha1.AlertChannel{}
err := k8sClient.Get(context.Background(), acKey, f)
if len(f.Finalizers) == 1 && err == nil {
return true
} else {
if err != nil {
return false
}

for _, finalizer := range f.Finalizers {
Expect(finalizer).To(Equal("testing.domain.tld/finalizer"), "Finalizer should match")
}

return true
}, timeout, interval).Should(BeTrue())

// Update
Expand Down
8 changes: 5 additions & 3 deletions internal/controller/checkly/apicheck_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package checkly

import (
"context"
"fmt"

"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
Expand All @@ -35,8 +36,9 @@ import (
// ApiCheckReconciler reconciles a ApiCheck object
type ApiCheckReconciler struct {
client.Client
Scheme *runtime.Scheme
ApiClient checkly.Client
Scheme *runtime.Scheme
ApiClient checkly.Client
ControllerDomain string
}

//+kubebuilder:rbac:groups=k8s.checklyhq.com,resources=apichecks,verbs=get;list;watch;create;update;patch;delete
Expand All @@ -56,7 +58,7 @@ type ApiCheckReconciler struct {
func (r *ApiCheckReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
logger := log.FromContext(ctx)

apiCheckFinalizer := "k8s.checklyhq.com/finalizer"
apiCheckFinalizer := fmt.Sprintf("%s/finalizer", r.ControllerDomain)

apiCheck := &checklyv1alpha1.ApiCheck{}

Expand Down
10 changes: 7 additions & 3 deletions internal/controller/checkly/apicheck_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,11 +117,15 @@ var _ = Describe("ApiCheck Controller", func() {
Eventually(func() bool {
f := &checklyv1alpha1.ApiCheck{}
err := k8sClient.Get(context.Background(), key, f)
if len(f.Finalizers) == 1 && err == nil {
return true
} else {
if err != nil {
return false
}

for _, finalizer := range f.Finalizers {
Expect(finalizer).To(Equal("testing.domain.tld/finalizer"), "Finalizer should match")
}

return true
}, timeout, interval).Should(BeTrue())

// Delete
Expand Down
8 changes: 5 additions & 3 deletions internal/controller/checkly/group_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package checkly

import (
"context"
"fmt"

"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
Expand All @@ -35,8 +36,9 @@ import (
// GroupReconciler reconciles a Group object
type GroupReconciler struct {
client.Client
Scheme *runtime.Scheme
ApiClient checkly.Client
Scheme *runtime.Scheme
ApiClient checkly.Client
ControllerDomain string
}

//+kubebuilder:rbac:groups=k8s.checklyhq.com,resources=groups,verbs=get;list;watch;create;update;patch;delete
Expand All @@ -53,7 +55,7 @@ func (r *GroupReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl

logger.Info("Reconciler started")

groupFinalizer := "k8s.checklyhq.com/finalizer"
groupFinalizer := fmt.Sprintf("%s/finalizer", r.ControllerDomain)

group := &checklyv1alpha1.Group{}

Expand Down
10 changes: 7 additions & 3 deletions internal/controller/checkly/group_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,11 +111,15 @@ var _ = Describe("ApiCheck Controller", func() {
Eventually(func() bool {
f := &checklyv1alpha1.Group{}
err := k8sClient.Get(context.Background(), groupKey, f)
if len(f.Finalizers) == 1 && err == nil {
return true
} else {
if err != nil {
return false
}

for _, finalizer := range f.Finalizers {
Expect(finalizer).To(Equal("testing.domain.tld/finalizer"), "Finalizer should match")
}

return true
}, timeout, interval).Should(BeTrue())

// Update
Expand Down
23 changes: 14 additions & 9 deletions internal/controller/checkly/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,24 +168,29 @@ var _ = BeforeSuite(func() {
http.ListenAndServe(":5555", nil)
}()

testControllerDomain := "testing.domain.tld"

err = (&ApiCheckReconciler{
Client: k8sManager.GetClient(),
Scheme: k8sManager.GetScheme(),
ApiClient: testClient,
Client: k8sManager.GetClient(),
Scheme: k8sManager.GetScheme(),
ApiClient: testClient,
ControllerDomain: testControllerDomain,
}).SetupWithManager(k8sManager)
Expect(err).ToNot(HaveOccurred())

err = (&GroupReconciler{
Client: k8sManager.GetClient(),
Scheme: k8sManager.GetScheme(),
ApiClient: testClient,
Client: k8sManager.GetClient(),
Scheme: k8sManager.GetScheme(),
ApiClient: testClient,
ControllerDomain: testControllerDomain,
}).SetupWithManager(k8sManager)
Expect(err).ToNot(HaveOccurred())

err = (&AlertChannelReconciler{
Client: k8sManager.GetClient(),
Scheme: k8sManager.GetScheme(),
ApiClient: testClient,
Client: k8sManager.GetClient(),
Scheme: k8sManager.GetScheme(),
ApiClient: testClient,
ControllerDomain: testControllerDomain,
}).SetupWithManager(k8sManager)
Expect(err).ToNot(HaveOccurred())

Expand Down
9 changes: 6 additions & 3 deletions internal/controller/networking/ingress_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ import (
// IngressReconciler reconciles a Ingress object
type IngressReconciler struct {
client.Client
Scheme *runtime.Scheme
Scheme *runtime.Scheme
ControllerDomain string
}

//+kubebuilder:rbac:groups=networking.k8s.io,resources=ingresses,verbs=get;list;watch;update;patch
Expand All @@ -54,6 +55,8 @@ func (r *IngressReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ct
ingress := &networkingv1.Ingress{}
apiCheck := &checklyv1alpha1.ApiCheck{}

annotationEnabled := fmt.Sprintf("%s/enabled", r.ControllerDomain)

// Check if ingress object is still present
err := r.Get(ctx, req.NamespacedName, ingress)
if err != nil {
Expand All @@ -67,7 +70,7 @@ func (r *IngressReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ct
logger.Info("Ingress Object found")

// Check if annotation is present on the object
checklyAnnotation := ingress.Annotations["k8s.checklyhq.com/enabled"] == "true"
checklyAnnotation := ingress.Annotations[annotationEnabled] == "true"
if !checklyAnnotation {
// Annotation may have been removed or updated, we have to determine if we need to delete a previously created ApiCheck resource
logger.Info("annotation is not present, checking if ApiCheck was created")
Expand Down Expand Up @@ -138,7 +141,7 @@ func (r *IngressReconciler) SetupWithManager(mgr ctrl.Manager) error {

func (r *IngressReconciler) gatherApiCheckData(ingress *networkingv1.Ingress) (apiCheckSpec checklyv1alpha1.ApiCheckSpec, err error) {

annotationHost := "k8s.checklyhq.com"
annotationHost := r.ControllerDomain
annotationPath := fmt.Sprintf("%s/path", annotationHost)
annotationEndpoint := fmt.Sprintf("%s/endpoint", annotationHost)
annotationSuccess := fmt.Sprintf("%s/success", annotationHost)
Expand Down
28 changes: 14 additions & 14 deletions internal/controller/networking/ingress_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@ var _ = Describe("Ingress Controller", func() {
}

annotation := make(map[string]string)
annotation["k8s.checklyhq.com/enabled"] = "true"
annotation["k8s.checklyhq.com/path"] = testPath
annotation["k8s.checklyhq.com/success"] = testSuccessCode
annotation["k8s.checklyhq.com/group"] = testGroup
annotation["testing.domain.tld/enabled"] = "true"
annotation["testing.domain.tld/path"] = testPath
annotation["testing.domain.tld/success"] = testSuccessCode
annotation["testing.domain.tld/group"] = testGroup

rules := make([]networkingv1.IngressRule, 0)
rules = append(rules, networkingv1.IngressRule{
Expand Down Expand Up @@ -116,10 +116,10 @@ var _ = Describe("Ingress Controller", func() {
// Update
updatePath := "baaz"
updateHost := "foo.update"
annotation["k8s.checklyhq.com/path"] = updatePath
annotation["k8s.checklyhq.com/endpoint"] = updateHost
annotation["k8s.checklyhq.com/success"] = ""
annotation["k8s.checklyhq.com/muted"] = "false"
annotation["testing.domain.tld/path"] = updatePath
annotation["testing.domain.tld/endpoint"] = updateHost
annotation["testing.domain.tld/success"] = ""
annotation["testing.domain.tld/muted"] = "false"
ingress = &networkingv1.Ingress{
ObjectMeta: metav1.ObjectMeta{
Name: key.Name,
Expand Down Expand Up @@ -164,7 +164,7 @@ var _ = Describe("Ingress Controller", func() {
}, timeout, interval).Should(BeTrue())

// Remove enabled label
annotation["k8s.checklyhq.com/enabled"] = "false"
annotation["testing.domain.tld/enabled"] = "false"
ingress = &networkingv1.Ingress{
ObjectMeta: metav1.ObjectMeta{
Name: key.Name,
Expand Down Expand Up @@ -221,10 +221,10 @@ var _ = Describe("Ingress Controller", func() {
}

annotation := make(map[string]string)
annotation["k8s.checklyhq.com/enabled"] = "false"
annotation["k8s.checklyhq.com/path"] = testPath
annotation["k8s.checklyhq.com/success"] = testSuccessCode
annotation["k8s.checklyhq.com/muted"] = "false"
annotation["testing.domain.tld/enabled"] = "false"
annotation["testing.domain.tld/path"] = testPath
annotation["testing.domain.tld/success"] = testSuccessCode
annotation["testing.domain.tld/muted"] = "false"

rules := make([]networkingv1.IngressRule, 0)
rules = append(rules, networkingv1.IngressRule{
Expand Down Expand Up @@ -255,7 +255,7 @@ var _ = Describe("Ingress Controller", func() {

updated := &networkingv1.Ingress{}
Expect(k8sClient.Get(context.Background(), key, updated)).Should(Succeed())
annotation["k8s.checklyhq.com/enabled"] = "true"
annotation["testing.domain.tld/enabled"] = "true"
updated.Annotations = annotation
Expect(k8sClient.Update(context.Background(), updated)).Should(Succeed())

Expand Down
7 changes: 5 additions & 2 deletions internal/controller/networking/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,12 @@ var _ = BeforeSuite(func() {
})
Expect(err).ToNot(HaveOccurred())

testControllerDomain := "testing.domain.tld"

err = (&IngressReconciler{
Client: k8sManager.GetClient(),
Scheme: k8sManager.GetScheme(),
Client: k8sManager.GetClient(),
Scheme: k8sManager.GetScheme(),
ControllerDomain: testControllerDomain,
}).SetupWithManager(k8sManager)
Expect(err).ToNot(HaveOccurred())

Expand Down

0 comments on commit b308dea

Please sign in to comment.