refactor: implement control plane as controller-runtime manager
This commit is contained in:
parent
a5c170a478
commit
3104f50c58
67 changed files with 3693 additions and 261 deletions
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2024 Peter Kurfer.
|
||||
Copyright 2025 Peter Kurfer.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2024 Peter Kurfer.
|
||||
Copyright 2025 Peter Kurfer.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
|
|
@ -221,8 +221,8 @@ func (r *CoreAuthReconciler) reconcileAuthService(
|
|||
core.Labels,
|
||||
)
|
||||
|
||||
if _, ok := authService.Labels[meta.SupabaseLabel.EnvoyCluster]; !ok {
|
||||
authService.Labels[meta.SupabaseLabel.EnvoyCluster] = core.Name
|
||||
if _, ok := authService.Labels[meta.SupabaseLabel.ApiGatewayTarget]; !ok {
|
||||
authService.Labels[meta.SupabaseLabel.ApiGatewayTarget] = core.Name
|
||||
}
|
||||
|
||||
authService.Spec = corev1.ServiceSpec{
|
||||
|
|
|
@ -228,8 +228,8 @@ func (r *CorePostgrestReconiler) reconcilePostgrestService(
|
|||
core.Labels,
|
||||
)
|
||||
|
||||
if _, ok := postgrestService.Labels[meta.SupabaseLabel.EnvoyCluster]; !ok {
|
||||
postgrestService.Labels[meta.SupabaseLabel.EnvoyCluster] = core.Name
|
||||
if _, ok := postgrestService.Labels[meta.SupabaseLabel.ApiGatewayTarget]; !ok {
|
||||
postgrestService.Labels[meta.SupabaseLabel.ApiGatewayTarget] = ""
|
||||
}
|
||||
|
||||
postgrestService.Spec = corev1.ServiceSpec{
|
||||
|
|
|
@ -196,8 +196,8 @@ func (r *DashboardPGMetaReconciler) reconcilePGMetaService(
|
|||
dashboard.Labels,
|
||||
)
|
||||
|
||||
if _, ok := pgMetaService.Labels[meta.SupabaseLabel.EnvoyCluster]; !ok {
|
||||
pgMetaService.Labels[meta.SupabaseLabel.EnvoyCluster] = dashboard.Name
|
||||
if _, ok := pgMetaService.Labels[meta.SupabaseLabel.ApiGatewayTarget]; !ok {
|
||||
pgMetaService.Labels[meta.SupabaseLabel.ApiGatewayTarget] = ""
|
||||
}
|
||||
|
||||
pgMetaService.Spec = corev1.ServiceSpec{
|
||||
|
|
|
@ -218,8 +218,8 @@ func (r *DashboardStudioReconciler) reconcileStudioService(
|
|||
dashboard.Labels,
|
||||
)
|
||||
|
||||
if _, ok := studioService.Labels[meta.SupabaseLabel.EnvoyCluster]; !ok {
|
||||
studioService.Labels[meta.SupabaseLabel.EnvoyCluster] = dashboard.Name
|
||||
if _, ok := studioService.Labels[meta.SupabaseLabel.ApiGatewayTarget]; !ok {
|
||||
studioService.Labels[meta.SupabaseLabel.ApiGatewayTarget] = ""
|
||||
}
|
||||
|
||||
studioService.Spec = corev1.ServiceSpec{
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
// /*
|
||||
// Copyright 2025 Peter Kurfer.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// */
|
||||
|
||||
package controller
|
||||
|
||||
import (
|
||||
|
|
63
internal/controller/storage_controller.go
Normal file
63
internal/controller/storage_controller.go
Normal file
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
Copyright 2025 Peter Kurfer.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package controller
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/log"
|
||||
|
||||
supabasev1alpha1 "code.icb4dc0.de/prskr/supabase-operator/api/v1alpha1"
|
||||
)
|
||||
|
||||
// StorageReconciler reconciles a Storage object
|
||||
type StorageReconciler struct {
|
||||
client.Client
|
||||
Scheme *runtime.Scheme
|
||||
}
|
||||
|
||||
// +kubebuilder:rbac:groups=supabase.k8s.icb4dc0.de,resources=storages,verbs=get;list;watch;create;update;patch;delete
|
||||
// +kubebuilder:rbac:groups=supabase.k8s.icb4dc0.de,resources=storages/status,verbs=get;update;patch
|
||||
// +kubebuilder:rbac:groups=supabase.k8s.icb4dc0.de,resources=storages/finalizers,verbs=update
|
||||
|
||||
// Reconcile is part of the main kubernetes reconciliation loop which aims to
|
||||
// move the current state of the cluster closer to the desired state.
|
||||
// TODO(user): Modify the Reconcile function to compare the state specified by
|
||||
// the Storage object against the actual cluster state, and then
|
||||
// perform operations to make the cluster state reflect the state specified by
|
||||
// the user.
|
||||
//
|
||||
// For more details, check Reconcile and its Result here:
|
||||
// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.19.4/pkg/reconcile
|
||||
func (r *StorageReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
|
||||
_ = log.FromContext(ctx)
|
||||
|
||||
// TODO(user): your logic here
|
||||
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
|
||||
// SetupWithManager sets up the controller with the Manager.
|
||||
func (r *StorageReconciler) SetupWithManager(mgr ctrl.Manager) error {
|
||||
return ctrl.NewControllerManagedBy(mgr).
|
||||
For(&supabasev1alpha1.Storage{}).
|
||||
Named("storage").
|
||||
Complete(r)
|
||||
}
|
84
internal/controller/storage_controller_test.go
Normal file
84
internal/controller/storage_controller_test.go
Normal file
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
Copyright 2025 Peter Kurfer.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package controller
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
. "github.com/onsi/gomega"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"sigs.k8s.io/controller-runtime/pkg/reconcile"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
supabasev1alpha1 "code.icb4dc0.de/prskr/supabase-operator/api/v1alpha1"
|
||||
)
|
||||
|
||||
var _ = Describe("Storage Controller", func() {
|
||||
Context("When reconciling a resource", func() {
|
||||
const resourceName = "test-resource"
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
typeNamespacedName := types.NamespacedName{
|
||||
Name: resourceName,
|
||||
Namespace: "default", // TODO(user):Modify as needed
|
||||
}
|
||||
storage := &supabasev1alpha1.Storage{}
|
||||
|
||||
BeforeEach(func() {
|
||||
By("creating the custom resource for the Kind Storage")
|
||||
err := k8sClient.Get(ctx, typeNamespacedName, storage)
|
||||
if err != nil && errors.IsNotFound(err) {
|
||||
resource := &supabasev1alpha1.Storage{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: resourceName,
|
||||
Namespace: "default",
|
||||
},
|
||||
// TODO(user): Specify other spec details if needed.
|
||||
}
|
||||
Expect(k8sClient.Create(ctx, resource)).To(Succeed())
|
||||
}
|
||||
})
|
||||
|
||||
AfterEach(func() {
|
||||
// TODO(user): Cleanup logic after each test, like removing the resource instance.
|
||||
resource := &supabasev1alpha1.Storage{}
|
||||
err := k8sClient.Get(ctx, typeNamespacedName, resource)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
By("Cleanup the specific resource instance Storage")
|
||||
Expect(k8sClient.Delete(ctx, resource)).To(Succeed())
|
||||
})
|
||||
It("should successfully reconcile the resource", func() {
|
||||
By("Reconciling the created resource")
|
||||
controllerReconciler := &StorageReconciler{
|
||||
Client: k8sClient,
|
||||
Scheme: k8sClient.Scheme(),
|
||||
}
|
||||
|
||||
_, err := controllerReconciler.Reconcile(ctx, reconcile.Request{
|
||||
NamespacedName: typeNamespacedName,
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
// TODO(user): Add more specific assertions depending on your controller's reconciliation logic.
|
||||
// Example: If you expect a certain status condition after reconciliation, verify it here.
|
||||
})
|
||||
})
|
||||
})
|
Loading…
Add table
Add a link
Reference in a new issue