Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(domain): add option to set controller domain #52

Merged
merged 1 commit into from
Nov 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.")
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This may not be the best naming of this ... but it's here, so please, suggest better ones and I'll update the PR.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've asked our k8s users for their opinion, but to me (as a lightweight user) it seems alright.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They are saying it's good 👍

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean if the controller-domain is the same concept as the prefix mentioned here

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, @pelzerim, correct, that's exactly what this is supposed to be, I just never seen this doc :D

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
sorccu marked this conversation as resolved.
Show resolved Hide resolved
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
Loading