diff --git a/Makefile b/Makefile index 46056fc8..d84b3532 100644 --- a/Makefile +++ b/Makefile @@ -71,6 +71,13 @@ generate-crds: controller-gen-install paths=./pkg/apis/core/v1 \ output:crd:artifacts:config=crds/v1 +### Webhook generation: it generates webhook configs with help of kubebuilder:webhook tag +generate-webhooks: controller-gen-install + controller-gen webhook \ + paths=./pkg/apis/core/v1 \ + output:dir=charts/fission-all/templates/webhook-server + + create-crds: @kubectl create -k crds/v1 diff --git a/charts/fission-all/templates/_certs.tpl b/charts/fission-all/templates/_certs.tpl new file mode 100644 index 00000000..eafef570 --- /dev/null +++ b/charts/fission-all/templates/_certs.tpl @@ -0,0 +1,43 @@ + + +{{- define "fision.selfSignedCABundleCertPEM" -}} + {{- $caKeypair := .selfSignedCAKeypair | default (genCA "fission-ca" 1825) -}} + {{- $_ := set . "selfSignedCAKeypair" $caKeypair -}} + {{- $caKeypair.Cert -}} +{{- end -}} + +{{- define "webhook.caBundleCertPEM" -}} + {{- if .Values.webhook.caBundlePEM -}} + {{- trim .Values.webhook.caBundlePEM -}} + {{- else -}} + {{- $caKeypair := .selfSignedCAKeypair | default (genCA "fission-ca" 1825) -}} + {{- $_ := set . "selfSignedCAKeypair" $caKeypair -}} + {{- $caKeypair.Cert -}} + {{- end -}} +{{- end -}} + +{{- define "webhook.certPEM" -}} + {{- if .Values.webhook.crtPEM -}} + {{- trim .Values.webhook.crtPEM -}} + {{- else -}} + {{- $webhookName := printf "%s.%s.svc" (include "fission-webhook.svc" .) .Release.Namespace }} + {{- $fullWebhookName := printf "%s.%s.svc.cluster.local" (include "fission-webhook.svc" .) .Release.Namespace -}} + {{- $webhookCA := required "self-signed CA keypair is requried" .selfSignedCAKeypair -}} + {{- $webhookServerTLSKeypair := .webhookTLSKeypair | default (genSignedCert $webhookName nil (list $webhookName $fullWebhookName) 1825 $webhookCA) }} + {{- $_ := set . "webhookTLSKeypair" $webhookServerTLSKeypair -}} + {{- $webhookServerTLSKeypair.Cert -}} + {{- end -}} +{{- end -}} + +{{- define "webhook.keyPEM" -}} + {{- if .Values.webhook.keyPEM -}} + {{ trim .Values.webhook.keyPEM }} + {{- else -}} + {{- $webhookName := printf "%s.%s.svc" (include "fission-webhook.svc" .) .Release.Namespace -}} + {{- $fullWebhookName := printf "%s.%s.svc.cluster.local" (include "fission-webhook.svc" .) .Release.Namespace -}} + {{- $webhookCA := required "self-signed CA keypair is requried" .selfSignedCAKeypair -}} + {{- $webhookServerTLSKeypair := .webhookTLSKeypair | default (genSignedCert $webhookName nil (list $webhookName $fullWebhookName) 1825 $webhookCA) -}} + {{- $_ := set . "webhookTLSKeypair" $webhookServerTLSKeypair -}} + {{- $webhookServerTLSKeypair.Key -}} + {{- end -}} +{{- end -}} diff --git a/charts/fission-all/templates/_helpers.tpl b/charts/fission-all/templates/_helpers.tpl index ed32d600..908b035f 100644 --- a/charts/fission-all/templates/_helpers.tpl +++ b/charts/fission-all/templates/_helpers.tpl @@ -79,4 +79,11 @@ This template generates the image name for the deployment depending on the value {{- else }} value: {{ .Values.defaultNamespace }} {{- end }} -{{- end }} \ No newline at end of file +{{- end }} + +{{/* +Define the svc's name +*/}} +{{- define "fission-webhook.svc" -}} +{{- printf "webhook-service" -}} +{{- end -}} \ No newline at end of file diff --git a/charts/fission-all/templates/webhook-server/cert.yaml b/charts/fission-all/templates/webhook-server/cert.yaml new file mode 100644 index 00000000..e4b98148 --- /dev/null +++ b/charts/fission-all/templates/webhook-server/cert.yaml @@ -0,0 +1,38 @@ +{{- $certManagerEnabled := .Values.webhook.certManager.enabled }} + +{{- if not $certManagerEnabled }} +kind: Secret +apiVersion: v1 +metadata: + name: fission-webhook-certs + labels: + app.kubernetes.io/component: webhook-secret +type: Opaque +data: + ca.crt: {{ b64enc (include "webhook.caBundleCertPEM" .) }} + tls.crt: {{ b64enc (include "webhook.certPEM" .) }} + tls.key: {{ b64enc (include "webhook.keyPEM" .) }} + +{{- else }} +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: fission-selfsigned-issuer + namespace: {{ .Release.Namespace }} +spec: + selfSigned: {} +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: fission-webhook-cert + namespace: {{ .Release.Namespace }} +spec: + secretName: fission-webhook-certs + dnsNames: + - "webhook-service.{{ .Release.Namespace }}.svc" + - "webhook-service.{{ .Release.Namespace }}.svc.cluster.local " + issuerRef: + name: fission-selfsigned-issuer + +{{- end }} \ No newline at end of file diff --git a/charts/fission-all/templates/webhook-server/deployment.yaml b/charts/fission-all/templates/webhook-server/deployment.yaml new file mode 100644 index 00000000..669b79a0 --- /dev/null +++ b/charts/fission-all/templates/webhook-server/deployment.yaml @@ -0,0 +1,55 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: webhook + labels: + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + svc: webhook-service + application: fission-webhook +spec: + replicas: 1 + selector: + matchLabels: + svc: webhook-service + application: fission-webhook + template: + metadata: + labels: + svc: webhook-service + application: fission-webhook + annotations: + prometheus.io/scrape: "true" + prometheus.io/path: "/metrics" + prometheus.io/port: "8080" + spec: + {{- if .Values.webhook.securityContext.enabled }} + securityContext: {{- omit .Values.webhook.securityContext "enabled" | toYaml | nindent 8 }} + {{- end }} + containers: + - name: webhook + image: {{ include "fission-bundleImage" . | quote }} + imagePullPolicy: {{ .Values.pullPolicy }} + command: ["/fission-bundle"] + args: ["--webhookPort", "9443"] + volumeMounts: + - mountPath: /tmp/k8s-webhook-server/serving-certs + name: serving-certs + readOnly: true + ports: + - containerPort: 8080 + name: metrics + volumes: + - name: serving-certs + secret: + secretName: fission-webhook-certs + serviceAccountName: fission-webhook +{{- if .Values.priorityClassName }} + priorityClassName: {{ .Values.priorityClassName }} +{{- end }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} +{{- if .Values.extraCoreComponentPodConfig }} +{{ toYaml .Values.extraCoreComponentPodConfig | indent 6 -}} +{{- end }} \ No newline at end of file diff --git a/charts/fission-all/templates/webhook-server/serviceaccount.yaml b/charts/fission-all/templates/webhook-server/serviceaccount.yaml new file mode 100644 index 00000000..4e90185b --- /dev/null +++ b/charts/fission-all/templates/webhook-server/serviceaccount.yaml @@ -0,0 +1,5 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: fission-webhook + namespace: {{ .Release.Namespace }} diff --git a/charts/fission-all/templates/webhook-server/servicemonitor.yaml b/charts/fission-all/templates/webhook-server/servicemonitor.yaml new file mode 100644 index 00000000..cdea65f6 --- /dev/null +++ b/charts/fission-all/templates/webhook-server/servicemonitor.yaml @@ -0,0 +1,22 @@ +{{- if .Values.serviceMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: webhook-monitor + {{- if .Values.serviceMonitor.namespace }} + namespace: {{ .Values.serviceMonitor.namespace }} + {{- end }} + {{- with .Values.serviceMonitor.additionalServiceMonitorLabels }} + labels: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + namespaceSelector: + matchNames: + - {{ .Release.Namespace }} + selector: + matchLabels: + svc: webhook-service + endpoints: + - targetPort: 8080 +{{- end -}} \ No newline at end of file diff --git a/charts/fission-all/templates/webhook-server/webhook-service.yaml b/charts/fission-all/templates/webhook-server/webhook-service.yaml new file mode 100644 index 00000000..67d64e55 --- /dev/null +++ b/charts/fission-all/templates/webhook-server/webhook-service.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + name: webhook-service + labels: + svc: webhook-service + application: fission-webhook + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" +spec: + type: {{ .Values.serviceType }} + ports: + - port: 443 + targetPort: 9443 + selector: + svc: webhook-service \ No newline at end of file diff --git a/charts/fission-all/templates/webhook-server/webhooks.yaml b/charts/fission-all/templates/webhook-server/webhooks.yaml new file mode 100644 index 00000000..7fe21528 --- /dev/null +++ b/charts/fission-all/templates/webhook-server/webhooks.yaml @@ -0,0 +1,203 @@ +--- +{{- $caCert := include "webhook.caBundleCertPEM" . -}} +{{- $crtPEM := include "webhook.certPEM" . -}} +{{- $keyPEM := include "webhook.keyPEM" . -}} + +{{- $certManagerEnabled := $.Values.webhook.certManager.enabled }} +{{- $caBundleValue := "" -}} +{{- if $certManagerEnabled }} +{{- $caBundleValue = "Cg==" -}} +{{- else }} +{{- $caBundleValue = ternary (b64enc $caCert) (b64enc (trim $crtPEM)) (empty $crtPEM) -}} +{{- end }} + +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + creationTimestamp: null + name: mutating-webhook-configuration + {{- if $certManagerEnabled }} + annotations: + cert-manager.io/inject-ca-from: "{{ .Release.Namespace }}/fission-webhook-cert" + {{- end }} +webhooks: +- admissionReviewVersions: + - v1 + clientConfig: + caBundle: {{ $caBundleValue }} + service: + name: webhook-service + namespace: {{ .Release.Namespace }} + path: /mutate-fission-io-v1-package + failurePolicy: Fail + name: mpackage.fission.io + rules: + - apiGroups: + - fission.io + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - packages + sideEffects: None +--- + +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + creationTimestamp: null + name: validating-webhook-configuration + {{- if $certManagerEnabled }} + annotations: + cert-manager.io/inject-ca-from: "{{ .Release.Namespace }}/fission-webhook-cert" + {{- end }} +webhooks: +- admissionReviewVersions: + - v1 + clientConfig: + caBundle: {{ $caBundleValue }} + service: + name: webhook-service + namespace: {{ .Release.Namespace }} + path: /validate-fission-io-v1-environment + failurePolicy: Fail + name: venvironment.fission.io + rules: + - apiGroups: + - fission.io + apiVersions: + - v1 + operations: + - CREATE + resources: + - environments + sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + caBundle: {{ $caBundleValue }} + service: + name: webhook-service + namespace: {{ .Release.Namespace }} + path: /validate-fission-io-v1-function + failurePolicy: Fail + name: vfunction.fission.io + rules: + - apiGroups: + - fission.io + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - functions + sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + caBundle: {{ $caBundleValue }} + service: + name: webhook-service + namespace: {{ .Release.Namespace }} + path: /validate-fission-io-v1-httptrigger + failurePolicy: Fail + name: vhttptrigger.fission.io + rules: + - apiGroups: + - fission.io + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - httptriggers + sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + caBundle: {{ $caBundleValue }} + service: + name: webhook-service + namespace: {{ .Release.Namespace }} + path: /validate-fission-io-v1-kuberneteswatchtrigger + failurePolicy: Fail + name: vkuberneteswatchtrigger.fission.io + rules: + - apiGroups: + - fission.io + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - kuberneteswatchtriggers + sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + caBundle: {{ $caBundleValue }} + service: + name: webhook-service + namespace: {{ .Release.Namespace }} + path: /validate-fission-io-v1-messagequeuetrigger + failurePolicy: Fail + name: vmessagequeuetrigger.fission.io + rules: + - apiGroups: + - fission.io + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - messagequeuetriggers + sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + caBundle: {{ $caBundleValue }} + service: + name: webhook-service + namespace: {{ .Release.Namespace }} + path: /validate-fission-io-v1-package + failurePolicy: Fail + name: vpackage.fission.io + rules: + - apiGroups: + - fission.io + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - packages + sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + caBundle: {{ $caBundleValue }} + service: + name: webhook-service + namespace: {{ .Release.Namespace }} + path: /validate-fission-io-v1-timetrigger + failurePolicy: Fail + name: vtimetrigger.fission.io + rules: + - apiGroups: + - fission.io + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - timetriggers + sideEffects: None diff --git a/charts/fission-all/values.yaml b/charts/fission-all/values.yaml index 9becc742..7c7aa823 100644 --- a/charts/fission-all/values.yaml +++ b/charts/fission-all/values.yaml @@ -361,6 +361,44 @@ controller: runAsUser: 10001 runAsGroup: 10001 +## webhook is the component that validates API calls. +## It contains validation and mutation for functions, triggers, environments, Kubernetes event watches, etc. +## +webhook: + ## Pod resources as: + ## resources: + ## limits: + ## cpu: + ## memory: + ## requests: + ## cpu: + ## memory: + ## + resources: {} + + certManager: + enabled: false + + caBundlePEM: | + + crtPEM: | + + keyPEM: | + + + ## Security Context + ## It holds pod-level and container level security configuration. + ## This is an experimental section, please verify before enabling in production. + ## Ref: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#security-context-1 + securityContext: + enabled: false + ## Mark it false, if you want to stop the non root user validation + runAsNonRoot: true + fsGroup: 10001 + runAsUser: 10001 + runAsGroup: 10001 + + ## kubewatcher watches the Kubernetes API and invokes functions associated with watches, sending the watch event to the function. ## kubewatcher: diff --git a/cmd/fission-bundle/main.go b/cmd/fission-bundle/main.go index 8a0b5257..736ada1a 100644 --- a/cmd/fission-bundle/main.go +++ b/cmd/fission-bundle/main.go @@ -24,9 +24,8 @@ import ( "strconv" docopt "github.com/docopt/docopt-go" - "sigs.k8s.io/controller-runtime/pkg/manager/signals" - "go.uber.org/zap" + "sigs.k8s.io/controller-runtime/pkg/manager/signals" "github.com/fission/fission/cmd/fission-bundle/mqtrigger" "github.com/fission/fission/pkg/buildermgr" @@ -42,8 +41,14 @@ import ( "github.com/fission/fission/pkg/utils/loggerfactory" "github.com/fission/fission/pkg/utils/otel" "github.com/fission/fission/pkg/utils/profile" + "github.com/fission/fission/pkg/webhook" ) +// runWebhook starts admission webhook server +func runWebhook(ctx context.Context, logger *zap.Logger, port int) error { + return webhook.Start(ctx, logger, port) +} + func runController(ctx context.Context, logger *zap.Logger, port int) { controller.Start(ctx, logger, port, false) } @@ -176,10 +181,12 @@ Usage: fission-bundle --timer [--routerUrl=] fission-bundle --mqt [--routerUrl=] fission-bundle --mqt_keda [--routerUrl=] + fission-bundle --webhookPort= fission-bundle --logger fission-bundle --version Options: --controllerPort= Port that the controller should listen on. + --webhookPort= Port that the webhook should listen on. --routerPort= Port that the router should listen on. --executorPort= Port that the executor should listen on. --storageServicePort= Port that the storage service should listen on. @@ -225,6 +232,13 @@ Options: routerUrl := getStringArgWithDefault(arguments["--routerUrl"], "http://router.fission") storageSvcUrl := getStringArgWithDefault(arguments["--storageSvcUrl"], "http://storagesvc.fission") + if arguments["--webhookPort"] != nil { + port := getPort(logger, arguments["--webhookPort"]) + err = runWebhook(ctx, logger, port) + logger.Error("webhook server exited:", zap.Error(err)) + return + } + if arguments["--controllerPort"] != nil { port := getPort(logger, arguments["--controllerPort"]) runController(ctx, logger, port) diff --git a/go.mod b/go.mod index b6c51b34..c837f6ee 100644 --- a/go.mod +++ b/go.mod @@ -83,6 +83,7 @@ require ( github.com/eapache/queue v1.1.0 // indirect github.com/emirpasic/gods v1.12.0 // indirect github.com/evanphx/json-patch v4.12.0+incompatible // indirect + github.com/evanphx/json-patch/v5 v5.6.0 // indirect github.com/felixge/httpsnoop v1.0.3 // indirect github.com/go-git/gcfg v1.5.0 // indirect github.com/go-git/go-billy/v5 v5.3.1 // indirect @@ -101,6 +102,7 @@ require ( github.com/google/gnostic v0.5.7-v3refs // indirect github.com/google/go-cmp v0.5.9 // indirect github.com/google/gofuzz v1.1.0 // indirect + github.com/google/uuid v1.3.0 // indirect github.com/gotestyourself/gotestyourself v2.2.0+incompatible // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.10.3 // indirect github.com/hashicorp/errwrap v1.0.0 // indirect @@ -161,6 +163,7 @@ require ( golang.org/x/term v0.1.0 // indirect golang.org/x/text v0.4.0 // indirect golang.org/x/time v0.0.0-20220609170525-579cf78fd858 // indirect + gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20220628213854-d9e0b6570c03 // indirect google.golang.org/protobuf v1.28.1 // indirect @@ -169,6 +172,7 @@ require ( gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect gotest.tools v2.2.0+incompatible // indirect + k8s.io/component-base v0.25.3 // indirect k8s.io/klog/v2 v2.70.1 // indirect k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1 // indirect k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed // indirect diff --git a/go.sum b/go.sum index 6fd02232..6d531fbb 100644 --- a/go.sum +++ b/go.sum @@ -199,8 +199,11 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.m github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ= github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJCLunww= +github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= @@ -353,6 +356,7 @@ github.com/google/readahead v0.0.0-20161222183148-eaceba169032/go.mod h1:qYysrqQ github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= @@ -415,6 +419,7 @@ github.com/jcmturner/gokrb5/v8 v8.4.3 h1:iTonLeSJOn7MVUtyMT+arAn5AKAPrkilzhGw8wE github.com/jcmturner/gokrb5/v8 v8.4.3/go.mod h1:dqRwJGXznQrzw6cWmyo6kH+E7jksEQG/CyVWsJEsJO0= github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZY= github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= @@ -978,6 +983,8 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gomodules.xyz/jsonpatch/v2 v2.2.0 h1:4pT439QV83L+G9FkcCriY6EkpcK6r6bK+A5FBUMI7qY= +gomodules.xyz/jsonpatch/v2 v2.2.0/go.mod h1:WXp+iVDkoLQqPudfQ9GBlwB2eZ5DKOnjQZCYdOS8GPY= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= @@ -1172,6 +1179,8 @@ k8s.io/apimachinery v0.25.3 h1:7o9ium4uyUOM76t6aunP0nZuex7gDf8VGwkR5RcJnQc= k8s.io/apimachinery v0.25.3/go.mod h1:jaF9C/iPNM1FuLl7Zuy5b9v+n35HGSh6AQ4HYRkCqwo= k8s.io/client-go v0.25.3 h1:oB4Dyl8d6UbfDHD8Bv8evKylzs3BXzzufLiO27xuPs0= k8s.io/client-go v0.25.3/go.mod h1:t39LPczAIMwycjcXkVc+CB+PZV69jQuNx4um5ORDjQA= +k8s.io/component-base v0.25.3 h1:UrsxciGdrCY03ULT1h/S/gXFCOPnLhUVwSyx+hM/zq4= +k8s.io/component-base v0.25.3/go.mod h1:WYoS8L+IlTZgU7rhAl5Ctpw0WdMxDfCC5dkxcEFa/TI= k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= k8s.io/klog/v2 v2.70.1 h1:7aaoSdahviPmR+XkS7FyxlkkXs6tHISSG03RxleQAVQ= k8s.io/klog/v2 v2.70.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= diff --git a/pkg/apis/core/v1/canaryconfig_webhook .go b/pkg/apis/core/v1/canaryconfig_webhook .go new file mode 100644 index 00000000..d2208d9b --- /dev/null +++ b/pkg/apis/core/v1/canaryconfig_webhook .go @@ -0,0 +1,68 @@ +/* +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 v1 + +import ( + "go.uber.org/zap" + "k8s.io/apimachinery/pkg/runtime" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/webhook" + + "github.com/fission/fission/pkg/utils/loggerfactory" +) + +// log is for logging in this package. +var canaryconfiglog = loggerfactory.GetLogger().Named("canaryconfig-resource") + +func (r *CanaryConfig) SetupWebhookWithManager(mgr ctrl.Manager) error { + return ctrl.NewWebhookManagedBy(mgr). + For(r). + Complete() +} + +// Admission webhooks can be added by adding tag: kubebuilder:webhook:path=/mutate-fission-io-v1-canaryconfig,mutating=true,failurePolicy=fail,sideEffects=None,groups=fission.io,resources=canaryconfigs,verbs=create;update,versions=v1,name=mcanaryconfig.fission.io,admissionReviewVersions=v1 +// Refer Makefile -> generate-webhooks to generate config for manifests + +var _ webhook.Defaulter = &CanaryConfig{} + +// Default implements webhook.Defaulter so a webhook will be registered for the type +func (r *CanaryConfig) Default() { + canaryconfiglog.Debug("default", zap.String("name", r.Name)) +} + +// user can change verbs to "verbs=create;update;delete" if you want to enable deletion validation. +// Validation webhooks can be added by adding tag: kubebuilder:webhook:path=/validate-fission-io-v1-canaryconfig,mutating=false,failurePolicy=fail,sideEffects=None,groups=fission.io,resources=canaryconfigs,verbs=create;update,versions=v1,name=vcanaryconfig.fission.io,admissionReviewVersions=v1 + +var _ webhook.Validator = &CanaryConfig{} + +// ValidateCreate implements webhook.Validator so a webhook will be registered for the type +func (r *CanaryConfig) ValidateCreate() error { + canaryconfiglog.Debug("validate create", zap.String("name", r.Name)) + return nil +} + +// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type +func (r *CanaryConfig) ValidateUpdate(old runtime.Object) error { + canaryconfiglog.Debug("validate update", zap.String("name", r.Name)) + return nil +} + +// ValidateDelete implements webhook.Validator so a webhook will be registered for the type +func (r *CanaryConfig) ValidateDelete() error { + canaryconfiglog.Debug("validate delete", zap.String("name", r.Name)) + return nil +} diff --git a/pkg/apis/core/v1/environment_webhook.go b/pkg/apis/core/v1/environment_webhook.go new file mode 100644 index 00000000..7c96d741 --- /dev/null +++ b/pkg/apis/core/v1/environment_webhook.go @@ -0,0 +1,72 @@ +/* +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 v1 + +import ( + "go.uber.org/zap" + "k8s.io/apimachinery/pkg/runtime" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/webhook" + + "github.com/fission/fission/pkg/utils/loggerfactory" +) + +// log is for logging in this package. +var environmentlog = loggerfactory.GetLogger().Named("environment-resource") + +func (r *Environment) SetupWebhookWithManager(mgr ctrl.Manager) error { + return ctrl.NewWebhookManagedBy(mgr). + For(r). + Complete() +} + +// Admission webhooks can be added by adding tag: kubebuilder:webhook:path=/mutate-fission-io-v1-environment,mutating=true,failurePolicy=fail,sideEffects=None,groups=fission.io,resources=environments,verbs=create;update,versions=v1,name=menvironment.fission.io,admissionReviewVersions=v1 + +var _ webhook.Defaulter = &Environment{} + +// Default implements webhook.Defaulter so a webhook will be registered for the type +func (r *Environment) Default() { + environmentlog.Debug("default", zap.String("name", r.Name)) +} + +// user: change verbs to "verbs=create;update;delete" if you want to enable deletion validation. +//+kubebuilder:webhook:path=/validate-fission-io-v1-environment,mutating=false,failurePolicy=fail,sideEffects=None,groups=fission.io,resources=environments,verbs=create,versions=v1,name=venvironment.fission.io,admissionReviewVersions=v1 + +var _ webhook.Validator = &Environment{} + +// ValidateCreate implements webhook.Validator so a webhook will be registered for the type +func (r *Environment) ValidateCreate() error { + environmentlog.Debug("validate create", zap.String("name", r.Name)) + err := r.Validate() + if err != nil { + err = AggregateValidationErrors("Environment", err) + return err + } + return nil +} + +// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type +func (r *Environment) ValidateUpdate(old runtime.Object) error { + environmentlog.Debug("validate update", zap.String("name", r.Name)) + return nil +} + +// ValidateDelete implements webhook.Validator so a webhook will be registered for the type +func (r *Environment) ValidateDelete() error { + environmentlog.Debug("validate delete", zap.String("name", r.Name)) + return nil +} diff --git a/pkg/apis/core/v1/function_webhook.go b/pkg/apis/core/v1/function_webhook.go new file mode 100644 index 00000000..13266840 --- /dev/null +++ b/pkg/apis/core/v1/function_webhook.go @@ -0,0 +1,74 @@ +/* +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 v1 + +import ( + "go.uber.org/zap" + "k8s.io/apimachinery/pkg/runtime" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/webhook" + + "github.com/fission/fission/pkg/utils/loggerfactory" +) + +// log is for logging in this package. +var functionlog = loggerfactory.GetLogger().Named("function-resource") + +func (r *Function) SetupWebhookWithManager(mgr ctrl.Manager) error { + return ctrl.NewWebhookManagedBy(mgr). + For(r). + Complete() +} + +// Admission webhooks can be added by adding tag: kubebuilder:webhook:path=/mutate-fission-io-v1-function,mutating=true,failurePolicy=fail,sideEffects=None,groups=fission.io,resources=functions,verbs=create;update,versions=v1,name=mfunction.fission.io,admissionReviewVersions=v1 + +var _ webhook.Defaulter = &Function{} + +// Default implements webhook.Defaulter so a webhook will be registered for the type +func (r *Function) Default() { +} + +// user change verbs to "verbs=create;update;delete" if you want to enable deletion validation. +//+kubebuilder:webhook:path=/validate-fission-io-v1-function,mutating=false,failurePolicy=fail,sideEffects=None,groups=fission.io,resources=functions,verbs=create;update,versions=v1,name=vfunction.fission.io,admissionReviewVersions=v1 + +var _ webhook.Validator = &Function{} + +// ValidateCreate implements webhook.Validator so a webhook will be registered for the type +func (r *Function) ValidateCreate() error { + functionlog.Debug("validate create", zap.String("name", r.Name)) + err := r.Validate() + if err != nil { + return AggregateValidationErrors("Function", err) + } + return nil +} + +// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type +func (r *Function) ValidateUpdate(old runtime.Object) error { + functionlog.Debug("validate update", zap.String("name", r.Name)) + err := r.Validate() + if err != nil { + return AggregateValidationErrors("Function", err) + } + return nil +} + +// ValidateDelete implements webhook.Validator so a webhook will be registered for the type +func (r *Function) ValidateDelete() error { + functionlog.Debug("validate delete", zap.String("name", r.Name)) + return nil +} diff --git a/pkg/apis/core/v1/httptrigger_webhook.go b/pkg/apis/core/v1/httptrigger_webhook.go new file mode 100644 index 00000000..bcff0c6d --- /dev/null +++ b/pkg/apis/core/v1/httptrigger_webhook.go @@ -0,0 +1,79 @@ +/* +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 v1 + +import ( + "go.uber.org/zap" + "k8s.io/apimachinery/pkg/runtime" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/webhook" + + "github.com/fission/fission/pkg/utils/loggerfactory" +) + +// log is for logging in this package. +var httptriggerlog = loggerfactory.GetLogger().Named("httptrigger-resource") + +func (r *HTTPTrigger) SetupWebhookWithManager(mgr ctrl.Manager) error { + return ctrl.NewWebhookManagedBy(mgr). + For(r). + Complete() +} + +// Admission webhooks can be added by adding tag: kubebuilder:webhook:path=/mutate-fission-io-v1-httptrigger,mutating=true,failurePolicy=fail,sideEffects=None,groups=fission.io,resources=httptriggers,verbs=create;update,versions=v1,name=mhttptrigger.fission.io,admissionReviewVersions=v1 + +var _ webhook.Defaulter = &HTTPTrigger{} + +// Default implements webhook.Defaulter so a webhook will be registered for the type +func (r *HTTPTrigger) Default() { + httptriggerlog.Debug("default", zap.String("name", r.Name)) +} + +// user change verbs to "verbs=create;update;delete" if you want to enable deletion validation. +//+kubebuilder:webhook:path=/validate-fission-io-v1-httptrigger,mutating=false,failurePolicy=fail,sideEffects=None,groups=fission.io,resources=httptriggers,verbs=create;update,versions=v1,name=vhttptrigger.fission.io,admissionReviewVersions=v1 + +var _ webhook.Validator = &HTTPTrigger{} + +// ValidateCreate implements webhook.Validator so a webhook will be registered for the type +func (t *HTTPTrigger) ValidateCreate() error { + httptriggerlog.Debug("validate create", zap.String("name", t.Name)) + err := t.Validate() + if err != nil { + err = AggregateValidationErrors("HTTPTrigger", err) + return err + } + return nil +} + +// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type +func (r *HTTPTrigger) ValidateUpdate(old runtime.Object) error { + httptriggerlog.Debug("validate update", zap.String("name", r.Name)) + err := r.Validate() + if err != nil { + err = AggregateValidationErrors("HTTPTrigger", err) + return err + } + + return nil +} + +// ValidateDelete implements webhook.Validator so a webhook will be registered for the type +func (r *HTTPTrigger) ValidateDelete() error { + httptriggerlog.Debug("validate delete", zap.String("name", r.Name)) + + return nil +} diff --git a/pkg/apis/core/v1/kuberneteswatchtrigger_webhook.go b/pkg/apis/core/v1/kuberneteswatchtrigger_webhook.go new file mode 100644 index 00000000..4b1e8f86 --- /dev/null +++ b/pkg/apis/core/v1/kuberneteswatchtrigger_webhook.go @@ -0,0 +1,72 @@ +/* +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 v1 + +import ( + "go.uber.org/zap" + "k8s.io/apimachinery/pkg/runtime" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/webhook" + + "github.com/fission/fission/pkg/utils/loggerfactory" +) + +// log is for logging in this package. +var kuberneteswatchtriggerlog = loggerfactory.GetLogger().Named("kuberneteswatchtrigger-resource") + +func (r *KubernetesWatchTrigger) SetupWebhookWithManager(mgr ctrl.Manager) error { + return ctrl.NewWebhookManagedBy(mgr). + For(r). + Complete() +} + +// Admission webhooks can be added by adding tag: kubebuilder:webhook:path=/mutate-fission-io-v1-kuberneteswatchtrigger,mutating=true,failurePolicy=fail,sideEffects=None,groups=fission.io,resources=kuberneteswatchtriggers,verbs=create;update,versions=v1,name=mkuberneteswatchtrigger.fission.io,admissionReviewVersions=v1 + +var _ webhook.Defaulter = &KubernetesWatchTrigger{} + +// Default implements webhook.Defaulter so a webhook will be registered for the type +func (r *KubernetesWatchTrigger) Default() { + kuberneteswatchtriggerlog.Debug("default", zap.String("name", r.Name)) +} + +// user: change verbs to "verbs=create;update;delete" if you want to enable deletion validation. +//+kubebuilder:webhook:path=/validate-fission-io-v1-kuberneteswatchtrigger,mutating=false,failurePolicy=fail,sideEffects=None,groups=fission.io,resources=kuberneteswatchtriggers,verbs=create,versions=v1,name=vkuberneteswatchtrigger.fission.io,admissionReviewVersions=v1 + +var _ webhook.Validator = &KubernetesWatchTrigger{} + +// ValidateCreate implements webhook.Validator so a webhook will be registered for the type +func (r *KubernetesWatchTrigger) ValidateCreate() error { + kuberneteswatchtriggerlog.Debug("validate create", zap.String("name", r.Name)) + err := r.Validate() + if err != nil { + err = AggregateValidationErrors("Watch", err) + return err + } + return nil +} + +// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type +func (r *KubernetesWatchTrigger) ValidateUpdate(old runtime.Object) error { + // WATCH UPDATE NOT IMPLEMENTED + return nil +} + +// ValidateDelete implements webhook.Validator so a webhook will be registered for the type +func (r *KubernetesWatchTrigger) ValidateDelete() error { + kuberneteswatchtriggerlog.Debug("validate delete", zap.String("name", r.Name)) + return nil +} diff --git a/pkg/apis/core/v1/messagequeuetrigger_webhook.go b/pkg/apis/core/v1/messagequeuetrigger_webhook.go new file mode 100644 index 00000000..febe822c --- /dev/null +++ b/pkg/apis/core/v1/messagequeuetrigger_webhook.go @@ -0,0 +1,77 @@ +/* +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 v1 + +import ( + "go.uber.org/zap" + "k8s.io/apimachinery/pkg/runtime" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/webhook" + + "github.com/fission/fission/pkg/utils/loggerfactory" +) + +// log is for logging in this package. +var messagequeuetriggerlog = loggerfactory.GetLogger().Named("messagequeuetrigger-resource") + +func (r *MessageQueueTrigger) SetupWebhookWithManager(mgr ctrl.Manager) error { + return ctrl.NewWebhookManagedBy(mgr). + For(r). + Complete() +} + +// Admission webhooks can be added by adding tag: kubebuilder:webhook:path=/mutate-fission-io-v1-messagequeuetrigger,mutating=true,failurePolicy=fail,sideEffects=None,groups=fission.io,resources=messagequeuetriggers,verbs=create;update,versions=v1,name=mmessagequeuetrigger.fission.io,admissionReviewVersions=v1 + +var _ webhook.Defaulter = &MessageQueueTrigger{} + +// Default implements webhook.Defaulter so a webhook will be registered for the type +func (r *MessageQueueTrigger) Default() { + messagequeuetriggerlog.Debug("default", zap.String("name", r.Name)) +} + +// user change verbs to "verbs=create;update;delete" if you want to enable deletion validation. +//+kubebuilder:webhook:path=/validate-fission-io-v1-messagequeuetrigger,mutating=false,failurePolicy=fail,sideEffects=None,groups=fission.io,resources=messagequeuetriggers,verbs=create;update,versions=v1,name=vmessagequeuetrigger.fission.io,admissionReviewVersions=v1 + +var _ webhook.Validator = &MessageQueueTrigger{} + +// ValidateCreate implements webhook.Validator so a webhook will be registered for the type +func (r *MessageQueueTrigger) ValidateCreate() error { + messagequeuetriggerlog.Debug("validate create", zap.String("name", r.Name)) + err := r.Validate() + if err != nil { + err = AggregateValidationErrors("MessageQueueTrigger", err) + return err + } + return nil +} + +// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type +func (r *MessageQueueTrigger) ValidateUpdate(old runtime.Object) error { + messagequeuetriggerlog.Debug("validate update", zap.String("name", r.Name)) + err := r.Validate() + if err != nil { + err = AggregateValidationErrors("MessageQueueTrigger", err) + return err + } + return nil +} + +// ValidateDelete implements webhook.Validator so a webhook will be registered for the type +func (r *MessageQueueTrigger) ValidateDelete() error { + messagequeuetriggerlog.Debug("validate delete", zap.String("name", r.Name)) + return nil +} diff --git a/pkg/apis/core/v1/package_webhook.go b/pkg/apis/core/v1/package_webhook.go new file mode 100644 index 00000000..41a16eef --- /dev/null +++ b/pkg/apis/core/v1/package_webhook.go @@ -0,0 +1,98 @@ +/* +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 v1 + +import ( + "fmt" + + "github.com/dustin/go-humanize" + "go.uber.org/zap" + "k8s.io/apimachinery/pkg/runtime" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/webhook" + + ferror "github.com/fission/fission/pkg/error" + "github.com/fission/fission/pkg/utils/loggerfactory" +) + +// log is for logging in this package. +var packagelog = loggerfactory.GetLogger().Named("package-resource") + +func (r *Package) SetupWebhookWithManager(mgr ctrl.Manager) error { + return ctrl.NewWebhookManagedBy(mgr). + For(r). + Complete() +} + +//+kubebuilder:webhook:path=/mutate-fission-io-v1-package,mutating=true,failurePolicy=fail,sideEffects=None,groups=fission.io,resources=packages,verbs=create;update,versions=v1,name=mpackage.fission.io,admissionReviewVersions=v1 + +var _ webhook.Defaulter = &Package{} + +// Default implements webhook.Defaulter so a webhook will be registered for the type +func (r *Package) Default() { + packagelog.Debug("default", zap.String("name", r.Name)) + if r.Status.BuildStatus == "" { + r.Status.BuildStatus = BuildStatusPending + } +} + +// user change verbs to "verbs=create;update;delete" if you want to enable deletion validation. +//+kubebuilder:webhook:path=/validate-fission-io-v1-package,mutating=false,failurePolicy=fail,sideEffects=None,groups=fission.io,resources=packages,verbs=create;update,versions=v1,name=vpackage.fission.io,admissionReviewVersions=v1 + +var _ webhook.Validator = &Package{} + +// ValidateCreate implements webhook.Validator so a webhook will be registered for the type +func (r *Package) ValidateCreate() error { + packagelog.Debug("validate create", zap.String("name", r.Name)) + err := r.Validate() + if err != nil { + err = AggregateValidationErrors("Package", err) + return err + } + + // Ensure size limits + if len(r.Spec.Source.Literal) > int(ArchiveLiteralSizeLimit) { + err := ferror.MakeError(ferror.ErrorInvalidArgument, + fmt.Sprintf("Package literal larger than %s", humanize.Bytes(uint64(ArchiveLiteralSizeLimit)))) + return err + } + if len(r.Spec.Deployment.Literal) > int(ArchiveLiteralSizeLimit) { + err := ferror.MakeError(ferror.ErrorInvalidArgument, + fmt.Sprintf("Package literal larger than %s", humanize.Bytes(uint64(ArchiveLiteralSizeLimit)))) + return err + } + return nil +} + +// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type +func (r *Package) ValidateUpdate(old runtime.Object) error { + packagelog.Debug("validate update", zap.String("name", r.Name)) + err := r.Validate() + + if err != nil { + err = AggregateValidationErrors("Package", err) + return err + } + + return nil +} + +// ValidateDelete implements webhook.Validator so a webhook will be registered for the type +func (r *Package) ValidateDelete() error { + packagelog.Debug("validate delete", zap.String("name", r.Name)) + return nil +} diff --git a/pkg/apis/core/v1/timetrigger_webhook.go b/pkg/apis/core/v1/timetrigger_webhook.go new file mode 100644 index 00000000..51de6bb2 --- /dev/null +++ b/pkg/apis/core/v1/timetrigger_webhook.go @@ -0,0 +1,92 @@ +/* +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 v1 + +import ( + "github.com/robfig/cron" + "go.uber.org/zap" + "k8s.io/apimachinery/pkg/runtime" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/webhook" + + ferror "github.com/fission/fission/pkg/error" + "github.com/fission/fission/pkg/utils/loggerfactory" +) + +// log is for logging in this package. +var timetriggerlog = loggerfactory.GetLogger().Named("timetrigger-resource") + +func (r *TimeTrigger) SetupWebhookWithManager(mgr ctrl.Manager) error { + return ctrl.NewWebhookManagedBy(mgr). + For(r). + Complete() +} + +// Admission webhooks can be added by adding tag: kubebuilder:webhook:path=/mutate-fission-io-v1-timetrigger,mutating=true,failurePolicy=fail,sideEffects=None,groups=fission.io,resources=timetriggers,verbs=create;update,versions=v1,name=mtimetrigger.fission.io,admissionReviewVersions=v1 + +var _ webhook.Defaulter = &TimeTrigger{} + +// Default implements webhook.Defaulter so a webhook will be registered for the type +func (r *TimeTrigger) Default() { + timetriggerlog.Debug("default", zap.String("name", r.Name)) +} + +// user change verbs to "verbs=create;update;delete" if you want to enable deletion validation. +//+kubebuilder:webhook:path=/validate-fission-io-v1-timetrigger,mutating=false,failurePolicy=fail,sideEffects=None,groups=fission.io,resources=timetriggers,verbs=create;update,versions=v1,name=vtimetrigger.fission.io,admissionReviewVersions=v1 + +var _ webhook.Validator = &TimeTrigger{} + +// ValidateCreate implements webhook.Validator so a webhook will be registered for the type +func (r *TimeTrigger) ValidateCreate() error { + timetriggerlog.Debug("validate create", zap.String("name", r.Name)) + err := r.Validate() + if err != nil { + err = AggregateValidationErrors("TimeTrigger", err) + return err + } + + _, err = cron.Parse(r.Spec.Cron) + if err != nil { + err = ferror.MakeError(ferror.ErrorInvalidArgument, "TimeTrigger cron spec is not valid") + return err + } + return nil +} + +// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type +func (r *TimeTrigger) ValidateUpdate(old runtime.Object) error { + timetriggerlog.Debug("validate update", zap.String("name", r.Name)) + err := r.Validate() + if err != nil { + err = AggregateValidationErrors("TimeTrigger", err) + return err + } + + _, err = cron.Parse(r.Spec.Cron) + if err != nil { + err = ferror.MakeError(ferror.ErrorInvalidArgument, "TimeTrigger cron spec is not valid") + return err + } + + return nil +} + +// ValidateDelete implements webhook.Validator so a webhook will be registered for the type +func (r *TimeTrigger) ValidateDelete() error { + timetriggerlog.Debug("validate delete", zap.String("name", r.Name)) + return nil +} diff --git a/pkg/webhook/admission-webhook.go b/pkg/webhook/admission-webhook.go new file mode 100644 index 00000000..7f53fc54 --- /dev/null +++ b/pkg/webhook/admission-webhook.go @@ -0,0 +1,85 @@ +/* +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 webhook + +import ( + "context" + "os" + + // Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.) + // to ensure that exec-entrypoint and run can make use of them. + + "go.uber.org/zap" + _ "k8s.io/client-go/plugin/pkg/client/auth" + "sigs.k8s.io/controller-runtime/pkg/client/config" + "sigs.k8s.io/controller-runtime/pkg/manager" + + v1 "github.com/fission/fission/pkg/apis/core/v1" + "github.com/fission/fission/pkg/generated/clientset/versioned/scheme" + //+kubebuilder:scaffold:imports +) + +type WebhookInjector interface { + SetupWebhookWithManager(mgr manager.Manager) error +} + +func Start(ctx context.Context, logger *zap.Logger, port int) (err error) { + + wLogger := logger.Named("webhook") + + metricsAddr := os.Getenv("METRICS_ADDR") + if metricsAddr == "" { + metricsAddr = ":8080" + } + // Setup a Manager + mgr, err := manager.New(config.GetConfigOrDie(), manager.Options{ + Scheme: scheme.Scheme, + Port: port, + MetricsBindAddress: metricsAddr, + }) + if err != nil { + wLogger.Error("unable to set up overall controller manager", zap.Error(err)) + return err + } + + // Setup webhooks + + webhookInjectors := []WebhookInjector{ + &v1.CanaryConfig{}, + &v1.Environment{}, + &v1.Package{}, + &v1.Function{}, + &v1.HTTPTrigger{}, + &v1.MessageQueueTrigger{}, + &v1.TimeTrigger{}, + &v1.KubernetesWatchTrigger{}, + } + + for _, injector := range webhookInjectors { + if err := injector.SetupWebhookWithManager(mgr); err != nil { + wLogger.Error("unable to create webhook", zap.Error(err)) + return err + } + } + + wLogger.Info("starting manager") + if err := mgr.Start(ctx); err != nil { + wLogger.Error("unable to run manager", zap.Error(err)) + return err + } + return nil +} diff --git a/skaffold.yaml b/skaffold.yaml index 3f1dcce9..b51fe525 100644 --- a/skaffold.yaml +++ b/skaffold.yaml @@ -63,6 +63,7 @@ deploy: buildermgr.securityContext.enabled: true controller.securityContext.enabled: true kubewatcher.securityContext.enabled: true + webhook.securityContext.enabled: true storagesvc.securityContext.enabled: true wait: true flags: