diff --git a/Makefile b/Makefile index 3c30f337..fc2d2142 100644 --- a/Makefile +++ b/Makefile @@ -106,14 +106,6 @@ ifndef ignore-not-found ignore-not-found = false endif -.PHONY: install -install: manifests kustomize ## Install CRDs into the K8s cluster specified in ~/.kube/config. - $(KUSTOMIZE) build config/crd | kubectl apply -f - - -.PHONY: uninstall -uninstall: manifests kustomize ## Uninstall CRDs 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/crd | kubectl delete --ignore-not-found=$(ignore-not-found) -f - - .PHONY: deploy deploy: _deploy-check-env-vars docker-build manifests kustomize _helm_setup ## Deploy controller to the K8s cluster specified in ~/.kube/config. helm upgrade ngrok-ingress-controller $(HELM_CHART_DIR) --install \ diff --git a/api/ngrok/v1alpha1/ngroktrafficpolicy_types.go b/api/ngrok/v1alpha1/ngroktrafficpolicy_types.go index 2397c6ec..fdef9cb3 100644 --- a/api/ngrok/v1alpha1/ngroktrafficpolicy_types.go +++ b/api/ngrok/v1alpha1/ngroktrafficpolicy_types.go @@ -38,13 +38,20 @@ type NgrokTrafficPolicySpec struct { // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster // Important: Run "make" to regenerate code after modifying this file + // The raw json encoded policy that was applied to the ngrok API + // +kubebuilder:validation:Schemaless + // +kubebuilder:pruning:PreserveUnknownFields + // +kubebuilder:validation:Type=object Policy json.RawMessage `json:"policy,omitempty"` } // NgrokTrafficPolicyStatus defines the observed state of NgrokTrafficPolicy type NgrokTrafficPolicyStatus struct { - // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster - // Important: Run "make" to regenerate code after modifying this file + + // The raw json encoded policy that was applied to the ngrok API + // +kubebuilder:validation:Schemaless + // +kubebuilder:pruning:PreserveUnknownFields + // +kubebuilder:validation:Type=object Policy json.RawMessage `json:"policy,omitempty"` } diff --git a/cmd/main.go b/cmd/main.go index 050ebf26..2b22ffce 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -51,6 +51,7 @@ import ( "github.com/ngrok/kubernetes-ingress-controller/internal/annotations" gatewaycontroller "github.com/ngrok/kubernetes-ingress-controller/internal/controller/gateway" controllers "github.com/ngrok/kubernetes-ingress-controller/internal/controller/ingress" + ngrokctr "github.com/ngrok/kubernetes-ingress-controller/internal/controller/ngrok" "github.com/ngrok/kubernetes-ingress-controller/internal/ngrokapi" "github.com/ngrok/kubernetes-ingress-controller/internal/store" "github.com/ngrok/kubernetes-ingress-controller/internal/version" @@ -318,6 +319,17 @@ func runController(ctx context.Context, opts managerOpts) error { os.Exit(1) } } + + if err = (&ngrokctr.NgrokTrafficPolicyReconciler{ + Client: mgr.GetClient(), + Log: ctrl.Log.WithName("controllers").WithName("Policy"), + Scheme: mgr.GetScheme(), + Recorder: mgr.GetEventRecorderFor("policy-controller"), + Driver: driver, + }).SetupWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create controller", "controller", "Policy") + os.Exit(1) + } //+kubebuilder:scaffold:builder if err := mgr.AddReadyzCheck("readyz", func(req *http.Request) error { diff --git a/config/crd/kustomization.yaml b/config/crd/kustomization.yaml deleted file mode 100644 index 6a0db12a..00000000 --- a/config/crd/kustomization.yaml +++ /dev/null @@ -1,23 +0,0 @@ -# This kustomization.yaml is not intended to be run by itself, -# since it depends on service name and namespace that are out of this kustomize package. -# It should be run by config/default -resources: -- bases/ngrok.k8s.ngrok.com_ngroktrafficpolicies.yaml -#+kubebuilder:scaffold:crdkustomizeresource - -patches: -# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix. -# patches here are for enabling the conversion webhook for each CRD -#- path: patches/webhook_in_ngrok_ngroktrafficpolicies.yaml -#+kubebuilder:scaffold:crdkustomizewebhookpatch - -# [CERTMANAGER] To enable cert-manager, uncomment all the sections with [CERTMANAGER] prefix. -# patches here are for enabling the CA injection for each CRD -#- path: patches/cainjection_in_ngrok_ngroktrafficpolicies.yaml -#+kubebuilder:scaffold:crdkustomizecainjectionpatch - -# [WEBHOOK] To enable webhook, uncomment the following section -# the following config is for teaching kustomize how to do kustomization for CRDs. - -#configurations: -#- kustomizeconfig.yaml diff --git a/config/crd/kustomizeconfig.yaml b/config/crd/kustomizeconfig.yaml deleted file mode 100644 index ec5c150a..00000000 --- a/config/crd/kustomizeconfig.yaml +++ /dev/null @@ -1,19 +0,0 @@ -# This file is for teaching kustomize how to substitute name and namespace reference in CRD -nameReference: -- kind: Service - version: v1 - fieldSpecs: - - kind: CustomResourceDefinition - version: v1 - group: apiextensions.k8s.io - path: spec/conversion/webhook/clientConfig/service/name - -namespace: -- kind: CustomResourceDefinition - version: v1 - group: apiextensions.k8s.io - path: spec/conversion/webhook/clientConfig/service/namespace - create: false - -varReference: -- path: metadata/annotations diff --git a/config/rbac/ngrok_ngroktrafficpolicy_editor_role.yaml b/config/rbac/ngrok_ngroktrafficpolicy_editor_role.yaml deleted file mode 100644 index 3cb3557a..00000000 --- a/config/rbac/ngrok_ngroktrafficpolicy_editor_role.yaml +++ /dev/null @@ -1,31 +0,0 @@ -# permissions for end users to edit ngroktrafficpolicies. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: ngroktrafficpolicy-editor-role - app.kubernetes.io/component: rbac - app.kubernetes.io/created-by: kubernetes-ingress-controller - app.kubernetes.io/part-of: kubernetes-ingress-controller - app.kubernetes.io/managed-by: kustomize - name: ngroktrafficpolicy-editor-role -rules: -- apiGroups: - - ngrok.k8s.ngrok.com - resources: - - ngroktrafficpolicies - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - ngrok.k8s.ngrok.com - resources: - - ngroktrafficpolicies/status - verbs: - - get diff --git a/config/rbac/ngrok_ngroktrafficpolicy_viewer_role.yaml b/config/rbac/ngrok_ngroktrafficpolicy_viewer_role.yaml deleted file mode 100644 index 31f66a58..00000000 --- a/config/rbac/ngrok_ngroktrafficpolicy_viewer_role.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# permissions for end users to view ngroktrafficpolicies. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: ngroktrafficpolicy-viewer-role - app.kubernetes.io/component: rbac - app.kubernetes.io/created-by: kubernetes-ingress-controller - app.kubernetes.io/part-of: kubernetes-ingress-controller - app.kubernetes.io/managed-by: kustomize - name: ngroktrafficpolicy-viewer-role -rules: -- apiGroups: - - ngrok.k8s.ngrok.com - resources: - - ngroktrafficpolicies - verbs: - - get - - list - - watch -- apiGroups: - - ngrok.k8s.ngrok.com - resources: - - ngroktrafficpolicies/status - verbs: - - get diff --git a/config/samples/kustomization.yaml b/config/samples/kustomization.yaml deleted file mode 100644 index 8f8203d6..00000000 --- a/config/samples/kustomization.yaml +++ /dev/null @@ -1,4 +0,0 @@ -## Append samples of your project ## -resources: -- ngrok_v1alpha1_ngroktrafficpolicy.yaml -#+kubebuilder:scaffold:manifestskustomizesamples diff --git a/config/samples/ngrok_v1alpha1_ngroktrafficpolicy.yaml b/config/samples/ngrok_v1alpha1_ngroktrafficpolicy.yaml deleted file mode 100644 index 22498da1..00000000 --- a/config/samples/ngrok_v1alpha1_ngroktrafficpolicy.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: ngrok.k8s.ngrok.com/v1alpha1 -kind: NgrokTrafficPolicy -metadata: - labels: - app.kubernetes.io/name: ngroktrafficpolicy - app.kubernetes.io/instance: ngroktrafficpolicy-sample - app.kubernetes.io/part-of: kubernetes-ingress-controller - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/created-by: kubernetes-ingress-controller - name: ngroktrafficpolicy-sample -spec: - # TODO(user): Add fields here diff --git a/helm/ingress-controller/templates/crds/ngrok.k8s.ngrok.com_ngroktrafficpolicies.yaml b/helm/ingress-controller/templates/crds/ngrok.k8s.ngrok.com_ngroktrafficpolicies.yaml index b76c0713..f3b49c08 100644 --- a/helm/ingress-controller/templates/crds/ngrok.k8s.ngrok.com_ngroktrafficpolicies.yaml +++ b/helm/ingress-controller/templates/crds/ngrok.k8s.ngrok.com_ngroktrafficpolicies.yaml @@ -37,21 +37,19 @@ spec: description: NgrokTrafficPolicySpec defines the desired state of NgrokTrafficPolicy properties: policy: - description: RawMessage is a raw encoded JSON value. It implements - Marshaler and Unmarshaler and can be used to delay JSON decoding - or precompute a JSON encoding. - format: byte - type: string + description: The raw json encoded policy that was applied to the ngrok + API + type: object + x-kubernetes-preserve-unknown-fields: true type: object status: description: NgrokTrafficPolicyStatus defines the observed state of NgrokTrafficPolicy properties: policy: - description: 'INSERT ADDITIONAL STATUS FIELD - define observed state - of cluster Important: Run "make" to regenerate code after modifying - this file' - format: byte - type: string + description: The raw json encoded policy that was applied to the ngrok + API + type: object + x-kubernetes-preserve-unknown-fields: true type: object type: object served: true diff --git a/internal/controller/ngrok/ngroktrafficpolicy_controller.go b/internal/controller/ngrok/ngroktrafficpolicy_controller.go index 4499efb9..847e7826 100644 --- a/internal/controller/ngrok/ngroktrafficpolicy_controller.go +++ b/internal/controller/ngrok/ngroktrafficpolicy_controller.go @@ -27,18 +27,23 @@ package ngrok import ( "context" + "github.com/go-logr/logr" + ngrokv1alpha1 "github.com/ngrok/kubernetes-ingress-controller/api/ngrok/v1alpha1" + "github.com/ngrok/kubernetes-ingress-controller/internal/store" "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/tools/record" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/log" - - ngrokv1alpha1 "github.com/ngrok/kubernetes-ingress-controller/api/ngrok/v1alpha1" ) // NgrokTrafficPolicyReconciler reconciles a NgrokTrafficPolicy object type NgrokTrafficPolicyReconciler struct { client.Client - Scheme *runtime.Scheme + Log logr.Logger + Scheme *runtime.Scheme + Recorder record.EventRecorder + Driver *store.Driver } //+kubebuilder:rbac:groups=ngrok.k8s.ngrok.com,resources=ngroktrafficpolicies,verbs=get;list;watch;create;update;patch;delete @@ -57,14 +62,14 @@ type NgrokTrafficPolicyReconciler struct { func (r *NgrokTrafficPolicyReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { _ = log.FromContext(ctx) - // TODO(user): your logic here - - return ctrl.Result{}, nil + err := r.Driver.SyncEdges(ctx, r.Client) + return ctrl.Result{}, err } // SetupWithManager sets up the controller with the Manager. func (r *NgrokTrafficPolicyReconciler) SetupWithManager(mgr ctrl.Manager) error { return ctrl.NewControllerManagedBy(mgr). For(&ngrokv1alpha1.NgrokTrafficPolicy{}). + WithEventFilter(commonPredicateFilters). Complete(r) } diff --git a/internal/controller/ngrok/policy_predicates.go b/internal/controller/ngrok/policy_predicates.go new file mode 100644 index 00000000..4138dbd8 --- /dev/null +++ b/internal/controller/ngrok/policy_predicates.go @@ -0,0 +1,24 @@ +package ngrok + +import ( + "sigs.k8s.io/controller-runtime/pkg/event" + "sigs.k8s.io/controller-runtime/pkg/predicate" +) + +// common update func predicate filter +func updateFuncPredicateFilter(ue event.UpdateEvent) bool { + // First check if there are any annotations present that aren't in the old version + oldAnnotations := ue.ObjectOld.GetAnnotations() + for newKey, newValue := range ue.ObjectNew.GetAnnotations() { + if oldAnnotations[newKey] != newValue { + return true + } + } + // No change to spec, so we can ignore. This does not filter out updates + // that set metadata.deletionTimestamp, so this won't undermine finalizer. + return ue.ObjectNew.GetGeneration() != ue.ObjectOld.GetGeneration() +} + +var commonPredicateFilters = predicate.Funcs{ + UpdateFunc: updateFuncPredicateFilter, +}