refactor: implement control plane as controller-runtime manager

This commit is contained in:
Peter 2025-01-20 17:06:41 +01:00
parent a5c170a478
commit 3104f50c58
Signed by: prskr
GPG key ID: F56BED6903BC5E37
67 changed files with 3693 additions and 261 deletions

View file

@ -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.
@ -54,15 +54,30 @@ type APIGatewaySpec struct {
Envoy *EnvoySpec `json:"envoy"`
// JWKSSelector - selector where the JWKS can be retrieved from to enable the API gateway to validate JWTs
JWKSSelector *corev1.SecretKeySelector `json:"jwks"`
// ServiceSelector - selector to match all Supabase services (or in fact EndpointSlices) that should be considered for this APIGateway
// +kubebuilder:default={"matchExpressions":{{"key": "app.kubernetes.io/part-of", "operator":"In", "values":{"supabase"}},{"key":"supabase.k8s.icb4dc0.de/api-gateway-target","operator":"Exists"}}}
ServiceSelector *metav1.LabelSelector `json:"serviceSelector"`
// ComponentTypeLabel - Label to identify which Supabase component a Service represents (e.g. auth, postgrest, ...)
// +kubebuilder:default="app.kubernetes.io/name"
ComponentTypeLabel string `json:"componentTypeLabel,omitempty"`
}
type EnvoyStatus struct {
ConfigVersion string `json:"configVersion,omitempty"`
ResourceHash []byte `json:"resourceHash,omitempty"`
}
// APIGatewayStatus defines the observed state of APIGateway.
type APIGatewayStatus struct{}
type APIGatewayStatus struct {
Envoy EnvoyStatus `json:"envoy,omitempty"`
ServiceTargets map[string][]string `json:"serviceTargets,omitempty"`
}
// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// APIGateway is the Schema for the apigateways API.
// +kubebuilder:printcolumn:name="EnvoyConfigVersion",type=string,JSONPath=`.status.envoy.configVersion`
type APIGateway struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

View file

@ -0,0 +1,64 @@
/*
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 v1alpha1
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
// StorageSpec defines the desired state of Storage.
type StorageSpec struct {
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
// Important: Run "make" to regenerate code after modifying this file
// Foo is an example field of Storage. Edit storage_types.go to remove/update
Foo string `json:"foo,omitempty"`
}
// StorageStatus defines the observed state of Storage.
type StorageStatus struct {
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
// Important: Run "make" to regenerate code after modifying this file
}
// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// Storage is the Schema for the storages API.
type Storage struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec StorageSpec `json:"spec,omitempty"`
Status StorageStatus `json:"status,omitempty"`
}
// +kubebuilder:object:root=true
// StorageList contains a list of Storage.
type StorageList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []Storage `json:"items"`
}
func init() {
SchemeBuilder.Register(&Storage{}, &StorageList{})
}

View file

@ -1,7 +1,7 @@
//go:build !ignore_autogenerated
/*
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.
@ -22,6 +22,7 @@ package v1alpha1
import (
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
runtime "k8s.io/apimachinery/pkg/runtime"
)
@ -31,7 +32,7 @@ func (in *APIGateway) DeepCopyInto(out *APIGateway) {
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
in.Spec.DeepCopyInto(&out.Spec)
out.Status = in.Status
in.Status.DeepCopyInto(&out.Status)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new APIGateway.
@ -97,6 +98,11 @@ func (in *APIGatewaySpec) DeepCopyInto(out *APIGatewaySpec) {
*out = new(v1.SecretKeySelector)
(*in).DeepCopyInto(*out)
}
if in.ServiceSelector != nil {
in, out := &in.ServiceSelector, &out.ServiceSelector
*out = new(metav1.LabelSelector)
(*in).DeepCopyInto(*out)
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new APIGatewaySpec.
@ -112,6 +118,23 @@ func (in *APIGatewaySpec) DeepCopy() *APIGatewaySpec {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *APIGatewayStatus) DeepCopyInto(out *APIGatewayStatus) {
*out = *in
in.Envoy.DeepCopyInto(&out.Envoy)
if in.ServiceTargets != nil {
in, out := &in.ServiceTargets, &out.ServiceTargets
*out = make(map[string][]string, len(*in))
for key, val := range *in {
var outVal []string
if val == nil {
(*out)[key] = nil
} else {
inVal := (*in)[key]
in, out := &inVal, &outVal
*out = make([]string, len(*in))
copy(*out, *in)
}
(*out)[key] = outVal
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new APIGatewayStatus.
@ -764,6 +787,26 @@ func (in *EnvoySpec) DeepCopy() *EnvoySpec {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *EnvoyStatus) DeepCopyInto(out *EnvoyStatus) {
*out = *in
if in.ResourceHash != nil {
in, out := &in.ResourceHash, &out.ResourceHash
*out = make([]byte, len(*in))
copy(*out, *in)
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EnvoyStatus.
func (in *EnvoyStatus) DeepCopy() *EnvoyStatus {
if in == nil {
return nil
}
out := new(EnvoyStatus)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *GithubAuthProvider) DeepCopyInto(out *GithubAuthProvider) {
*out = *in
@ -903,6 +946,95 @@ func (in *PostgrestSpec) DeepCopy() *PostgrestSpec {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Storage) DeepCopyInto(out *Storage) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
out.Spec = in.Spec
out.Status = in.Status
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Storage.
func (in *Storage) DeepCopy() *Storage {
if in == nil {
return nil
}
out := new(Storage)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *Storage) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *StorageList) DeepCopyInto(out *StorageList) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]Storage, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StorageList.
func (in *StorageList) DeepCopy() *StorageList {
if in == nil {
return nil
}
out := new(StorageList)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *StorageList) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *StorageSpec) DeepCopyInto(out *StorageSpec) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StorageSpec.
func (in *StorageSpec) DeepCopy() *StorageSpec {
if in == nil {
return nil
}
out := new(StorageSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *StorageStatus) DeepCopyInto(out *StorageStatus) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StorageStatus.
func (in *StorageStatus) DeepCopy() *StorageStatus {
if in == nil {
return nil
}
out := new(StorageStatus)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *StudioSpec) DeepCopyInto(out *StudioSpec) {
*out = *in