From b85a85e5fa1c91beff81c90959ecf8df970b4b98 Mon Sep 17 00:00:00 2001 From: Tim Riffer Date: Wed, 13 Nov 2024 13:40:26 +0100 Subject: [PATCH 01/10] Add rate limit api, controller and config files. Add build tag to handle go file scoping --- PROJECT | 9 ++ apis/ratelimit/v1alpha1/groupversion_info.go | 36 ++++++ apis/ratelimit/v1alpha1/ratelimit_types.go | 64 ++++++++++ .../v1alpha1/zz_generated.deepcopy.go | 114 ++++++++++++++++++ config/crd/kustomization.yaml | 1 + .../rbac/ratelimit_ratelimit_editor_role.yaml | 31 +++++ .../rbac/ratelimit_ratelimit_viewer_role.yaml | 27 +++++ .../samples/ratelimit_v1alpha1_ratelimit.yaml | 12 ++ controllers/ratelimit/feature_flag_dummy.go | 9 ++ controllers/ratelimit/ratelimit_controller.go | 72 +++++++++++ main.go | 9 +- 11 files changed, 383 insertions(+), 1 deletion(-) create mode 100644 apis/ratelimit/v1alpha1/groupversion_info.go create mode 100644 apis/ratelimit/v1alpha1/ratelimit_types.go create mode 100644 apis/ratelimit/v1alpha1/zz_generated.deepcopy.go create mode 100644 config/rbac/ratelimit_ratelimit_editor_role.yaml create mode 100644 config/rbac/ratelimit_ratelimit_viewer_role.yaml create mode 100644 config/samples/ratelimit_v1alpha1_ratelimit.yaml create mode 100644 controllers/ratelimit/feature_flag_dummy.go create mode 100644 controllers/ratelimit/ratelimit_controller.go diff --git a/PROJECT b/PROJECT index 1c436738e..82eec1a0c 100644 --- a/PROJECT +++ b/PROJECT @@ -29,4 +29,13 @@ resources: kind: APIGateway path: github.com/kyma-project/api-gateway/apis/operator/v1alpha1 version: v1alpha1 +- api: + crdVersion: v1 + namespaced: true + controller: true + domain: kyma-project.io + group: ratelimit + kind: RateLimit + path: github.com/kyma-project/api-gateway/apis/ratelimit/v1alpha1 + version: v1alpha1 version: "3" diff --git a/apis/ratelimit/v1alpha1/groupversion_info.go b/apis/ratelimit/v1alpha1/groupversion_info.go new file mode 100644 index 000000000..e8407259b --- /dev/null +++ b/apis/ratelimit/v1alpha1/groupversion_info.go @@ -0,0 +1,36 @@ +/* +Copyright 2022. + +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 contains API Schema definitions for the ratelimit v1alpha1 API group +// +kubebuilder:object:generate=true +// +groupName=ratelimit.kyma-project.io +package v1alpha1 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/scheme" +) + +var ( + // GroupVersion is group version used to register these objects + GroupVersion = schema.GroupVersion{Group: "ratelimit.kyma-project.io", Version: "v1alpha1"} + + // SchemeBuilder is used to add go types to the GroupVersionKind scheme + SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} + + // AddToScheme adds the types in this group-version to the given scheme. + AddToScheme = SchemeBuilder.AddToScheme +) diff --git a/apis/ratelimit/v1alpha1/ratelimit_types.go b/apis/ratelimit/v1alpha1/ratelimit_types.go new file mode 100644 index 000000000..2352d611b --- /dev/null +++ b/apis/ratelimit/v1alpha1/ratelimit_types.go @@ -0,0 +1,64 @@ +/* +Copyright 2022. + +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. + +// RateLimitSpec defines the desired state of RateLimit +type RateLimitSpec 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 RateLimit. Edit ratelimit_types.go to remove/update + Foo string `json:"foo,omitempty"` +} + +// RateLimitStatus defines the observed state of RateLimit +type RateLimitStatus 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 + +// RateLimit is the Schema for the ratelimits API +type RateLimit struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec RateLimitSpec `json:"spec,omitempty"` + Status RateLimitStatus `json:"status,omitempty"` +} + +//+kubebuilder:object:root=true + +// RateLimitList contains a list of RateLimit +type RateLimitList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []RateLimit `json:"items"` +} + +func init() { + SchemeBuilder.Register(&RateLimit{}, &RateLimitList{}) +} diff --git a/apis/ratelimit/v1alpha1/zz_generated.deepcopy.go b/apis/ratelimit/v1alpha1/zz_generated.deepcopy.go new file mode 100644 index 000000000..b915f6b35 --- /dev/null +++ b/apis/ratelimit/v1alpha1/zz_generated.deepcopy.go @@ -0,0 +1,114 @@ +//go:build !ignore_autogenerated + +/* +Copyright 2022. + +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. +*/ + +// Code generated by controller-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RateLimit) DeepCopyInto(out *RateLimit) { + *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 RateLimit. +func (in *RateLimit) DeepCopy() *RateLimit { + if in == nil { + return nil + } + out := new(RateLimit) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *RateLimit) 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 *RateLimitList) DeepCopyInto(out *RateLimitList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]RateLimit, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RateLimitList. +func (in *RateLimitList) DeepCopy() *RateLimitList { + if in == nil { + return nil + } + out := new(RateLimitList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *RateLimitList) 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 *RateLimitSpec) DeepCopyInto(out *RateLimitSpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RateLimitSpec. +func (in *RateLimitSpec) DeepCopy() *RateLimitSpec { + if in == nil { + return nil + } + out := new(RateLimitSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RateLimitStatus) DeepCopyInto(out *RateLimitStatus) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RateLimitStatus. +func (in *RateLimitStatus) DeepCopy() *RateLimitStatus { + if in == nil { + return nil + } + out := new(RateLimitStatus) + in.DeepCopyInto(out) + return out +} diff --git a/config/crd/kustomization.yaml b/config/crd/kustomization.yaml index bb5d8a7f4..d0e4f98e7 100644 --- a/config/crd/kustomization.yaml +++ b/config/crd/kustomization.yaml @@ -4,6 +4,7 @@ resources: - bases/gateway.kyma-project.io_apirules.yaml - bases/operator.kyma-project.io_apigateways.yaml +- bases/ratelimit.kyma-project.io_ratelimits.yaml #+kubebuilder:scaffold:crdkustomizeresource labels: diff --git a/config/rbac/ratelimit_ratelimit_editor_role.yaml b/config/rbac/ratelimit_ratelimit_editor_role.yaml new file mode 100644 index 000000000..52c9d1a98 --- /dev/null +++ b/config/rbac/ratelimit_ratelimit_editor_role.yaml @@ -0,0 +1,31 @@ +# permissions for end users to edit ratelimits. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: clusterrole + app.kubernetes.io/instance: ratelimit-editor-role + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: api-gateway + app.kubernetes.io/part-of: api-gateway + app.kubernetes.io/managed-by: kustomize + name: ratelimit-editor-role +rules: +- apiGroups: + - ratelimit.kyma-project.io + resources: + - ratelimits + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - ratelimit.kyma-project.io + resources: + - ratelimits/status + verbs: + - get diff --git a/config/rbac/ratelimit_ratelimit_viewer_role.yaml b/config/rbac/ratelimit_ratelimit_viewer_role.yaml new file mode 100644 index 000000000..3f5606e35 --- /dev/null +++ b/config/rbac/ratelimit_ratelimit_viewer_role.yaml @@ -0,0 +1,27 @@ +# permissions for end users to view ratelimits. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: clusterrole + app.kubernetes.io/instance: ratelimit-viewer-role + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: api-gateway + app.kubernetes.io/part-of: api-gateway + app.kubernetes.io/managed-by: kustomize + name: ratelimit-viewer-role +rules: +- apiGroups: + - ratelimit.kyma-project.io + resources: + - ratelimits + verbs: + - get + - list + - watch +- apiGroups: + - ratelimit.kyma-project.io + resources: + - ratelimits/status + verbs: + - get diff --git a/config/samples/ratelimit_v1alpha1_ratelimit.yaml b/config/samples/ratelimit_v1alpha1_ratelimit.yaml new file mode 100644 index 000000000..9d4b37609 --- /dev/null +++ b/config/samples/ratelimit_v1alpha1_ratelimit.yaml @@ -0,0 +1,12 @@ +apiVersion: ratelimit.kyma-project.io/v1alpha1 +kind: RateLimit +metadata: + labels: + app.kubernetes.io/name: ratelimit + app.kubernetes.io/instance: ratelimit-sample + app.kubernetes.io/part-of: api-gateway + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/created-by: api-gateway + name: ratelimit-sample +spec: + diff --git a/controllers/ratelimit/feature_flag_dummy.go b/controllers/ratelimit/feature_flag_dummy.go new file mode 100644 index 000000000..2da9fa59b --- /dev/null +++ b/controllers/ratelimit/feature_flag_dummy.go @@ -0,0 +1,9 @@ +//go:build !ratelimit + +package ratelimit + +import "sigs.k8s.io/controller-runtime/pkg/manager" + +func Setup(_ manager.Manager) error { + return nil +} diff --git a/controllers/ratelimit/ratelimit_controller.go b/controllers/ratelimit/ratelimit_controller.go new file mode 100644 index 000000000..9bd833621 --- /dev/null +++ b/controllers/ratelimit/ratelimit_controller.go @@ -0,0 +1,72 @@ +//go:build ratelimit + +/* +Copyright 2022. + +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 ratelimit + +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" + "sigs.k8s.io/controller-runtime/pkg/manager" + + ratelimitv1alpha1 "github.com/kyma-project/api-gateway/apis/ratelimit/v1alpha1" +) + +func init() { + utilruntime.Must(ratelimitv1alpha1.AddToScheme(scheme)) +} + +// Reconciler reconciles a RateLimit object +type Reconciler struct { + client.Client + Scheme *runtime.Scheme +} + +func Setup(mgr manager.Manager) error { + return (&Reconciler{ + Client: mgr.GetClient(), + Scheme: mgr.GetScheme(), + }).SetupWithManager(mgr) +} + +//+kubebuilder:rbac:groups=ratelimit.kyma-project.io,resources=ratelimits,verbs=get;list;watch;create;update;patch;delete +//+kubebuilder:rbac:groups=ratelimit.kyma-project.io,resources=ratelimits/status,verbs=get;update;patch +//+kubebuilder:rbac:groups=ratelimit.kyma-project.io,resources=ratelimits/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. +// the RateLimit 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.14.1/pkg/reconcile +func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { + _ = log.FromContext(ctx) + + return ctrl.Result{}, nil +} + +// SetupWithManager sets up the controller with the Manager. +func (r *Reconciler) SetupWithManager(mgr ctrl.Manager) error { + return ctrl.NewControllerManagedBy(mgr). + For(&ratelimitv1alpha1.RateLimit{}). + Complete(r) +} diff --git a/main.go b/main.go index d8b465399..fcb686c31 100644 --- a/main.go +++ b/main.go @@ -56,10 +56,12 @@ import ( certv1alpha1 "github.com/gardener/cert-management/pkg/apis/cert/v1alpha1" dnsv1alpha1 "github.com/gardener/external-dns-management/pkg/apis/dns/v1alpha1" - operatorv1alpha1 "github.com/kyma-project/api-gateway/apis/operator/v1alpha1" rulev1alpha1 "github.com/ory/oathkeeper-maester/api/v1alpha1" networkingv1beta1 "istio.io/client-go/pkg/apis/networking/v1beta1" securityv1beta1 "istio.io/client-go/pkg/apis/security/v1beta1" + + operatorv1alpha1 "github.com/kyma-project/api-gateway/apis/operator/v1alpha1" + "github.com/kyma-project/api-gateway/controllers/ratelimit" //+kubebuilder:scaffold:imports ) @@ -239,6 +241,11 @@ func main() { setupLog.Error(err, "Unable to create webhook", "webhook", "APIRule") os.Exit(1) } + + if err = ratelimit.Setup(mgr); err != nil { + setupLog.Error(err, "unable to create controller", "controller", "RateLimit") + os.Exit(1) + } //+kubebuilder:scaffold:builder if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil { From 0b1191261974b82b4dc18772b6d553ff49f21745 Mon Sep 17 00:00:00 2001 From: Tim Riffer Date: Wed, 13 Nov 2024 13:41:06 +0100 Subject: [PATCH 02/10] Add RateLimit CRD --- .../ratelimit.kyma-project.io_ratelimits.yaml | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 config/crd/bases/ratelimit.kyma-project.io_ratelimits.yaml diff --git a/config/crd/bases/ratelimit.kyma-project.io_ratelimits.yaml b/config/crd/bases/ratelimit.kyma-project.io_ratelimits.yaml new file mode 100644 index 000000000..12460e164 --- /dev/null +++ b/config/crd/bases/ratelimit.kyma-project.io_ratelimits.yaml @@ -0,0 +1,54 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + name: ratelimits.ratelimit.kyma-project.io +spec: + group: ratelimit.kyma-project.io + names: + kind: RateLimit + listKind: RateLimitList + plural: ratelimits + singular: ratelimit + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: RateLimit is the Schema for the ratelimits API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: RateLimitSpec defines the desired state of RateLimit + properties: + foo: + description: Foo is an example field of RateLimit. Edit ratelimit_types.go + to remove/update + type: string + type: object + status: + description: RateLimitStatus defines the observed state of RateLimit + type: object + type: object + served: true + storage: true + subresources: + status: {} From 27f1bb17532a25c174d87461c24ce011e0348743 Mon Sep 17 00:00:00 2001 From: Tim Riffer Date: Wed, 13 Nov 2024 15:40:44 +0100 Subject: [PATCH 03/10] Remove unnecessary files --- .../rbac/ratelimit_ratelimit_editor_role.yaml | 31 ------------------- .../rbac/ratelimit_ratelimit_viewer_role.yaml | 27 ---------------- 2 files changed, 58 deletions(-) delete mode 100644 config/rbac/ratelimit_ratelimit_editor_role.yaml delete mode 100644 config/rbac/ratelimit_ratelimit_viewer_role.yaml diff --git a/config/rbac/ratelimit_ratelimit_editor_role.yaml b/config/rbac/ratelimit_ratelimit_editor_role.yaml deleted file mode 100644 index 52c9d1a98..000000000 --- a/config/rbac/ratelimit_ratelimit_editor_role.yaml +++ /dev/null @@ -1,31 +0,0 @@ -# permissions for end users to edit ratelimits. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: ratelimit-editor-role - app.kubernetes.io/component: rbac - app.kubernetes.io/created-by: api-gateway - app.kubernetes.io/part-of: api-gateway - app.kubernetes.io/managed-by: kustomize - name: ratelimit-editor-role -rules: -- apiGroups: - - ratelimit.kyma-project.io - resources: - - ratelimits - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - ratelimit.kyma-project.io - resources: - - ratelimits/status - verbs: - - get diff --git a/config/rbac/ratelimit_ratelimit_viewer_role.yaml b/config/rbac/ratelimit_ratelimit_viewer_role.yaml deleted file mode 100644 index 3f5606e35..000000000 --- a/config/rbac/ratelimit_ratelimit_viewer_role.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# permissions for end users to view ratelimits. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: ratelimit-viewer-role - app.kubernetes.io/component: rbac - app.kubernetes.io/created-by: api-gateway - app.kubernetes.io/part-of: api-gateway - app.kubernetes.io/managed-by: kustomize - name: ratelimit-viewer-role -rules: -- apiGroups: - - ratelimit.kyma-project.io - resources: - - ratelimits - verbs: - - get - - list - - watch -- apiGroups: - - ratelimit.kyma-project.io - resources: - - ratelimits/status - verbs: - - get From 7290d3fd3d80cb2b6ce9c8ad8f26911f4b3053e5 Mon Sep 17 00:00:00 2001 From: Tim Riffer Date: Thu, 14 Nov 2024 09:31:30 +0100 Subject: [PATCH 04/10] Remove ratelimit CRD when creating manifests for release --- Makefile | 2 +- config/prod/kustomization.yaml | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 config/prod/kustomization.yaml diff --git a/Makefile b/Makefile index f1823b748..2e8732d37 100644 --- a/Makefile +++ b/Makefile @@ -244,7 +244,7 @@ module-image: docker-build docker-push ## Build the Module Image and push it to .PHONY: generate-manifests generate-manifests: kustomize module-version cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG} - $(KUSTOMIZE) build config/default > api-gateway-manager.yaml + $(KUSTOMIZE) build config/prod > api-gateway-manager.yaml .PHONY: get-latest-release get-latest-release: diff --git a/config/prod/kustomization.yaml b/config/prod/kustomization.yaml new file mode 100644 index 000000000..0948ff387 --- /dev/null +++ b/config/prod/kustomization.yaml @@ -0,0 +1,14 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: + - ../default + +# Remove CRDs that belong to a feature is not released. +patchesStrategicMerge: + - |- + apiVersion: apiextensions.k8s.io/v1 + kind: CustomResourceDefinition + metadata: + name: ratelimits.ratelimit.kyma-project.io + $patch: delete From 4e0a895213c5a9a733b39aad2c70a26abee7475b Mon Sep 17 00:00:00 2001 From: Tim Riffer Date: Thu, 14 Nov 2024 11:29:19 +0100 Subject: [PATCH 05/10] Add dummy unit test for ratelimit controller --- controllers/ratelimit/feature_flag_dummy.go | 9 ------ controllers/ratelimit/feature_off.go | 12 ++++++++ controllers/ratelimit/feature_on.go | 18 +++++++++++ controllers/ratelimit/ratelimit_controller.go | 17 +---------- .../ratelimit/ratelimit_controller_test.go | 30 +++++++++++++++++++ controllers/ratelimit/suite_test.go | 18 +++++++++++ main.go | 2 +- 7 files changed, 80 insertions(+), 26 deletions(-) delete mode 100644 controllers/ratelimit/feature_flag_dummy.go create mode 100644 controllers/ratelimit/feature_off.go create mode 100644 controllers/ratelimit/feature_on.go create mode 100644 controllers/ratelimit/ratelimit_controller_test.go create mode 100644 controllers/ratelimit/suite_test.go diff --git a/controllers/ratelimit/feature_flag_dummy.go b/controllers/ratelimit/feature_flag_dummy.go deleted file mode 100644 index 2da9fa59b..000000000 --- a/controllers/ratelimit/feature_flag_dummy.go +++ /dev/null @@ -1,9 +0,0 @@ -//go:build !ratelimit - -package ratelimit - -import "sigs.k8s.io/controller-runtime/pkg/manager" - -func Setup(_ manager.Manager) error { - return nil -} diff --git a/controllers/ratelimit/feature_off.go b/controllers/ratelimit/feature_off.go new file mode 100644 index 000000000..855cf4c07 --- /dev/null +++ b/controllers/ratelimit/feature_off.go @@ -0,0 +1,12 @@ +//go:build !ratelimit + +package ratelimit + +import ( + "k8s.io/apimachinery/pkg/runtime" + "sigs.k8s.io/controller-runtime/pkg/manager" +) + +func Setup(_ manager.Manager, _ *runtime.Scheme) error { + return nil +} diff --git a/controllers/ratelimit/feature_on.go b/controllers/ratelimit/feature_on.go new file mode 100644 index 000000000..16fc202d9 --- /dev/null +++ b/controllers/ratelimit/feature_on.go @@ -0,0 +1,18 @@ +//go:build ratelimit + +package ratelimit + +import ( + ratelimitv1alpha1 "github.com/kyma-project/api-gateway/apis/ratelimit/v1alpha1" + "k8s.io/apimachinery/pkg/runtime" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + "sigs.k8s.io/controller-runtime/pkg/manager" +) + +func Setup(mgr manager.Manager, scheme *runtime.Scheme) error { + utilruntime.Must(ratelimitv1alpha1.AddToScheme(scheme)) + return (&Reconciler{ + Client: mgr.GetClient(), + Scheme: mgr.GetScheme(), + }).SetupWithManager(mgr) +} diff --git a/controllers/ratelimit/ratelimit_controller.go b/controllers/ratelimit/ratelimit_controller.go index 9bd833621..ed9db61ca 100644 --- a/controllers/ratelimit/ratelimit_controller.go +++ b/controllers/ratelimit/ratelimit_controller.go @@ -1,5 +1,3 @@ -//go:build ratelimit - /* Copyright 2022. @@ -20,32 +18,19 @@ package ratelimit import ( "context" + ratelimitv1alpha1 "github.com/kyma-project/api-gateway/apis/ratelimit/v1alpha1" "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" - "sigs.k8s.io/controller-runtime/pkg/manager" - - ratelimitv1alpha1 "github.com/kyma-project/api-gateway/apis/ratelimit/v1alpha1" ) -func init() { - utilruntime.Must(ratelimitv1alpha1.AddToScheme(scheme)) -} - // Reconciler reconciles a RateLimit object type Reconciler struct { client.Client Scheme *runtime.Scheme } -func Setup(mgr manager.Manager) error { - return (&Reconciler{ - Client: mgr.GetClient(), - Scheme: mgr.GetScheme(), - }).SetupWithManager(mgr) -} - //+kubebuilder:rbac:groups=ratelimit.kyma-project.io,resources=ratelimits,verbs=get;list;watch;create;update;patch;delete //+kubebuilder:rbac:groups=ratelimit.kyma-project.io,resources=ratelimits/status,verbs=get;update;patch //+kubebuilder:rbac:groups=ratelimit.kyma-project.io,resources=ratelimits/finalizers,verbs=update diff --git a/controllers/ratelimit/ratelimit_controller_test.go b/controllers/ratelimit/ratelimit_controller_test.go new file mode 100644 index 000000000..c5afcb005 --- /dev/null +++ b/controllers/ratelimit/ratelimit_controller_test.go @@ -0,0 +1,30 @@ +package ratelimit_test + +import ( + "context" + "github.com/kyma-project/api-gateway/controllers/ratelimit" + "k8s.io/apimachinery/pkg/runtime" + + "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/reconcile" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +var _ = Describe("Rate Limit Controller", func() { + It("Dummy test", func() { + + r := ratelimit.Reconciler{ + Scheme: runtime.NewScheme(), + } + + result, err := r.Reconcile(context.Background(), reconcile.Request{NamespacedName: types.NamespacedName{Namespace: "test", Name: "test"}}) + + Expect(err).ShouldNot(HaveOccurred()) + Expect(result).Should(Equal(reconcile.Result{ + Requeue: false, + })) + }) + +}) diff --git a/controllers/ratelimit/suite_test.go b/controllers/ratelimit/suite_test.go new file mode 100644 index 000000000..cc1bc24b8 --- /dev/null +++ b/controllers/ratelimit/suite_test.go @@ -0,0 +1,18 @@ +package ratelimit_test + +import ( + "github.com/kyma-project/api-gateway/tests" + . "github.com/onsi/ginkgo/v2" + "github.com/onsi/ginkgo/v2/types" + . "github.com/onsi/gomega" + "testing" +) + +func Test(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Ratelimit Controller Suite") +} + +var _ = ReportAfterSuite("custom reporter", func(report types.Report) { + tests.GenerateGinkgoJunitReport("ratelimit-controller-suite", report) +}) diff --git a/main.go b/main.go index fcb686c31..993c0ca3b 100644 --- a/main.go +++ b/main.go @@ -242,7 +242,7 @@ func main() { os.Exit(1) } - if err = ratelimit.Setup(mgr); err != nil { + if err = ratelimit.Setup(mgr, scheme); err != nil { setupLog.Error(err, "unable to create controller", "controller", "RateLimit") os.Exit(1) } From d71eac054b4d6bd8efca9d628c9a28379b91a108 Mon Sep 17 00:00:00 2001 From: Tim Riffer Date: Thu, 14 Nov 2024 12:01:00 +0100 Subject: [PATCH 06/10] Add go build tag support in Dockerfile Add ratelimit build tag to development make targets --- Dockerfile | 3 ++- Makefile | 10 +++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/Dockerfile b/Dockerfile index ef3fe9a23..ab58e37eb 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,6 +2,7 @@ FROM golang:1.23.3-alpine AS builder ARG TARGET_OS ARG TARGET_ARCH +ARG GO_BUILD_TAGS ARG VERSION WORKDIR /api-gateway-build @@ -24,7 +25,7 @@ COPY manifests/ manifests/ # was called. For example, if we call make docker-build in a local env which has the Apple Silicon M1 SO # the docker BUILDPLATFORM arg will be linux/arm64 when for Apple x86 it will be linux/amd64. Therefore, # by leaving it empty we can ensure that the container and binary shipped on it will have the same platform. -RUN CGO_ENABLED=0 GOOS=${TARGET_OS:-linux} GOARCH=${TARGET_ARCH:-amd64} go build -ldflags="-X 'github.com/kyma-project/api-gateway/internal/version.version=${VERSION:-}'" -a -o manager main.go +RUN CGO_ENABLED=0 GOOS=${TARGET_OS:-linux} GOARCH=${TARGET_ARCH:-amd64} go build -tags ${GO_BUILD_TAGS} -ldflags="-X 'github.com/kyma-project/api-gateway/internal/version.version=${VERSION:-}'" -a -o manager main.go # Use distroless as minimal base image to package the manager binary diff --git a/Makefile b/Makefile index 2e8732d37..89eb19db5 100644 --- a/Makefile +++ b/Makefile @@ -89,7 +89,7 @@ vet: ## Run go vet against code. .PHONY: test test: manifests generate fmt vet envtest ## Generate manifests and run tests. - KUBEBUILDER_CONTROLPLANE_START_TIMEOUT=2m KUBEBUILDER_CONTROLPLANE_STOP_TIMEOUT=2m KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) -p path)" go test $(shell go list ./... | grep -v /tests/integration) -coverprofile cover.out + KUBEBUILDER_CONTROLPLANE_START_TIMEOUT=2m KUBEBUILDER_CONTROLPLANE_STOP_TIMEOUT=2m KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) -p path)" go test -tags ratelimit $(shell go list ./... | grep -v /tests/integration) -coverprofile cover.out .PHONY: test-integration test-integration: test-integration-v2alpha1 test-integration-ory test-integration-istio test-integration-gateway @@ -134,15 +134,15 @@ install-istio: create-namespace .PHONY: build build: generate fmt vet ## Build manager binary. - go build -o bin/manager main.go + go build -tags ratelimit -o bin/manager main.go .PHONY: run -run: manifests build - go run ./main.go +run: manifests generate fmt vet + go run -tags ratelimit ./main.go .PHONY: docker-build docker-build: - IMG=$(IMG) docker build -t ${IMG} --build-arg TARGET_OS=${TARGET_OS} --build-arg TARGET_ARCH=${TARGET_ARCH} --build-arg VERSION=${VERSION} . + IMG=$(IMG) docker build -t ${IMG} --build-arg GO_BUILD_TAGS=ratelimit --build-arg TARGET_OS=${TARGET_OS} --build-arg TARGET_ARCH=${TARGET_ARCH} --build-arg VERSION=${VERSION} . .PHONY: docker-push docker-push: ## Push docker image with the manager. From 84bd668e0d4a78067c1e6cdd91ad46c88a015405 Mon Sep 17 00:00:00 2001 From: Tim Riffer Date: Thu, 14 Nov 2024 14:44:01 +0100 Subject: [PATCH 07/10] Add handling of manager ClusterRole rules for ratelimit by introducing dev overlay --- Makefile | 4 +- config/dev/kustomization.yaml | 60 +++++++++++++++++++ controllers/ratelimit/ratelimit_controller.go | 8 +-- 3 files changed, 66 insertions(+), 6 deletions(-) create mode 100644 config/dev/kustomization.yaml diff --git a/Makefile b/Makefile index 89eb19db5..792d25241 100644 --- a/Makefile +++ b/Makefile @@ -188,11 +188,11 @@ create-namespace: .PHONY: deploy deploy: manifests kustomize module-version create-namespace ## Deploy controller to the K8s cluster specified in ~/.kube/config. cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG} - $(KUSTOMIZE) build config/default | kubectl apply -f - + $(KUSTOMIZE) build config/dev | kubectl apply -f - .PHONY: undeploy undeploy: ## Undeploy controller from the K8s cluster specified in ~/.kube/config. Call with ignore-not-found=true to ignore resource not found errors during deletion. - $(KUSTOMIZE) build config/default | kubectl delete --ignore-not-found=$(ignore-not-found) -f - + $(KUSTOMIZE) build config/dev | kubectl delete --ignore-not-found=$(ignore-not-found) -f - ##@ Build Dependencies diff --git a/config/dev/kustomization.yaml b/config/dev/kustomization.yaml new file mode 100644 index 000000000..3434b990b --- /dev/null +++ b/config/dev/kustomization.yaml @@ -0,0 +1,60 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: + - ../default + +patches: + - patch: |- + - op: add + path: /rules/- + value: + apiGroups: + - ratelimit.kyma-project.io + resources: + - ratelimits + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + target: + group: rbac.authorization.k8s.io + version: v1 + kind: ClusterRole + name: manager-role + - patch: |- + - op: add + path: /rules/- + value: + apiGroups: + - ratelimit.kyma-project.io + resources: + - ratelimits/finalizers + verbs: + - update + target: + group: rbac.authorization.k8s.io + version: v1 + kind: ClusterRole + name: manager-role + - patch: |- + - op: add + path: /rules/- + value: + apiGroups: + - ratelimit.kyma-project.io + resources: + - ratelimits/status + verbs: + - get + - patch + - update + target: + group: rbac.authorization.k8s.io + version: v1 + kind: ClusterRole + name: manager-role \ No newline at end of file diff --git a/controllers/ratelimit/ratelimit_controller.go b/controllers/ratelimit/ratelimit_controller.go index ed9db61ca..aa1e2eba5 100644 --- a/controllers/ratelimit/ratelimit_controller.go +++ b/controllers/ratelimit/ratelimit_controller.go @@ -31,9 +31,9 @@ type Reconciler struct { Scheme *runtime.Scheme } -//+kubebuilder:rbac:groups=ratelimit.kyma-project.io,resources=ratelimits,verbs=get;list;watch;create;update;patch;delete -//+kubebuilder:rbac:groups=ratelimit.kyma-project.io,resources=ratelimits/status,verbs=get;update;patch -//+kubebuilder:rbac:groups=ratelimit.kyma-project.io,resources=ratelimits/finalizers,verbs=update +// There should be no kubebuilder:rbac markers in this file as it's hard to modify the ClusterRole rules array in +// kustomize. The roles are managed in the file config/dev/kustomization.yaml. Once this feature is ready for release, +// the markers can be added again. // Reconcile is part of the main kubernetes reconciliation loop which aims to // move the current state of the cluster closer to the desired state. @@ -43,7 +43,7 @@ type Reconciler struct { // // For more details, check Reconcile and its Result here: // - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.14.1/pkg/reconcile -func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { +func (r *Reconciler) Reconcile(ctx context.Context, _ ctrl.Request) (ctrl.Result, error) { _ = log.FromContext(ctx) return ctrl.Result{}, nil From 98e570f25d590da33012c860ddad405cef41ab09 Mon Sep 17 00:00:00 2001 From: Tim Riffer Date: Thu, 14 Nov 2024 15:07:01 +0100 Subject: [PATCH 08/10] Rename feature toggle build tag to make it reusable for upcoming features --- Makefile | 8 ++++---- .../ratelimit/{feature_off.go => feature_disabled.go} | 2 +- .../ratelimit/{feature_on.go => feature_enabled.go} | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) rename controllers/ratelimit/{feature_off.go => feature_disabled.go} (85%) rename controllers/ratelimit/{feature_on.go => feature_enabled.go} (93%) diff --git a/Makefile b/Makefile index 792d25241..60319602b 100644 --- a/Makefile +++ b/Makefile @@ -89,7 +89,7 @@ vet: ## Run go vet against code. .PHONY: test test: manifests generate fmt vet envtest ## Generate manifests and run tests. - KUBEBUILDER_CONTROLPLANE_START_TIMEOUT=2m KUBEBUILDER_CONTROLPLANE_STOP_TIMEOUT=2m KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) -p path)" go test -tags ratelimit $(shell go list ./... | grep -v /tests/integration) -coverprofile cover.out + KUBEBUILDER_CONTROLPLANE_START_TIMEOUT=2m KUBEBUILDER_CONTROLPLANE_STOP_TIMEOUT=2m KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) -p path)" go test -tags enable_dev_features $(shell go list ./... | grep -v /tests/integration) -coverprofile cover.out .PHONY: test-integration test-integration: test-integration-v2alpha1 test-integration-ory test-integration-istio test-integration-gateway @@ -134,15 +134,15 @@ install-istio: create-namespace .PHONY: build build: generate fmt vet ## Build manager binary. - go build -tags ratelimit -o bin/manager main.go + go build -tags enable_dev_features -o bin/manager main.go .PHONY: run run: manifests generate fmt vet - go run -tags ratelimit ./main.go + go run -tags enable_dev_features ./main.go .PHONY: docker-build docker-build: - IMG=$(IMG) docker build -t ${IMG} --build-arg GO_BUILD_TAGS=ratelimit --build-arg TARGET_OS=${TARGET_OS} --build-arg TARGET_ARCH=${TARGET_ARCH} --build-arg VERSION=${VERSION} . + IMG=$(IMG) docker build -t ${IMG} --build-arg GO_BUILD_TAGS=enable_dev_features --build-arg TARGET_OS=${TARGET_OS} --build-arg TARGET_ARCH=${TARGET_ARCH} --build-arg VERSION=${VERSION} . .PHONY: docker-push docker-push: ## Push docker image with the manager. diff --git a/controllers/ratelimit/feature_off.go b/controllers/ratelimit/feature_disabled.go similarity index 85% rename from controllers/ratelimit/feature_off.go rename to controllers/ratelimit/feature_disabled.go index 855cf4c07..92f896f22 100644 --- a/controllers/ratelimit/feature_off.go +++ b/controllers/ratelimit/feature_disabled.go @@ -1,4 +1,4 @@ -//go:build !ratelimit +//go:build !enable_dev_features package ratelimit diff --git a/controllers/ratelimit/feature_on.go b/controllers/ratelimit/feature_enabled.go similarity index 93% rename from controllers/ratelimit/feature_on.go rename to controllers/ratelimit/feature_enabled.go index 16fc202d9..ab49a6e57 100644 --- a/controllers/ratelimit/feature_on.go +++ b/controllers/ratelimit/feature_enabled.go @@ -1,4 +1,4 @@ -//go:build ratelimit +//go:build enable_dev_features package ratelimit From c534b8548ee8f44485fff7b26eab73125edb9187 Mon Sep 17 00:00:00 2001 From: Tim Riffer Date: Thu, 14 Nov 2024 15:09:24 +0100 Subject: [PATCH 09/10] Fix typo in comment --- config/prod/kustomization.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/prod/kustomization.yaml b/config/prod/kustomization.yaml index 0948ff387..d7a88a225 100644 --- a/config/prod/kustomization.yaml +++ b/config/prod/kustomization.yaml @@ -4,7 +4,7 @@ kind: Kustomization resources: - ../default -# Remove CRDs that belong to a feature is not released. +# Remove CRDs that belong to a feature that is not released. patchesStrategicMerge: - |- apiVersion: apiextensions.k8s.io/v1 From 8d532dd56215f8e1d7a6699a4b44314298c0774a Mon Sep 17 00:00:00 2001 From: Tim Riffer Date: Fri, 15 Nov 2024 08:17:13 +0100 Subject: [PATCH 10/10] Rename feature toggle --- Makefile | 8 ++++---- controllers/ratelimit/feature_disabled.go | 2 +- controllers/ratelimit/feature_enabled.go | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index 60319602b..dad6e8eb6 100644 --- a/Makefile +++ b/Makefile @@ -89,7 +89,7 @@ vet: ## Run go vet against code. .PHONY: test test: manifests generate fmt vet envtest ## Generate manifests and run tests. - KUBEBUILDER_CONTROLPLANE_START_TIMEOUT=2m KUBEBUILDER_CONTROLPLANE_STOP_TIMEOUT=2m KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) -p path)" go test -tags enable_dev_features $(shell go list ./... | grep -v /tests/integration) -coverprofile cover.out + KUBEBUILDER_CONTROLPLANE_START_TIMEOUT=2m KUBEBUILDER_CONTROLPLANE_STOP_TIMEOUT=2m KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) -p path)" go test -tags dev_features $(shell go list ./... | grep -v /tests/integration) -coverprofile cover.out .PHONY: test-integration test-integration: test-integration-v2alpha1 test-integration-ory test-integration-istio test-integration-gateway @@ -134,15 +134,15 @@ install-istio: create-namespace .PHONY: build build: generate fmt vet ## Build manager binary. - go build -tags enable_dev_features -o bin/manager main.go + go build -tags dev_features -o bin/manager main.go .PHONY: run run: manifests generate fmt vet - go run -tags enable_dev_features ./main.go + go run -tags dev_features ./main.go .PHONY: docker-build docker-build: - IMG=$(IMG) docker build -t ${IMG} --build-arg GO_BUILD_TAGS=enable_dev_features --build-arg TARGET_OS=${TARGET_OS} --build-arg TARGET_ARCH=${TARGET_ARCH} --build-arg VERSION=${VERSION} . + IMG=$(IMG) docker build -t ${IMG} --build-arg GO_BUILD_TAGS=dev_features --build-arg TARGET_OS=${TARGET_OS} --build-arg TARGET_ARCH=${TARGET_ARCH} --build-arg VERSION=${VERSION} . .PHONY: docker-push docker-push: ## Push docker image with the manager. diff --git a/controllers/ratelimit/feature_disabled.go b/controllers/ratelimit/feature_disabled.go index 92f896f22..22d6b9929 100644 --- a/controllers/ratelimit/feature_disabled.go +++ b/controllers/ratelimit/feature_disabled.go @@ -1,4 +1,4 @@ -//go:build !enable_dev_features +//go:build !dev_features package ratelimit diff --git a/controllers/ratelimit/feature_enabled.go b/controllers/ratelimit/feature_enabled.go index ab49a6e57..565957eec 100644 --- a/controllers/ratelimit/feature_enabled.go +++ b/controllers/ratelimit/feature_enabled.go @@ -1,4 +1,4 @@ -//go:build enable_dev_features +//go:build dev_features package ratelimit