diff --git a/.ci/jenkins/Jenkinsfile.promote b/.ci/jenkins/Jenkinsfile.promote index 5e240a458..4c6f03641 100644 --- a/.ci/jenkins/Jenkinsfile.promote +++ b/.ci/jenkins/Jenkinsfile.promote @@ -126,6 +126,7 @@ pipeline { withCredentials([usernamePassword(credentialsId: helper.getGitAuthorCredsID(), usernameVariable: 'GH_USER', passwordVariable: 'GH_TOKEN')]) { sh """ gh release upload ${helper.getGitTag()} "operator.yaml" + gh release upload ${helper.getGitTag()} "operator-no-webhooks.yaml" """ } } diff --git a/Makefile b/Makefile index 10dcd876b..380702f6d 100644 --- a/Makefile +++ b/Makefile @@ -98,6 +98,10 @@ help: ## Display this help. manifests: generate ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects. $(CONTROLLER_GEN) rbac:roleName=manager-role crd:allowDangerousTypes=true webhook paths="./api/..." paths="./controllers/..." output:crd:artifacts:config=config/crd/bases +.PHONY: manifests-crd-no-webhooks +manifests-crd-no-webhooks: generate ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects. + $(CONTROLLER_GEN) rbac:roleName=manager-role crd:allowDangerousTypes=true webhook paths="./api/..." paths="./controllers/..." output:crd:artifacts:config=config/crd-no-webhooks/bases + .PHONY: generate generate: controller-gen ## Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations. $(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" paths="./api/..." paths="./container-builder/api/..." @@ -119,7 +123,7 @@ test: manifests generate envtest vet fmt test-api ## Run tests. .PHONY: test-api test-api: - cd api && make test + cd api && make test KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" .PHONY: test-container-builder test-container-builder: @@ -139,9 +143,10 @@ build: generate ## Build manager binary. build-4-debug: generate ## Build manager binary with debug options. go build -gcflags="all=-N -l" -o bin/manager main.go +ENABLE_WEBHOOKS ?= false .PHONY: run run: manifests generate ## Run a controller from your host. - go run ./main.go + ENABLE_WEBHOOKS=${ENABLE_WEBHOOKS} go run ./main.go .PHONY: debug debug: build-4-debug ## Run a controller from your host from binary @@ -159,6 +164,10 @@ podman-build: test ## Build container image with the manager. docker-push: ## Push docker image with the manager. docker push ${IMG} +.PHONY: podman-push +podman-push: ## Push container image with the manager. + podman push ${PODMAN_PUSH_PARAMS} ${IMG} + # This is currently done directly into the CI # PLATFORMS defines the target platforms for the manager image be build to provide support to multiple # architectures. (i.e. make docker-buildx IMG=myregistry/mypoperator:0.0.1). To use this option you need to: @@ -177,10 +186,6 @@ docker-buildx: test ## Build and push docker image for the manager for cross-pla - docker buildx rm project-v3-builder rm Dockerfile.cross -.PHONY: podman-push -podman-push: ## Push container image with the manager. - podman push ${PODMAN_PUSH_PARAMS} ${IMG} - .PHONY: container-build container-build: test ## Build the container image cekit -v --descriptor image.yaml build ${build_options} $(BUILDER) @@ -202,24 +207,34 @@ endif install: manifests kustomize ## Install CRDs into the K8s cluster specified in ~/.kube/config. $(KUSTOMIZE) build config/crd | kubectl create -f - +.PHONY: install-no-webhooks +install-no-webhooks: manifests-crd-no-webhooks kustomize ## Install CRDs into the K8s cluster specified in ~/.kube/config. + $(KUSTOMIZE) build config/crd-no-webhooks | 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: manifests kustomize ## Deploy controller to the K8s cluster specified in ~/.kube/config. +deploy: manifests kustomize install-cert-manager ## Deploy controller to the K8s cluster specified in ~/.kube/config. cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG} $(KUSTOMIZE) build config/default | kubectl create -f - -.PHONY: generate-deploy -generate-deploy: manifests kustomize ## Deploy controller to the K8s cluster specified in ~/.kube/config. +.PHONY: deploy-no-webhooks +deploy-no-webhooks: manifests-crd-no-webhooks kustomize ## Deploy controller to the K8s cluster specified in ~/.kube/config. cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG} - $(KUSTOMIZE) build config/default > operator.yaml + $(KUSTOMIZE) build config/default-no-webhooks | 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. +undeploy: uninstall-cert-manager ## 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 - +.PHONY: generate-deploy +generate-deploy: manifests kustomize ## Deploy controller to the K8s cluster specified in ~/.kube/config. + cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG} + $(KUSTOMIZE) build config/default > operator.yaml + $(KUSTOMIZE) build config/default-no-webhooks > operator-no-webhooks.yaml + ##@ Build Dependencies ## Location to install dependencies to @@ -265,7 +280,7 @@ bundle-build: ## Build the bundle image. .PHONY: bundle-push bundle-push: ## Push the bundle image. - $(MAKE) contianer-push IMG=$(BUNDLE_IMG) + $(MAKE) container-push IMG=$(BUNDLE_IMG) .PHONY: opm OPM = ./bin/opm @@ -330,7 +345,15 @@ generate-all: generate generate-deploy bundle addheaders vet fmt .PHONY: test-e2e # You will need to have a Minikube/Kind cluster up in running to run this target, and run container-builder before the test test-e2e: install-operator-sdk - go test ./test/e2e/* -v -ginkgo.v + go test -timeout=20m ./test/e2e/* -v -ginkgo.v .PHONY: before-pr -before-pr: test generate-all \ No newline at end of file +before-pr: test generate-all + +.PHONY: install-cert-manager +install-cert-manager: + ./hack/local/cert-manager.sh install + +.PHONY: uninstall-cert-manager +uninstall-cert-manager: + ./hack/local/cert-manager.sh uninstall \ No newline at end of file diff --git a/PROJECT b/PROJECT index 0dc6a090f..0fdacec75 100644 --- a/PROJECT +++ b/PROJECT @@ -16,6 +16,10 @@ resources: kind: SonataFlow path: github.com/kiegroup/kogito-serverless-operator/api/v1alpha08 version: v1alpha08 + webhooks: + defaulting: true + validation: true + webhookVersion: v1 - api: crdVersion: v1 namespaced: true diff --git a/api/Makefile b/api/Makefile index 00c73d818..0a57d6a70 100644 --- a/api/Makefile +++ b/api/Makefile @@ -1,3 +1,3 @@ .PHONY: test test: - go test $(shell go list ./... | grep -v /test/) -coverprofile cover.out + KUBEBUILDER_ASSETS=${KUBEBUILDER_ASSETS} go test $(shell go list ./... | grep -v /test/) -coverprofile cover.out diff --git a/api/go.mod b/api/go.mod index a674e6960..ba2e50faf 100644 --- a/api/go.mod +++ b/api/go.mod @@ -4,8 +4,12 @@ go 1.19 require ( github.com/serverlessworkflow/sdk-go/v2 v2.2.4 + github.com/onsi/ginkgo/v2 v2.9.5 + github.com/onsi/gomega v1.27.7 k8s.io/api v0.27.2 k8s.io/apimachinery v0.27.2 + k8s.io/client-go v0.27.2 + k8s.io/klog/v2 v2.100.1 knative.dev/pkg v0.0.0-20230525143525-9bda38b21643 sigs.k8s.io/controller-runtime v0.15.0 sigs.k8s.io/yaml v1.3.0 @@ -20,18 +24,21 @@ require ( github.com/evanphx/json-patch/v5 v5.6.0 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/go-logr/logr v1.2.4 // indirect + github.com/go-logr/zapr v1.2.4 // indirect github.com/go-openapi/jsonpointer v0.19.6 // indirect github.com/go-openapi/jsonreference v0.20.1 // indirect github.com/go-openapi/swag v0.22.3 // indirect github.com/go-playground/locales v0.14.0 // indirect github.com/go-playground/universal-translator v0.18.0 // indirect github.com/go-playground/validator/v10 v10.11.1 // indirect + github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/google/gnostic v0.6.9 // indirect github.com/google/go-cmp v0.5.9 // indirect github.com/google/gofuzz v1.2.0 // indirect + github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 // indirect github.com/google/uuid v1.3.0 // indirect github.com/imdario/mergo v0.3.13 // indirect github.com/josharian/intern v1.0.0 // indirect @@ -52,15 +59,15 @@ require ( github.com/stretchr/testify v1.8.2 // indirect go.uber.org/atomic v1.10.0 // indirect go.uber.org/multierr v1.9.0 // indirect + go.uber.org/zap v1.24.0 // indirect golang.org/x/crypto v0.8.0 // indirect - golang.org/x/mod v0.10.0 // indirect golang.org/x/net v0.10.0 // indirect golang.org/x/oauth2 v0.7.0 // indirect - golang.org/x/sync v0.2.0 // indirect golang.org/x/sys v0.8.0 // indirect golang.org/x/term v0.8.0 // indirect golang.org/x/text v0.9.0 // indirect golang.org/x/time v0.3.0 // indirect + golang.org/x/tools v0.9.1 // indirect gomodules.xyz/jsonpatch/v2 v2.3.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/protobuf v1.30.0 // indirect @@ -68,9 +75,7 @@ require ( gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/apiextensions-apiserver v0.27.2 // indirect - k8s.io/client-go v0.27.2 // indirect k8s.io/component-base v0.27.2 // indirect - k8s.io/klog/v2 v2.100.1 // indirect k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f // indirect k8s.io/utils v0.0.0-20230313181309-38a27ef9d749 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect diff --git a/api/go.sum b/api/go.sum index 598f9f33e..3810e6d26 100644 --- a/api/go.sum +++ b/api/go.sum @@ -1,341 +1,87 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= -github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= -github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= -github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= github.com/emicklei/go-restful/v3 v3.9.0 h1:XwGDlfxEnQZzuopoqxwSEllNcCOM9DhhFyhFIIGKwxE= -github.com/emicklei/go-restful/v3 v3.9.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= -github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCvpL6mnFh5mB2/l16U= -github.com/evanphx/json-patch v5.6.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/flowstack/go-jsonschema v0.1.1/go.mod h1:yL7fNggx1o8rm9RlgXv7hTBWxdBM0rVwpMwimd3F3N0= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= -github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= -github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= -github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/zapr v1.2.4 h1:QHVo+6stLbfJmYGkQ7uGHUCu5hnAFAj6mDe6Ea0SeOo= github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= -github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= github.com/go-openapi/jsonreference v0.20.1 h1:FBLnyygC4/IZZr893oiomc9XaghoveYTrLC1F86HID8= -github.com/go-openapi/jsonreference v0.20.1/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= -github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= -github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU= -github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho= -github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA= github.com/go-playground/validator/v10 v10.11.1 h1:prmOlTVv+YjZjmRmNSF3VmspqJIxJWXmqUsHwfTRRkQ= -github.com/go-playground/validator/v10 v10.11.1/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4dMGDBiPU55YFDl0WbKdWU= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/gnostic v0.6.9 h1:ZK/5VhkoX835RikCHpSUJV9a+S3e1zLh59YnyWeBW+0= -github.com/google/gnostic v0.6.9/go.mod h1:Nm8234We1lq6iB9OmlgNv3nH91XLLVZHCDayfA3xq+E= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= -github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec= -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/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk= -github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= -github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= -github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= -github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= -github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= -github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= -github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/onsi/ginkgo/v2 v2.9.5 h1:+6Hr4uxzP4XIUyAkg61dWBw8lb/gc4/X5luuxN/EC+Q= github.com/onsi/gomega v1.27.7 h1:fVih9JD6ogIiHUN6ePK7HJidyEDpWGVB5mzM7cWNXoU= -github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_golang v1.15.1 h1:8tXpTmJbyH5lydzFPoxSIJ0J46jdh3tylbvM1xCv0LI= -github.com/prometheus/client_golang v1.15.1/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY= -github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM= -github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= -github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= -github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= -github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/senseyeio/duration v0.0.0-20180430131211-7c2a214ada46 h1:Dz0HrI1AtNSGCE8LXLLqoZU4iuOJXPWndenCsZfstA8= -github.com/senseyeio/duration v0.0.0-20180430131211-7c2a214ada46/go.mod h1:is8FVkzSi7PYLWEXT5MgWhglFsyyiW8ffxAoJqfuFZo= github.com/serverlessworkflow/sdk-go/v2 v2.2.4 h1:uAYaezqiw6Q3RR3UBRQOd5YCZtmYtLZAYC74iW253dU= -github.com/serverlessworkflow/sdk-go/v2 v2.2.4/go.mod h1:YmKuDaZ81zLyIfYZtgkcUpOzGN8xWMWeZGGaO5pW0Us= -github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= -github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= -github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= -go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= -go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.8.0 h1:pd9TJtTueMTVQXzk8E2XESSMQDj/U7OUu0PqJqPXQjQ= -golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk= -golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= -golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.7.0 h1:qe6s0zUXlPX80/dITx3440hWZ7GwMwgDDyrSGTPJG/g= -golang.org/x/oauth2 v0.7.0/go.mod h1:hPLQkd9LyjfXTiRohC/41GhcFqxisoUQ99sCUOHO9x4= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI= -golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols= -golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= -golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.9.1 h1:8WMNJAz3zrtPmnYC7ISf5dEn3MT0gY7jBJfw27yrrLo= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -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.3.0 h1:8NFhfS6gzxNqjLIYnZxg319wZ5Qjnx4m/CcX+Klzazc= -gomodules.xyz/jsonpatch/v2 v2.3.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= -google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20220107163113-42d7afdf6368/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= -google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= -google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= -gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= k8s.io/api v0.27.2 h1:+H17AJpUMvl+clT+BPnKf0E3ksMAzoBBg7CntpSuADo= -k8s.io/api v0.27.2/go.mod h1:ENmbocXfBT2ADujUXcBhHV55RIT31IIEvkntP6vZKS4= k8s.io/apiextensions-apiserver v0.27.2 h1:iwhyoeS4xj9Y7v8YExhUwbVuBhMr3Q4bd/laClBV6Bo= -k8s.io/apiextensions-apiserver v0.27.2/go.mod h1:Oz9UdvGguL3ULgRdY9QMUzL2RZImotgxvGjdWRq6ZXQ= k8s.io/apimachinery v0.27.2 h1:vBjGaKKieaIreI+oQwELalVG4d8f3YAMNpWLzDXkxeg= -k8s.io/apimachinery v0.27.2/go.mod h1:XNfZ6xklnMCOGGFNqXG7bUrQCoR04dh/E7FprV6pb+E= k8s.io/client-go v0.27.2 h1:vDLSeuYvCHKeoQRhCXjxXO45nHVv2Ip4Fe0MfioMrhE= -k8s.io/client-go v0.27.2/go.mod h1:tY0gVmUsHrAmjzHX9zs7eCjxcBsf8IiNe7KQ52biTcQ= k8s.io/component-base v0.27.2 h1:neju+7s/r5O4x4/txeUONNTS9r1HsPbyoPBAtHsDCpo= -k8s.io/component-base v0.27.2/go.mod h1:5UPk7EjfgrfgRIuDBFtsEFAe4DAvP3U+M8RTzoSJkpo= k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg= -k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f h1:2kWPakN3i/k81b0gvD5C5FJ2kxm1WrQFanWchyKuqGg= -k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f/go.mod h1:byini6yhqGC14c3ebc/QwanvYwhuMWF6yz2F8uwW8eg= k8s.io/utils v0.0.0-20230313181309-38a27ef9d749 h1:xMMXJlJbsU8w3V5N2FLDQ8YgU8s1EoULdbQBcAeNJkY= -k8s.io/utils v0.0.0-20230313181309-38a27ef9d749/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= knative.dev/pkg v0.0.0-20230525143525-9bda38b21643 h1:DoGHeW3ckr509v87NcYSSuRHEnxKIxyJxWrrDO/71CY= -knative.dev/pkg v0.0.0-20230525143525-9bda38b21643/go.mod h1:dqC6IrvyBE7E+oZocs5PkVhq1G59pDTA7r8U17EAKMk= sigs.k8s.io/controller-runtime v0.15.0 h1:ML+5Adt3qZnMSYxZ7gAverBLNPSMQEibtzAgp0UPojU= -sigs.k8s.io/controller-runtime v0.15.0/go.mod h1:7ngYvp1MLT+9GeZ+6lH3LOlcHkp/+tzA/fmHa4iq9kk= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= -sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= -sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= -sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= diff --git a/api/v1alpha08/sonataflow_webhook.go b/api/v1alpha08/sonataflow_webhook.go new file mode 100644 index 000000000..b61e67967 --- /dev/null +++ b/api/v1alpha08/sonataflow_webhook.go @@ -0,0 +1,99 @@ +// Copyright 2023 Red Hat, Inc. and/or its affiliates +// +// 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 v1alpha08 + +import ( + "fmt" + + cncfvalidator "github.com/serverlessworkflow/sdk-go/v2/validator" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/klog/v2" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/webhook" + "sigs.k8s.io/controller-runtime/pkg/webhook/admission" + + "github.com/kiegroup/kogito-serverless-operator/api/metadata" + "github.com/kiegroup/kogito-serverless-operator/log" +) + +func (r *SonataFlow) SetupWebhookWithManager(mgr ctrl.Manager) error { + return ctrl.NewWebhookManagedBy(mgr). + For(r). + Complete() +} + +// Uncomment to enable the mutating webhook. +// Uncomment also the mutating webhook in the config/default/webhookcainjection_patch.yaml file. +// //+kubebuilder:webhook:path=/mutate-sonataflow-org-v1alpha08-sonataflow,mutating=true,failurePolicy=fail,sideEffects=None,groups=sonataflow.org,resources=sonataflows,verbs=create;update,versions=v1alpha08,name=msonataflow.kb.io,admissionReviewVersions=v1 + +var _ webhook.Defaulter = &SonataFlow{} + +// Default implements webhook.Defaulter so a webhook will be registered for the type +func (s *SonataFlow) Default() { + klog.V(log.D).InfoS("Applying default values for ", "name", s.Name) + // Add defaults + if len(s.ObjectMeta.Annotations[metadata.Version]) == 0 { + s.ObjectMeta.Annotations[metadata.Version] = "0.0.1" + } +} + +// change verbs to "verbs=create;update;delete" if you want to enable deletion validation. +//+kubebuilder:webhook:path=/validate-sonataflow-org-v1alpha08-sonataflow,mutating=false,failurePolicy=fail,sideEffects=None,groups=sonataflow.org,resources=sonataflows,verbs=create;update;delete,versions=v1alpha08,name=vsonataflow.kb.io,admissionReviewVersions=v1 + +var _ webhook.Validator = &SonataFlow{} + +var requiredMetadataFields = [2]string{metadata.Description, metadata.Version} + +// ValidateCreate implements webhook.Validator so a webhook will be registered for the type +func (s *SonataFlow) ValidateCreate() (admission.Warnings, error) { + klog.V(log.D).InfoS("validate create", "name", s.Name) + return nil, validate(s) +} + +// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type +func (s *SonataFlow) ValidateUpdate(old runtime.Object) (admission.Warnings, error) { + klog.V(log.D).InfoS("validate update", "name", s.Name) + return nil, validate(s) +} + +// ValidateDelete implements webhook.Validator so a webhook will be registered for the type +func (s *SonataFlow) ValidateDelete() (admission.Warnings, error) { + // TODO + return nil, nil +} + +func validate(s *SonataFlow) error { + // validate the required metadata + response := "Field metadata.annotation.%s.%s not set." + var missingAnnotations []string + for _, field := range requiredMetadataFields { + if len(s.Annotations[field]) == 0 { + missingAnnotations = append(missingAnnotations, fmt.Sprintf(response, metadata.Domain, field)) + } + } + if len(missingAnnotations) > 0 { + return fmt.Errorf("%+v", missingAnnotations) + } + + klog.V(log.D).InfoS("Validating workflow", "flow", s.Spec.Flow) + + validator := cncfvalidator.GetValidator() + fmt.Printf("validator: %+v", s.Spec.Flow) + if err := validator.Struct(s.Spec.Flow); err != nil { + return err + } + + return nil +} diff --git a/api/v1alpha08/webhook_suite_test.go b/api/v1alpha08/webhook_suite_test.go new file mode 100644 index 000000000..38a56479a --- /dev/null +++ b/api/v1alpha08/webhook_suite_test.go @@ -0,0 +1,181 @@ +// Copyright 2023 Red Hat, Inc. and/or its affiliates +// +// 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 v1alpha08 + +import ( + "context" + "crypto/tls" + "fmt" + "net" + "path/filepath" + "testing" + "time" + + "github.com/kiegroup/kogito-serverless-operator/api/metadata" + + "github.com/serverlessworkflow/sdk-go/v2/model" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + admissionv1beta1 "k8s.io/api/admission/v1beta1" + //+kubebuilder:scaffold:imports + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/rest" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/envtest" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" +) + +// These tests use Ginkgo (BDD-style Go testing framework). Refer to +// http://onsi.github.io/ginkgo/ to learn more about Ginkgo. + +var cfg *rest.Config +var k8sClient client.Client +var testEnv *envtest.Environment +var ctx context.Context +var cancel context.CancelFunc + +func TestAPIs(t *testing.T) { + RegisterFailHandler(Fail) + + RunSpecs(t, "Webhook Suite") +} + +var _ = BeforeSuite(func() { + logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) + + ctx, cancel = context.WithCancel(context.TODO()) + + By("bootstrapping test environment") + testEnv = &envtest.Environment{ + CRDDirectoryPaths: []string{filepath.Join("..", "..", "config", "crd", "bases")}, + ErrorIfCRDPathMissing: false, + WebhookInstallOptions: envtest.WebhookInstallOptions{ + Paths: []string{filepath.Join("..", "..", "config", "webhook")}, + }, + } + + var err error + // cfg is defined in this file globally. + cfg, err = testEnv.Start() + Expect(err).NotTo(HaveOccurred()) + Expect(cfg).NotTo(BeNil()) + + scheme := runtime.NewScheme() + err = AddToScheme(scheme) + Expect(err).NotTo(HaveOccurred()) + + err = admissionv1beta1.AddToScheme(scheme) + Expect(err).NotTo(HaveOccurred()) + + //+kubebuilder:scaffold:scheme + + k8sClient, err = client.New(cfg, client.Options{Scheme: scheme}) + Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient).NotTo(BeNil()) + + // start webhook server using Manager + webhookInstallOptions := &testEnv.WebhookInstallOptions + mgr, err := ctrl.NewManager(cfg, ctrl.Options{ + Scheme: scheme, + Host: webhookInstallOptions.LocalServingHost, + Port: webhookInstallOptions.LocalServingPort, + CertDir: webhookInstallOptions.LocalServingCertDir, + LeaderElection: false, + MetricsBindAddress: "0", + }) + Expect(err).NotTo(HaveOccurred()) + + err = (&SonataFlow{}).SetupWebhookWithManager(mgr) + Expect(err).NotTo(HaveOccurred()) + + //+kubebuilder:scaffold:webhook + + go func() { + defer GinkgoRecover() + err = mgr.Start(ctx) + Expect(err).NotTo(HaveOccurred()) + }() + + // wait for the webhook server to get ready + dialer := &net.Dialer{Timeout: time.Second} + addrPort := fmt.Sprintf("%s:%d", webhookInstallOptions.LocalServingHost, webhookInstallOptions.LocalServingPort) + Eventually(func() error { + conn, err := tls.DialWithDialer(dialer, "tcp", addrPort, &tls.Config{InsecureSkipVerify: true}) + if err != nil { + return err + } + conn.Close() + return nil + }).Should(Succeed()) + +}) + +var _ = AfterSuite(func() { + cancel() + By("tearing down the test environment") + err := testEnv.Stop() + Expect(err).NotTo(HaveOccurred()) +}) + +var _ = Describe("Test Serverless Workflow Validating Webhook", func() { + Context("basic workflow validations", func() { + + var swf SonataFlow + swf.ObjectMeta.Name = "greeting-fail-no-version" + swf.ObjectMeta.Namespace = "default" + annotations := make(map[string]string) + annotations[metadata.Description] = "Greeting example on k8s!" + swf.ObjectMeta.Annotations = annotations + + swf.Spec.Flow = Flow{ + Start: &model.Start{ + StateName: "ChooseOnLanguage", + }, + } + + state := &model.States{ + model.State{ + BaseState: model.BaseState{ + Name: "ChooseOnLanguage", + Type: "sleep", + End: &model.End{ + Terminate: true, + }, + }, + SleepState: &model.SleepState{ + Duration: "PTasd10S", + }, + }, + } + swf.Spec.Flow.States = *state + + It("should return validation error on missing version annotation", func() { + err := k8sClient.Create(context.TODO(), &swf) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("admission webhook \"vsonataflow.kb.io\" denied the request: [Field metadata.annotation.sonataflow.org.sonataflow.org/version not set.]")) + }) + + It("should return validation error on the workflow definition", func() { + swf.ObjectMeta.Annotations[metadata.Version] = "0.0.1" + err := k8sClient.Create(context.TODO(), &swf) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("admission webhook \"vsonataflow.kb.io\" denied the request: Key: 'Flow.States[0].SleepState.Duration' Error:Field validation for 'Duration' failed on the 'iso8601duration' tag")) + }) + }) +}) diff --git a/bundle/manifests/sonataflow-operator-webhook-service_v1_service.yaml b/bundle/manifests/sonataflow-operator-webhook-service_v1_service.yaml new file mode 100644 index 000000000..3f5623554 --- /dev/null +++ b/bundle/manifests/sonataflow-operator-webhook-service_v1_service.yaml @@ -0,0 +1,21 @@ +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: webhook + app.kubernetes.io/created-by: sonataflow + app.kubernetes.io/instance: webhook-service + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: service + app.kubernetes.io/part-of: sonataflow + name: sonataflow-operator-webhook-service +spec: + ports: + - port: 443 + protocol: TCP + targetPort: 9443 + selector: + control-plane: controller-manager +status: + loadBalancer: {} diff --git a/bundle/manifests/sonataflow-operator.clusterserviceversion.yaml b/bundle/manifests/sonataflow-operator.clusterserviceversion.yaml index 2fc42f029..3250d8d5c 100644 --- a/bundle/manifests/sonataflow-operator.clusterserviceversion.yaml +++ b/bundle/manifests/sonataflow-operator.clusterserviceversion.yaml @@ -412,31 +412,6 @@ spec: control-plane: controller-manager spec: containers: - - args: - - --secure-listen-address=0.0.0.0:8443 - - --upstream=http://127.0.0.1:8080/ - - --logtostderr=true - - --v=0 - image: gcr.io/kubebuilder/kube-rbac-proxy:v0.13.0 - name: kube-rbac-proxy - ports: - - containerPort: 8443 - name: https - protocol: TCP - resources: - limits: - cpu: 500m - memory: 128Mi - requests: - cpu: 5m - memory: 64Mi - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - ALL - seccompProfile: - type: RuntimeDefault - args: - --health-probe-bind-address=:8081 - --metrics-bind-address=127.0.0.1:8080 @@ -457,6 +432,10 @@ spec: initialDelaySeconds: 15 periodSeconds: 20 name: manager + ports: + - containerPort: 9443 + name: webhook-server + protocol: TCP readinessProbe: httpGet: path: /readyz @@ -475,6 +454,31 @@ spec: capabilities: drop: - ALL + - args: + - --secure-listen-address=0.0.0.0:8443 + - --upstream=http://127.0.0.1:8080/ + - --logtostderr=true + - --v=0 + image: gcr.io/kubebuilder/kube-rbac-proxy:v0.13.0 + name: kube-rbac-proxy + ports: + - containerPort: 8443 + name: https + protocol: TCP + resources: + limits: + cpu: 500m + memory: 128Mi + requests: + cpu: 5m + memory: 64Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + seccompProfile: + type: RuntimeDefault securityContext: runAsNonRoot: true seccompProfile: @@ -541,3 +545,36 @@ spec: provider: name: Red Hat version: 2.0.0-snapshot + webhookdefinitions: + - admissionReviewVersions: + - v1 + containerPort: 443 + conversionCRDs: + - sonataflowplatforms.sonataflow.org + deploymentName: sonataflow-operator-controller-manager + generateName: csonataflowplatforms.kb.io + sideEffects: None + targetPort: 9443 + type: ConversionWebhook + webhookPath: /convert + - admissionReviewVersions: + - v1 + containerPort: 443 + deploymentName: sonataflow-operator-controller-manager + failurePolicy: Fail + generateName: vsonataflow.kb.io + rules: + - apiGroups: + - sonataflow.org + apiVersions: + - v1alpha08 + operations: + - CREATE + - UPDATE + - DELETE + resources: + - sonataflows + sideEffects: None + targetPort: 9443 + type: ValidatingAdmissionWebhook + webhookPath: /validate-sonataflow-org-v1alpha08-sonataflow diff --git a/bundle/manifests/sonataflow.org_sonataflowbuilds.yaml b/bundle/manifests/sonataflow.org_sonataflowbuilds.yaml index 0f268ba1a..5fdad5066 100644 --- a/bundle/manifests/sonataflow.org_sonataflowbuilds.yaml +++ b/bundle/manifests/sonataflow.org_sonataflowbuilds.yaml @@ -2,6 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: + cert-manager.io/inject-ca-from: sonataflow-operator-system/sonataflow-operator-serving-cert controller-gen.kubebuilder.io/version: v0.9.2 creationTimestamp: null name: sonataflowbuilds.sonataflow.org diff --git a/bundle/manifests/sonataflow.org_sonataflowplatforms.yaml b/bundle/manifests/sonataflow.org_sonataflowplatforms.yaml index 4bea2cd04..6cc07b17c 100644 --- a/bundle/manifests/sonataflow.org_sonataflowplatforms.yaml +++ b/bundle/manifests/sonataflow.org_sonataflowplatforms.yaml @@ -2,10 +2,21 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: + cert-manager.io/inject-ca-from: sonataflow-operator-system/sonataflow-operator-serving-cert controller-gen.kubebuilder.io/version: v0.9.2 creationTimestamp: null name: sonataflowplatforms.sonataflow.org spec: + conversion: + strategy: Webhook + webhook: + clientConfig: + service: + name: sonataflow-operator-webhook-service + namespace: sonataflow-operator-system + path: /convert + conversionReviewVersions: + - v1 group: sonataflow.org names: kind: SonataFlowPlatform diff --git a/bundle/manifests/sonataflow.org_sonataflows.yaml b/bundle/manifests/sonataflow.org_sonataflows.yaml index 1fd78fd19..99d0150e2 100644 --- a/bundle/manifests/sonataflow.org_sonataflows.yaml +++ b/bundle/manifests/sonataflow.org_sonataflows.yaml @@ -2,6 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: + cert-manager.io/inject-ca-from: sonataflow-operator-system/sonataflow-operator-serving-cert controller-gen.kubebuilder.io/version: v0.9.2 creationTimestamp: null name: sonataflows.sonataflow.org diff --git a/config/certmanager/certificate.yaml b/config/certmanager/certificate.yaml new file mode 100644 index 000000000..6759ea148 --- /dev/null +++ b/config/certmanager/certificate.yaml @@ -0,0 +1,39 @@ +# The following manifests contain a self-signed issuer CR and a certificate CR. +# More document can be found at https://docs.cert-manager.io +# WARNING: Targets CertManager v1.0. Check https://cert-manager.io/docs/installation/upgrading/ for breaking changes. +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + labels: + app.kubernetes.io/name: issuer + app.kubernetes.io/instance: selfsigned-issuer + app.kubernetes.io/component: certificate + app.kubernetes.io/created-by: sonataflow + app.kubernetes.io/part-of: sonataflow + app.kubernetes.io/managed-by: kustomize + name: selfsigned-issuer + namespace: system +spec: + selfSigned: {} +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + labels: + app.kubernetes.io/name: certificate + app.kubernetes.io/instance: serving-cert + app.kubernetes.io/component: certificate + app.kubernetes.io/created-by: sonataflow + app.kubernetes.io/part-of: sonataflow + app.kubernetes.io/managed-by: kustomize + name: serving-cert # this name should match the one appeared in kustomizeconfig.yaml + namespace: system +spec: + # $(SERVICE_NAME) and $(SERVICE_NAMESPACE) will be substituted by kustomize + dnsNames: + - $(SERVICE_NAME).$(SERVICE_NAMESPACE).svc + - $(SERVICE_NAME).$(SERVICE_NAMESPACE).svc.cluster.local + issuerRef: + kind: Issuer + name: selfsigned-issuer + secretName: webhook-server-cert # this secret will not be prefixed, since it's not managed by kustomize \ No newline at end of file diff --git a/config/certmanager/kustomization.yaml b/config/certmanager/kustomization.yaml new file mode 100644 index 000000000..bbaca30d1 --- /dev/null +++ b/config/certmanager/kustomization.yaml @@ -0,0 +1,5 @@ +resources: + - certificate.yaml + +configurations: + - kustomizeconfig.yaml \ No newline at end of file diff --git a/config/certmanager/kustomizeconfig.yaml b/config/certmanager/kustomizeconfig.yaml new file mode 100644 index 000000000..5d0f125b4 --- /dev/null +++ b/config/certmanager/kustomizeconfig.yaml @@ -0,0 +1,16 @@ +# This configuration is for teaching kustomize how to update name ref and var substitution +nameReference: + - kind: Issuer + group: cert-manager.io + fieldSpecs: + - kind: Certificate + group: cert-manager.io + path: spec/issuerRef/name + +varReference: + - kind: Certificate + group: cert-manager.io + path: spec/commonName + - kind: Certificate + group: cert-manager.io + path: spec/dnsNames \ No newline at end of file diff --git a/config/crd-no-webhooks/bases/sonataflow.org_sonataflowbuilds.yaml b/config/crd-no-webhooks/bases/sonataflow.org_sonataflowbuilds.yaml new file mode 100644 index 000000000..d5043d615 --- /dev/null +++ b/config/crd-no-webhooks/bases/sonataflow.org_sonataflowbuilds.yaml @@ -0,0 +1,358 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.9.2 + creationTimestamp: null + name: sonataflowbuilds.sonataflow.org +spec: + group: sonataflow.org + names: + kind: SonataFlowBuild + listKind: SonataFlowBuildList + plural: sonataflowbuilds + shortNames: + - sfb + - sfbuild + - sfbuilds + singular: sonataflowbuild + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.imageTag + name: Image + type: string + - jsonPath: .status.buildPhase + name: Phase + type: string + name: v1alpha08 + schema: + openAPIV3Schema: + description: SonataFlowBuild is an internal custom resource to control workflow + build instances in the target platform + 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: SonataFlowBuildSpec an abstraction over the actual build + process performed by the platform. + properties: + arguments: + description: 'Arguments lists the command line arguments to send to + the internal builder command. Depending on the build method you + might set this attribute instead of BuildArgs. For example: ".spec.arguments=verbose=3". + Please see the SonataFlow guides.' + items: + type: string + type: array + buildArgs: + description: Optional build arguments that can be set to the internal + build (e.g. Docker ARG) + items: + description: EnvVar represents an environment variable present in + a Container. + properties: + name: + description: Name of the environment variable. Must be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded using + the previously defined environment variables in the container + and any service environment variables. If a variable cannot + be resolved, the reference in the input string will be unchanged. + Double $$ are reduced to a single $, which allows for escaping + the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the + string literal "$(VAR_NAME)". Escaped references will never + be expanded, regardless of whether the variable exists or + not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. Cannot + be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, `metadata.annotations['''']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, + status.podIP, status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath is + written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified + API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed + resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the pod's namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + envs: + description: Optional environment variables to add to the internal + build + items: + description: EnvVar represents an environment variable present in + a Container. + properties: + name: + description: Name of the environment variable. Must be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded using + the previously defined environment variables in the container + and any service environment variables. If a variable cannot + be resolved, the reference in the input string will be unchanged. + Double $$ are reduced to a single $, which allows for escaping + the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the + string literal "$(VAR_NAME)". Escaped references will never + be expanded, regardless of whether the variable exists or + not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. Cannot + be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, `metadata.annotations['''']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, + status.podIP, status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath is + written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified + API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed + resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the pod's namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + resources: + description: Resources optional compute resource requirements for + the builder + properties: + claims: + description: "Claims lists the names of resources, defined in + spec.resourceClaims, that are used by this container. \n This + is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be set + for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in pod.spec.resourceClaims + of the Pod where this field is used. It makes that resource + available inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute resources + allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + timeout: + description: Timeout defines the Build maximum execution duration. + The Build deadline is set to the Build start time plus the Timeout + duration. If the Build deadline is exceeded, the Build context is + canceled, and its phase set to BuildPhaseFailed. + format: duration + type: string + type: object + status: + description: SonataFlowBuildStatus defines the observed state of SonataFlowBuild + properties: + buildPhase: + description: Current phase of the build + type: string + error: + description: Last error found during build + type: string + imageTag: + description: The final image tag produced by this build instance + type: string + innerBuild: + description: InnerBuild is a reference to an internal build object, + which can be anything known only to internal builders. + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/config/crd-no-webhooks/bases/sonataflow.org_sonataflowplatforms.yaml b/config/crd-no-webhooks/bases/sonataflow.org_sonataflowplatforms.yaml new file mode 100644 index 000000000..c8196a759 --- /dev/null +++ b/config/crd-no-webhooks/bases/sonataflow.org_sonataflowplatforms.yaml @@ -0,0 +1,480 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.9.2 + creationTimestamp: null + name: sonataflowplatforms.sonataflow.org +spec: + group: sonataflow.org + names: + kind: SonataFlowPlatform + listKind: SonataFlowPlatformList + plural: sonataflowplatforms + shortNames: + - sfp + - sfplatform + - sfplatforms + singular: sonataflowplatform + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.cluster + name: Cluster + type: string + - jsonPath: .status.conditions[?(@.type=='Succeed')].status + name: Ready + type: string + - jsonPath: .status.conditions[?(@.type=='Succeed')].reason + name: Reason + type: string + name: v1alpha08 + schema: + openAPIV3Schema: + description: SonataFlowPlatform is the descriptor for the workflow platform + infrastructure. + 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: SonataFlowPlatformSpec defines the desired state of SonataFlowPlatform + properties: + build: + description: Attributes for building workflows in the target platform + properties: + config: + description: Describes the platform configuration for building + workflows. + properties: + baseImage: + description: a base image that can be used as base layer for + all images. It can be useful if you want to provide some + custom base image with further utility software + type: string + registry: + description: Registry the registry where to publish the built + image + properties: + address: + description: the URI to access + type: string + ca: + description: the configmap which stores the Certificate + Authority + type: string + insecure: + description: if the container registry is insecure (ie, + http only) + type: boolean + organization: + description: the registry organization + type: string + secret: + description: the secret where credentials are stored + type: string + type: object + strategy: + description: BuildStrategy to use to build workflows in the + platform. Usually, the operator elect the strategy based + on the platform. Note that this field might be read only + in certain scenarios. + type: string + strategyOptions: + additionalProperties: + type: string + description: BuildStrategyOptions additional options to add + to the build strategy. See https://sonataflow.org/serverlessworkflow/main/cloud/operator/build-and-deploy-workflows.html + type: object + timeout: + description: how much time to wait before time out the build + process + type: string + type: object + template: + description: Describes a build template for building workflows. + Base for the internal SonataFlowBuild resource. + properties: + arguments: + description: 'Arguments lists the command line arguments to + send to the internal builder command. Depending on the build + method you might set this attribute instead of BuildArgs. + For example: ".spec.arguments=verbose=3". Please see the + SonataFlow guides.' + items: + type: string + type: array + buildArgs: + description: Optional build arguments that can be set to the + internal build (e.g. Docker ARG) + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must + be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables + in the container and any service environment variables. + If a variable cannot be resolved, the reference in + the input string will be unchanged. Double $$ are + reduced to a single $, which allows for escaping the + $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce + the string literal "$(VAR_NAME)". Escaped references + will never be expanded, regardless of whether the + variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or + its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: 'Selects a field of the pod: supports + metadata.name, metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in + the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, limits.ephemeral-storage, requests.cpu, + requests.memory and requests.ephemeral-storage) + are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of + the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + envs: + description: Optional environment variables to add to the + internal build + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must + be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables + in the container and any service environment variables. + If a variable cannot be resolved, the reference in + the input string will be unchanged. Double $$ are + reduced to a single $, which allows for escaping the + $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce + the string literal "$(VAR_NAME)". Escaped references + will never be expanded, regardless of whether the + variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or + its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: 'Selects a field of the pod: supports + metadata.name, metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in + the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, limits.ephemeral-storage, requests.cpu, + requests.memory and requests.ephemeral-storage) + are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of + the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + resources: + description: Resources optional compute resource requirements + for the builder + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. \n This field + is immutable. It can only be set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry + in pod.spec.resourceClaims of the Pod where this + field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of + compute resources required. If Requests is omitted for + a container, it defaults to Limits if that is explicitly + specified, otherwise to an implementation-defined value. + Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + timeout: + description: Timeout defines the Build maximum execution duration. + The Build deadline is set to the Build start time plus the + Timeout duration. If the Build deadline is exceeded, the + Build context is canceled, and its phase set to BuildPhaseFailed. + format: duration + type: string + type: object + type: object + devMode: + description: Attributes for running workflows in devmode (immutable, + no build required) + properties: + baseImage: + description: Base image to run the Workflow in dev mode instead + of the operator's default. + type: string + type: object + type: object + status: + description: SonataFlowPlatformStatus defines the observed state of SonataFlowPlatform + properties: + cluster: + description: Cluster what kind of cluster you're running (ie, plain + Kubernetes or OpenShift) + enum: + - kubernetes + - openshift + type: string + conditions: + description: The latest available observations of a resource's current + state. + items: + description: Condition describes the common structure for conditions + in our types + properties: + lastUpdateTime: + description: The last time this condition was updated. + format: date-time + type: string + message: + description: A human-readable message indicating details about + the transition. + type: string + reason: + description: The reason for the condition's last transition. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: Type condition for the given object + type: string + required: + - status + - type + type: object + type: array + info: + additionalProperties: + type: string + description: Info generic information related to the build + type: object + observedGeneration: + description: The generation observed by the deployment controller. + format: int64 + type: integer + version: + description: Version the operator version controlling this Platform + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/config/crd-no-webhooks/bases/sonataflow.org_sonataflows.yaml b/config/crd-no-webhooks/bases/sonataflow.org_sonataflows.yaml new file mode 100644 index 000000000..f4402b206 --- /dev/null +++ b/config/crd-no-webhooks/bases/sonataflow.org_sonataflows.yaml @@ -0,0 +1,2215 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.9.2 + creationTimestamp: null + name: sonataflows.sonataflow.org +spec: + group: sonataflow.org + names: + kind: SonataFlow + listKind: SonataFlowList + plural: sonataflows + shortNames: + - sf + - workflow + - workflows + singular: sonataflow + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.annotations.sonataflow\.org\/profile + name: Profile + type: string + - jsonPath: .metadata.annotations.sonataflow\.org\/version + name: Version + type: string + - jsonPath: .status.endpoint + name: URL + type: string + - jsonPath: .status.conditions[?(@.type=='Running')].status + name: Ready + type: string + - jsonPath: .status.conditions[?(@.type=='Running')].reason + name: Reason + type: string + name: v1alpha08 + schema: + openAPIV3Schema: + description: SonataFlow is the descriptor representation for a workflow application + based on the CNCF Serverless Workflow specification. + 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: SonataFlowSpec defines the desired state of SonataFlow + properties: + flow: + description: "Flow describes the contents of the Workflow definition + following the CNCF Serverless Workflow Specification. The attributes + not part of the flow are defined by the Custom Resource metadata + information, as follows: \n - Id, name, and key are replaced by + the Custom Resource's name. Must follow the Kubernetes naming patterns + (RFC1123). \n - Description can be added in the CR's annotation + field sonataflow.org/description \n - Version is also defined in + the CR's annotation, field sonataflow.org/version \n - SpecVersion + is in the CR's apiVersion, for example v1alpha08 means that it follows + the specification version 0.8." + properties: + annotations: + description: Annotations List of helpful terms describing the + workflows intended purpose, subject areas, or other important + qualities. + items: + type: string + type: array + auth: + description: Auth definitions can be used to define authentication + information that should be applied to resources defined in the + operation property of function definitions. It is not used as + authentication information for the function invocation, but + just to access the resource containing the function invocation + information. + x-kubernetes-preserve-unknown-fields: true + autoRetries: + description: AutoRetries If set to true, actions should automatically + be retried on unchecked errors. Default is false + type: boolean + constants: + additionalProperties: + 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: Constants Workflow constants are used to define static, + and immutable, data which is available to Workflow Expressions. + type: object + dataInputSchema: + description: DataInputSchema URI of the JSON Schema used to validate + the workflow data input + properties: + failOnValidationErrors: + type: boolean + schema: + type: string + required: + - failOnValidationErrors + - schema + type: object + errors: + description: Defines checked errors that can be explicitly handled + during workflow execution. + items: + description: Error declaration for workflow definitions + properties: + code: + description: Code OnError code. Can be used in addition + to the name to help runtimes resolve to technical errors/exceptions. + Should not be defined if error is set to '*'. + type: string + description: + description: OnError description. + type: string + name: + description: Name Domain-specific error name. + type: string + required: + - name + type: object + type: array + events: + items: + description: Event used to define events and their correlations + properties: + correlation: + description: Define event correlation rules for this event. + Only used for consumed events. + items: + description: Correlation define event correlation rules + for an event. Only used for `consumed` events + properties: + contextAttributeName: + description: CloudEvent Extension Context Attribute + name + type: string + contextAttributeValue: + description: CloudEvent Extension Context Attribute + value + type: string + required: + - contextAttributeName + type: object + type: array + dataOnly: + description: If `true`, only the Event payload is accessible + to consuming Workflow states. If `false`, both event payload + and context attributes should be accessible. Defaults + to true. + type: boolean + kind: + default: consumed + description: Defines the CloudEvent as either 'consumed' + or 'produced' by the workflow. Defaults to `consumed`. + enum: + - consumed + - produced + type: string + metadata: + additionalProperties: + type: object + description: Metadata information + type: object + name: + description: Unique event name. + type: string + source: + description: CloudEvent source. + type: string + type: + description: CloudEvent type. + type: string + required: + - name + - type + type: object + type: array + functions: + items: + description: Function ... + properties: + authRef: + description: References an auth definition name to be used + to access to resource defined in the operation parameter. + type: string + metadata: + additionalProperties: + type: object + description: Metadata information + type: object + name: + description: Unique function name + type: string + operation: + description: If type is `rest`, #. + If type is `rpc`, ##. + If type is `expression`, defines the workflow expression. + If the type is `custom`, #. + type: string + type: + default: rest + description: Defines the function type. Is either `custom`, + `rest`, `rpc`, `expression`, `graphql`, `odata` or `asyncapi`. + Default is `rest`. + enum: + - rest + - rpc + - expression + - graphql + - odata + - asyncapi + - custom + type: string + required: + - name + - operation + type: object + type: array + keepActive: + description: If "true", workflow instances is not terminated when + there are no active execution paths. Instance can be terminated + with "terminate end definition" or reaching defined "workflowExecTimeout" + type: boolean + metadata: + description: Metadata custom information shared with the runtime. + x-kubernetes-preserve-unknown-fields: true + retries: + items: + description: Retry ... + properties: + delay: + description: Time delay between retry attempts (ISO 8601 + duration format) + type: string + increment: + description: Static value by which the delay increases during + each attempt (ISO 8601 time format) + type: string + jitter: + description: 'If float type, maximum amount of random time + added or subtracted from the delay between each retry + relative to total delay (between 0 and 1). If string type, + absolute maximum amount of random time added or subtracted + from the delay between each retry (ISO 8601 duration format) + TODO: make iso8601duration compatible this type' + properties: + floatVal: + type: number + strVal: + type: string + type: + description: Type represents the stored type of Float32OrString. + format: int64 + type: integer + type: object + maxAttempts: + anyOf: + - type: integer + - type: string + description: Maximum number of retry attempts. + x-kubernetes-int-or-string: true + maxDelay: + description: Maximum time delay between retry attempts (ISO + 8601 duration format) + type: string + multiplier: + description: Numeric value, if specified the delay between + retries is multiplied by this value. + properties: + floatVal: + type: number + strVal: + type: string + type: + description: Type represents the stored type of Float32OrString. + format: int64 + type: integer + type: object + name: + description: Unique retry strategy name + type: string + required: + - maxAttempts + - name + type: object + type: array + secrets: + description: Secrets allow you to access sensitive information, + such as passwords, OAuth tokens, ssh keys, etc, inside your + Workflow Expressions. + items: + type: string + type: array + start: + description: Workflow start definition. + x-kubernetes-preserve-unknown-fields: true + states: + items: + properties: + callbackState: + description: callbackState executes a function and waits + for callback event that indicates completion of the task. + properties: + action: + description: Defines the action to be executed. + properties: + actionDataFilter: + description: Filter the state data to select only + the data that can be used within function definition + arguments using its fromStateData property. Filter + the action results to select only the result data + that should be added/merged back into the state + data using its results property. Select the part + of state data which the action data results should + be added/merged to using the toStateData property. + properties: + fromStateData: + description: Workflow expression that filters + state data that can be used by the action. + type: string + results: + description: Workflow expression that filters + the actions data results. + type: string + toStateData: + description: Workflow expression that selects + a state data element to which the action results + should be added/merged into. If not specified + denotes the top-level state data element. + type: string + useResults: + description: If set to false, action data results + are not added/merged to state data. In this + case 'results' and 'toStateData' should be + ignored. Default is true. + type: boolean + type: object + condition: + description: Expression, if defined, must evaluate + to true for this action to be performed. If false, + action is disregarded. + type: string + eventRef: + description: References a 'trigger' and 'result' + reusable event definitions. + properties: + contextAttributes: + additionalProperties: + type: object + description: Add additional extension context + attributes to the produced event. + type: object + data: + description: If string type, an expression which + selects parts of the states data output to + become the data (payload) of the event referenced + by triggerEventRef. If object type, a custom + object to become the data (payload) of the + event referenced by triggerEventRef. + type: object + invoke: + default: sync + description: Specifies if the function should + be invoked sync or async. Default is sync. + enum: + - async + - sync + type: string + resultEventRef: + description: Reference to the unique name of + a 'consumed' event definition + type: string + resultEventTimeout: + description: Maximum amount of time (ISO 8601 + format) to wait for the result event. If not + defined it be set to the actionExecutionTimeout + type: string + triggerEventRef: + description: Reference to the unique name of + a 'produced' event definition, + type: string + required: + - resultEventRef + - triggerEventRef + type: object + functionRef: + description: References a reusable function definition. + properties: + arguments: + additionalProperties: + type: object + description: 'Arguments (inputs) to be passed + to the referenced function TODO: validate + it as required if function type is graphql' + type: object + invoke: + default: sync + description: Specifies if the function should + be invoked sync or async. Default is sync. + enum: + - async + - sync + type: string + refName: + description: Name of the referenced function. + type: string + selectionSet: + description: 'Used if function type is graphql. + String containing a valid GraphQL selection + set. TODO: validate it as required if function + type is graphql' + type: string + required: + - refName + type: object + id: + description: Defines Unique action identifier. + type: string + name: + description: Defines Unique action name. + type: string + nonRetryableErrors: + description: List of unique references to defined + workflow errors for which the action should not + be retried. Used only when `autoRetries` is set + to `true` + items: + type: string + type: array + retryRef: + description: References a defined workflow retry + definition. If not defined uses the default runtime + retry definition. + type: string + retryableErrors: + description: List of unique references to defined + workflow errors for which the action should be + retried. Used only when `autoRetries` is set to + `false` + items: + type: string + type: array + sleep: + description: Defines time period workflow execution + should sleep before / after function execution. + properties: + after: + description: Defines amount of time (ISO 8601 + duration format) to sleep after function/subflow + invocation. Does not apply if 'eventRef' is + defined. + type: string + before: + description: Defines amount of time (ISO 8601 + duration format) to sleep before function/subflow + invocation. Does not apply if 'eventRef' is + defined. + type: string + type: object + subFlowRef: + description: References a workflow to be invoked. + properties: + invoke: + default: sync + description: Specifies if the subflow should + be invoked sync or async. Defaults to sync. + enum: + - async + - sync + type: string + onParentComplete: + default: terminate + description: onParentComplete specifies how + subflow execution should behave when parent + workflow completes if invoke is 'async'. Defaults + to terminate. + enum: + - terminate + - continue + type: string + version: + description: Sub-workflow version + type: string + workflowId: + description: Sub-workflow unique id + type: string + required: + - workflowId + type: object + type: object + eventDataFilter: + description: Event data filter definition. + properties: + data: + description: Workflow expression that filters of + the event data (payload). + type: string + toStateData: + description: Workflow expression that selects a + state data element to which the action results + should be added/merged into. If not specified + denotes the top-level state data element + type: string + useData: + description: If set to false, event payload is not + added/merged to state data. In this case 'data' + and 'toStateData' should be ignored. Default is + true. + type: boolean + type: object + eventRef: + description: References a unique callback event name + in the defined workflow events. + type: string + timeouts: + description: Time period to wait for incoming events + (ISO 8601 format) + properties: + actionExecTimeout: + description: Default single actions definition execution + timeout (ISO 8601 duration format) + type: string + eventTimeout: + description: Default timeout for consuming defined + events (ISO 8601 duration format) + type: string + stateExecTimeout: + description: Default workflow state execution timeout + (ISO 8601 duration format) + properties: + single: + description: Single state execution timeout, + not including retries (ISO 8601 duration format) + type: string + total: + description: Total state execution timeout, + including retries (ISO 8601 duration format) + type: string + required: + - total + type: object + type: object + required: + - action + - eventRef + type: object + compensatedBy: + description: Unique Name of a workflow state which is responsible + for compensation of this state. + type: string + delayState: + description: delayState Causes the workflow execution to + delay for a specified duration. + properties: + timeDelay: + description: Amount of time (ISO 8601 format) to delay + type: string + required: + - timeDelay + type: object + end: + description: State end definition. + x-kubernetes-preserve-unknown-fields: true + eventState: + description: event states await one or more events and perform + actions when they are received. If defined as the workflow + starting state, the event state definition controls when + the workflow instances should be created. + properties: + exclusive: + default: true + description: If true consuming one of the defined events + causes its associated actions to be performed. If + false all the defined events must be consumed in order + for actions to be performed. Defaults to true. + type: boolean + onEvents: + description: Define the events to be consumed and optional + actions to be performed. + items: + description: OnEvents define which actions are be + performed for the one or more events. + properties: + actionMode: + default: sequential + description: Should actions be performed sequentially + or in parallel. Default is sequential. + enum: + - sequential + - parallel + type: string + actions: + description: Actions to be performed if expression + matches + items: + description: Action specify invocations of services + or other workflows during workflow execution. + properties: + actionDataFilter: + description: Filter the state data to select + only the data that can be used within + function definition arguments using its + fromStateData property. Filter the action + results to select only the result data + that should be added/merged back into + the state data using its results property. + Select the part of state data which the + action data results should be added/merged + to using the toStateData property. + properties: + fromStateData: + description: Workflow expression that + filters state data that can be used + by the action. + type: string + results: + description: Workflow expression that + filters the actions data results. + type: string + toStateData: + description: Workflow expression that + selects a state data element to which + the action results should be added/merged + into. If not specified denotes the + top-level state data element. + type: string + useResults: + description: If set to false, action + data results are not added/merged + to state data. In this case 'results' + and 'toStateData' should be ignored. + Default is true. + type: boolean + type: object + condition: + description: Expression, if defined, must + evaluate to true for this action to be + performed. If false, action is disregarded. + type: string + eventRef: + description: References a 'trigger' and + 'result' reusable event definitions. + properties: + contextAttributes: + additionalProperties: + type: object + description: Add additional extension + context attributes to the produced + event. + type: object + data: + description: If string type, an expression + which selects parts of the states + data output to become the data (payload) + of the event referenced by triggerEventRef. + If object type, a custom object to + become the data (payload) of the event + referenced by triggerEventRef. + type: object + invoke: + default: sync + description: Specifies if the function + should be invoked sync or async. Default + is sync. + enum: + - async + - sync + type: string + resultEventRef: + description: Reference to the unique + name of a 'consumed' event definition + type: string + resultEventTimeout: + description: Maximum amount of time + (ISO 8601 format) to wait for the + result event. If not defined it be + set to the actionExecutionTimeout + type: string + triggerEventRef: + description: Reference to the unique + name of a 'produced' event definition, + type: string + required: + - resultEventRef + - triggerEventRef + type: object + functionRef: + description: References a reusable function + definition. + properties: + arguments: + additionalProperties: + type: object + description: 'Arguments (inputs) to + be passed to the referenced function + TODO: validate it as required if function + type is graphql' + type: object + invoke: + default: sync + description: Specifies if the function + should be invoked sync or async. Default + is sync. + enum: + - async + - sync + type: string + refName: + description: Name of the referenced + function. + type: string + selectionSet: + description: 'Used if function type + is graphql. String containing a valid + GraphQL selection set. TODO: validate + it as required if function type is + graphql' + type: string + required: + - refName + type: object + id: + description: Defines Unique action identifier. + type: string + name: + description: Defines Unique action name. + type: string + nonRetryableErrors: + description: List of unique references to + defined workflow errors for which the + action should not be retried. Used only + when `autoRetries` is set to `true` + items: + type: string + type: array + retryRef: + description: References a defined workflow + retry definition. If not defined uses + the default runtime retry definition. + type: string + retryableErrors: + description: List of unique references to + defined workflow errors for which the + action should be retried. Used only when + `autoRetries` is set to `false` + items: + type: string + type: array + sleep: + description: Defines time period workflow + execution should sleep before / after + function execution. + properties: + after: + description: Defines amount of time + (ISO 8601 duration format) to sleep + after function/subflow invocation. + Does not apply if 'eventRef' is defined. + type: string + before: + description: Defines amount of time + (ISO 8601 duration format) to sleep + before function/subflow invocation. + Does not apply if 'eventRef' is defined. + type: string + type: object + subFlowRef: + description: References a workflow to be + invoked. + properties: + invoke: + default: sync + description: Specifies if the subflow + should be invoked sync or async. Defaults + to sync. + enum: + - async + - sync + type: string + onParentComplete: + default: terminate + description: onParentComplete specifies + how subflow execution should behave + when parent workflow completes if + invoke is 'async'. Defaults to terminate. + enum: + - terminate + - continue + type: string + version: + description: Sub-workflow version + type: string + workflowId: + description: Sub-workflow unique id + type: string + required: + - workflowId + type: object + type: object + type: array + eventDataFilter: + description: eventDataFilter defines the callback + event data filter definition + properties: + data: + description: Workflow expression that filters + of the event data (payload). + type: string + toStateData: + description: Workflow expression that selects + a state data element to which the action + results should be added/merged into. If + not specified denotes the top-level state + data element + type: string + useData: + description: If set to false, event payload + is not added/merged to state data. In this + case 'data' and 'toStateData' should be + ignored. Default is true. + type: boolean + type: object + eventRefs: + description: References one or more unique event + names in the defined workflow events. + items: + type: string + minItems: 1 + type: array + required: + - eventRefs + type: object + minItems: 1 + type: array + timeouts: + description: State specific timeouts. + properties: + actionExecTimeout: + description: Default single actions definition execution + timeout (ISO 8601 duration format) + type: string + eventTimeout: + description: Default timeout for consuming defined + events (ISO 8601 duration format) + type: string + stateExecTimeout: + description: Default workflow state execution timeout + (ISO 8601 duration format) + properties: + single: + description: Single state execution timeout, + not including retries (ISO 8601 duration format) + type: string + total: + description: Total state execution timeout, + including retries (ISO 8601 duration format) + type: string + required: + - total + type: object + type: object + required: + - onEvents + type: object + forEachState: + description: forEachState used to execute actions for each + element of a data set. + properties: + actions: + description: Actions to be executed for each of the + elements of inputCollection. + items: + description: Action specify invocations of services + or other workflows during workflow execution. + properties: + actionDataFilter: + description: Filter the state data to select only + the data that can be used within function definition + arguments using its fromStateData property. + Filter the action results to select only the + result data that should be added/merged back + into the state data using its results property. + Select the part of state data which the action + data results should be added/merged to using + the toStateData property. + properties: + fromStateData: + description: Workflow expression that filters + state data that can be used by the action. + type: string + results: + description: Workflow expression that filters + the actions data results. + type: string + toStateData: + description: Workflow expression that selects + a state data element to which the action + results should be added/merged into. If + not specified denotes the top-level state + data element. + type: string + useResults: + description: If set to false, action data + results are not added/merged to state data. + In this case 'results' and 'toStateData' + should be ignored. Default is true. + type: boolean + type: object + condition: + description: Expression, if defined, must evaluate + to true for this action to be performed. If + false, action is disregarded. + type: string + eventRef: + description: References a 'trigger' and 'result' + reusable event definitions. + properties: + contextAttributes: + additionalProperties: + type: object + description: Add additional extension context + attributes to the produced event. + type: object + data: + description: If string type, an expression + which selects parts of the states data output + to become the data (payload) of the event + referenced by triggerEventRef. If object + type, a custom object to become the data + (payload) of the event referenced by triggerEventRef. + type: object + invoke: + default: sync + description: Specifies if the function should + be invoked sync or async. Default is sync. + enum: + - async + - sync + type: string + resultEventRef: + description: Reference to the unique name + of a 'consumed' event definition + type: string + resultEventTimeout: + description: Maximum amount of time (ISO 8601 + format) to wait for the result event. If + not defined it be set to the actionExecutionTimeout + type: string + triggerEventRef: + description: Reference to the unique name + of a 'produced' event definition, + type: string + required: + - resultEventRef + - triggerEventRef + type: object + functionRef: + description: References a reusable function definition. + properties: + arguments: + additionalProperties: + type: object + description: 'Arguments (inputs) to be passed + to the referenced function TODO: validate + it as required if function type is graphql' + type: object + invoke: + default: sync + description: Specifies if the function should + be invoked sync or async. Default is sync. + enum: + - async + - sync + type: string + refName: + description: Name of the referenced function. + type: string + selectionSet: + description: 'Used if function type is graphql. + String containing a valid GraphQL selection + set. TODO: validate it as required if function + type is graphql' + type: string + required: + - refName + type: object + id: + description: Defines Unique action identifier. + type: string + name: + description: Defines Unique action name. + type: string + nonRetryableErrors: + description: List of unique references to defined + workflow errors for which the action should + not be retried. Used only when `autoRetries` + is set to `true` + items: + type: string + type: array + retryRef: + description: References a defined workflow retry + definition. If not defined uses the default + runtime retry definition. + type: string + retryableErrors: + description: List of unique references to defined + workflow errors for which the action should + be retried. Used only when `autoRetries` is + set to `false` + items: + type: string + type: array + sleep: + description: Defines time period workflow execution + should sleep before / after function execution. + properties: + after: + description: Defines amount of time (ISO 8601 + duration format) to sleep after function/subflow + invocation. Does not apply if 'eventRef' + is defined. + type: string + before: + description: Defines amount of time (ISO 8601 + duration format) to sleep before function/subflow + invocation. Does not apply if 'eventRef' + is defined. + type: string + type: object + subFlowRef: + description: References a workflow to be invoked. + properties: + invoke: + default: sync + description: Specifies if the subflow should + be invoked sync or async. Defaults to sync. + enum: + - async + - sync + type: string + onParentComplete: + default: terminate + description: onParentComplete specifies how + subflow execution should behave when parent + workflow completes if invoke is 'async'. + Defaults to terminate. + enum: + - terminate + - continue + type: string + version: + description: Sub-workflow version + type: string + workflowId: + description: Sub-workflow unique id + type: string + required: + - workflowId + type: object + type: object + minItems: 0 + type: array + batchSize: + anyOf: + - type: integer + - type: string + description: Specifies how many iterations may run in + parallel at the same time. Used if mode property is + set to parallel (default). If not specified, its value + should be the size of the inputCollection. + x-kubernetes-int-or-string: true + inputCollection: + description: Workflow expression selecting an array + element of the states' data. + type: string + iterationParam: + description: Name of the iteration parameter that can + be referenced in actions/workflow. For each parallel + iteration, this param should contain a unique element + of the inputCollection array. + type: string + mode: + default: parallel + description: Specifies how iterations are to be performed + (sequential or in parallel), defaults to parallel. + enum: + - sequential + - parallel + type: string + outputCollection: + description: Workflow expression specifying an array + element of the states data to add the results of each + iteration. + type: string + timeouts: + description: State specific timeout. + properties: + actionExecTimeout: + description: Default single actions definition execution + timeout (ISO 8601 duration format) + type: string + stateExecTimeout: + description: Default workflow state execution timeout + (ISO 8601 duration format) + properties: + single: + description: Single state execution timeout, + not including retries (ISO 8601 duration format) + type: string + total: + description: Total state execution timeout, + including retries (ISO 8601 duration format) + type: string + required: + - total + type: object + type: object + required: + - inputCollection + type: object + id: + description: Unique State id. + type: string + injectState: + description: injectState used to inject static data into + state data input. + properties: + data: + additionalProperties: + type: object + description: JSON object which can be set as state's + data input and can be manipulated via filter + minProperties: 1 + type: object + timeouts: + description: State specific timeouts + properties: + stateExecTimeout: + description: Default workflow state execution timeout + (ISO 8601 duration format) + properties: + single: + description: Single state execution timeout, + not including retries (ISO 8601 duration format) + type: string + total: + description: Total state execution timeout, + including retries (ISO 8601 duration format) + type: string + required: + - total + type: object + type: object + required: + - data + type: object + metadata: + additionalProperties: + type: object + description: Metadata information. + type: object + name: + description: State name. + type: string + onErrors: + description: States error handling and retries definitions. + items: + description: OnError ... + properties: + end: + description: End workflow execution in case of this + error. If retryRef is defined, this ends workflow + only if retries were unsuccessful. + x-kubernetes-preserve-unknown-fields: true + errorRef: + description: ErrorRef Reference to a unique workflow + error definition. Used of errorRefs is not used + type: string + errorRefs: + description: ErrorRefs References one or more workflow + error definitions. Used if errorRef is not used + items: + type: string + type: array + transition: + description: Transition to next state to handle the + error. If retryRef is defined, this transition is + taken only if retries were unsuccessful. + x-kubernetes-preserve-unknown-fields: true + type: object + type: array + operationState: + description: operationState defines a set of actions to + be performed in sequence or in parallel. + properties: + actionMode: + default: sequential + description: Specifies whether actions are performed + in sequence or in parallel, defaults to sequential. + enum: + - sequential + - parallel + type: string + actions: + description: Actions to be performed + items: + description: Action specify invocations of services + or other workflows during workflow execution. + properties: + actionDataFilter: + description: Filter the state data to select only + the data that can be used within function definition + arguments using its fromStateData property. + Filter the action results to select only the + result data that should be added/merged back + into the state data using its results property. + Select the part of state data which the action + data results should be added/merged to using + the toStateData property. + properties: + fromStateData: + description: Workflow expression that filters + state data that can be used by the action. + type: string + results: + description: Workflow expression that filters + the actions data results. + type: string + toStateData: + description: Workflow expression that selects + a state data element to which the action + results should be added/merged into. If + not specified denotes the top-level state + data element. + type: string + useResults: + description: If set to false, action data + results are not added/merged to state data. + In this case 'results' and 'toStateData' + should be ignored. Default is true. + type: boolean + type: object + condition: + description: Expression, if defined, must evaluate + to true for this action to be performed. If + false, action is disregarded. + type: string + eventRef: + description: References a 'trigger' and 'result' + reusable event definitions. + properties: + contextAttributes: + additionalProperties: + type: object + description: Add additional extension context + attributes to the produced event. + type: object + data: + description: If string type, an expression + which selects parts of the states data output + to become the data (payload) of the event + referenced by triggerEventRef. If object + type, a custom object to become the data + (payload) of the event referenced by triggerEventRef. + type: object + invoke: + default: sync + description: Specifies if the function should + be invoked sync or async. Default is sync. + enum: + - async + - sync + type: string + resultEventRef: + description: Reference to the unique name + of a 'consumed' event definition + type: string + resultEventTimeout: + description: Maximum amount of time (ISO 8601 + format) to wait for the result event. If + not defined it be set to the actionExecutionTimeout + type: string + triggerEventRef: + description: Reference to the unique name + of a 'produced' event definition, + type: string + required: + - resultEventRef + - triggerEventRef + type: object + functionRef: + description: References a reusable function definition. + properties: + arguments: + additionalProperties: + type: object + description: 'Arguments (inputs) to be passed + to the referenced function TODO: validate + it as required if function type is graphql' + type: object + invoke: + default: sync + description: Specifies if the function should + be invoked sync or async. Default is sync. + enum: + - async + - sync + type: string + refName: + description: Name of the referenced function. + type: string + selectionSet: + description: 'Used if function type is graphql. + String containing a valid GraphQL selection + set. TODO: validate it as required if function + type is graphql' + type: string + required: + - refName + type: object + id: + description: Defines Unique action identifier. + type: string + name: + description: Defines Unique action name. + type: string + nonRetryableErrors: + description: List of unique references to defined + workflow errors for which the action should + not be retried. Used only when `autoRetries` + is set to `true` + items: + type: string + type: array + retryRef: + description: References a defined workflow retry + definition. If not defined uses the default + runtime retry definition. + type: string + retryableErrors: + description: List of unique references to defined + workflow errors for which the action should + be retried. Used only when `autoRetries` is + set to `false` + items: + type: string + type: array + sleep: + description: Defines time period workflow execution + should sleep before / after function execution. + properties: + after: + description: Defines amount of time (ISO 8601 + duration format) to sleep after function/subflow + invocation. Does not apply if 'eventRef' + is defined. + type: string + before: + description: Defines amount of time (ISO 8601 + duration format) to sleep before function/subflow + invocation. Does not apply if 'eventRef' + is defined. + type: string + type: object + subFlowRef: + description: References a workflow to be invoked. + properties: + invoke: + default: sync + description: Specifies if the subflow should + be invoked sync or async. Defaults to sync. + enum: + - async + - sync + type: string + onParentComplete: + default: terminate + description: onParentComplete specifies how + subflow execution should behave when parent + workflow completes if invoke is 'async'. + Defaults to terminate. + enum: + - terminate + - continue + type: string + version: + description: Sub-workflow version + type: string + workflowId: + description: Sub-workflow unique id + type: string + required: + - workflowId + type: object + type: object + minItems: 0 + type: array + timeouts: + description: State specific timeouts + properties: + actionExecTimeout: + description: Default single actions definition execution + timeout (ISO 8601 duration format) + type: string + stateExecTimeout: + description: Defines workflow state execution timeout. + properties: + single: + description: Single state execution timeout, + not including retries (ISO 8601 duration format) + type: string + total: + description: Total state execution timeout, + including retries (ISO 8601 duration format) + type: string + required: + - total + type: object + type: object + required: + - actions + type: object + parallelState: + description: parallelState Consists of a number of states + that are executed in parallel. + properties: + branches: + description: List of branches for this parallel state. + items: + description: Branch Definition + properties: + actions: + description: Actions to be executed in this branch + items: + description: Action specify invocations of services + or other workflows during workflow execution. + properties: + actionDataFilter: + description: Filter the state data to select + only the data that can be used within + function definition arguments using its + fromStateData property. Filter the action + results to select only the result data + that should be added/merged back into + the state data using its results property. + Select the part of state data which the + action data results should be added/merged + to using the toStateData property. + properties: + fromStateData: + description: Workflow expression that + filters state data that can be used + by the action. + type: string + results: + description: Workflow expression that + filters the actions data results. + type: string + toStateData: + description: Workflow expression that + selects a state data element to which + the action results should be added/merged + into. If not specified denotes the + top-level state data element. + type: string + useResults: + description: If set to false, action + data results are not added/merged + to state data. In this case 'results' + and 'toStateData' should be ignored. + Default is true. + type: boolean + type: object + condition: + description: Expression, if defined, must + evaluate to true for this action to be + performed. If false, action is disregarded. + type: string + eventRef: + description: References a 'trigger' and + 'result' reusable event definitions. + properties: + contextAttributes: + additionalProperties: + type: object + description: Add additional extension + context attributes to the produced + event. + type: object + data: + description: If string type, an expression + which selects parts of the states + data output to become the data (payload) + of the event referenced by triggerEventRef. + If object type, a custom object to + become the data (payload) of the event + referenced by triggerEventRef. + type: object + invoke: + default: sync + description: Specifies if the function + should be invoked sync or async. Default + is sync. + enum: + - async + - sync + type: string + resultEventRef: + description: Reference to the unique + name of a 'consumed' event definition + type: string + resultEventTimeout: + description: Maximum amount of time + (ISO 8601 format) to wait for the + result event. If not defined it be + set to the actionExecutionTimeout + type: string + triggerEventRef: + description: Reference to the unique + name of a 'produced' event definition, + type: string + required: + - resultEventRef + - triggerEventRef + type: object + functionRef: + description: References a reusable function + definition. + properties: + arguments: + additionalProperties: + type: object + description: 'Arguments (inputs) to + be passed to the referenced function + TODO: validate it as required if function + type is graphql' + type: object + invoke: + default: sync + description: Specifies if the function + should be invoked sync or async. Default + is sync. + enum: + - async + - sync + type: string + refName: + description: Name of the referenced + function. + type: string + selectionSet: + description: 'Used if function type + is graphql. String containing a valid + GraphQL selection set. TODO: validate + it as required if function type is + graphql' + type: string + required: + - refName + type: object + id: + description: Defines Unique action identifier. + type: string + name: + description: Defines Unique action name. + type: string + nonRetryableErrors: + description: List of unique references to + defined workflow errors for which the + action should not be retried. Used only + when `autoRetries` is set to `true` + items: + type: string + type: array + retryRef: + description: References a defined workflow + retry definition. If not defined uses + the default runtime retry definition. + type: string + retryableErrors: + description: List of unique references to + defined workflow errors for which the + action should be retried. Used only when + `autoRetries` is set to `false` + items: + type: string + type: array + sleep: + description: Defines time period workflow + execution should sleep before / after + function execution. + properties: + after: + description: Defines amount of time + (ISO 8601 duration format) to sleep + after function/subflow invocation. + Does not apply if 'eventRef' is defined. + type: string + before: + description: Defines amount of time + (ISO 8601 duration format) to sleep + before function/subflow invocation. + Does not apply if 'eventRef' is defined. + type: string + type: object + subFlowRef: + description: References a workflow to be + invoked. + properties: + invoke: + default: sync + description: Specifies if the subflow + should be invoked sync or async. Defaults + to sync. + enum: + - async + - sync + type: string + onParentComplete: + default: terminate + description: onParentComplete specifies + how subflow execution should behave + when parent workflow completes if + invoke is 'async'. Defaults to terminate. + enum: + - terminate + - continue + type: string + version: + description: Sub-workflow version + type: string + workflowId: + description: Sub-workflow unique id + type: string + required: + - workflowId + type: object + type: object + minItems: 1 + type: array + name: + description: Branch name + type: string + timeouts: + description: Branch specific timeout settings + properties: + actionExecTimeout: + description: Single actions definition execution + timeout duration (ISO 8601 duration format) + type: string + branchExecTimeout: + description: Single branch execution timeout + duration (ISO 8601 duration format) + type: string + type: object + required: + - actions + - name + type: object + minItems: 1 + type: array + completionType: + default: allOf + description: Option types on how to complete branch + execution. Defaults to `allOf`. + enum: + - allOf + - atLeast + type: string + numCompleted: + anyOf: + - type: integer + - type: string + description: 'Used when branchCompletionType is set + to atLeast to specify the least number of branches + that must complete in order for the state to transition/end. + TODO: change this field to unmarshal result as int' + x-kubernetes-int-or-string: true + timeouts: + description: State specific timeouts + properties: + branchExecTimeout: + description: Default single branch execution timeout + (ISO 8601 duration format) + type: string + stateExecTimeout: + description: Default workflow state execution timeout + (ISO 8601 duration format) + properties: + single: + description: Single state execution timeout, + not including retries (ISO 8601 duration format) + type: string + total: + description: Total state execution timeout, + including retries (ISO 8601 duration format) + type: string + required: + - total + type: object + type: object + required: + - branches + type: object + sleepState: + description: sleepState suspends workflow execution for + a given time duration. + properties: + duration: + description: Duration (ISO 8601 duration format) to + sleep + type: string + timeouts: + description: Timeouts State specific timeouts + properties: + stateExecTimeout: + description: Default workflow state execution timeout + (ISO 8601 duration format) + properties: + single: + description: Single state execution timeout, + not including retries (ISO 8601 duration format) + type: string + total: + description: Total state execution timeout, + including retries (ISO 8601 duration format) + type: string + required: + - total + type: object + type: object + required: + - duration + type: object + stateDataFilter: + description: State data filter. + properties: + input: + description: Workflow expression to filter the state + data input + type: string + output: + description: Workflow expression that filters the state + data output + type: string + type: object + switchState: + description: 'switchState is workflow''s gateways: direct + transitions onf a workflow based on certain conditions.' + properties: + dataConditions: + description: Defines conditions evaluated against data + items: + description: DataCondition specify a data-based condition + statement which causes a transition to another workflow + state if evaluated to true. + properties: + condition: + description: Workflow expression evaluated against + state data. Must evaluate to true or false. + type: string + end: + description: TODO End or Transition needs to be + exclusive tag, one or another should be set. + Explicit transition to end + properties: + compensate: + description: If set to true, triggers workflow + compensation before workflow execution completes. + Default is false. + type: boolean + continueAs: + description: Defines that current workflow + execution should stop, and execution should + continue as a new workflow instance of the + provided id + properties: + data: + description: If string type, an expression + which selects parts of the states data + output to become the workflow data input + of continued execution. If object type, + a custom object to become the workflow + data input of the continued execution + type: object + version: + description: Version of the workflow to + continue execution as. + type: string + workflowExecTimeout: + description: WorkflowExecTimeout Workflow + execution timeout to be used by the + workflow continuing execution. Overwrites + any specific settings set by that workflow + properties: + duration: + default: unlimited + description: Workflow execution timeout + duration (ISO 8601 duration format). + If not specified should be 'unlimited'. + type: string + interrupt: + description: If false, workflow instance + is allowed to finish current execution. + If true, current workflow execution + is stopped immediately. Default + is false. + type: boolean + runBefore: + description: Name of a workflow state + to be executed before workflow instance + is terminated. + type: string + required: + - duration + type: object + workflowId: + description: Unique id of the workflow + to continue execution as. + type: string + required: + - workflowId + type: object + produceEvents: + description: Array of producedEvent definitions. + Defines events that should be produced. + items: + description: ProduceEvent Defines the event + (CloudEvent format) to be produced when + workflow execution completes or during + a workflow transitions. The eventRef property + must match the name of one of the defined + produced events in the events definition. + properties: + contextAttributes: + additionalProperties: + type: string + description: Add additional event extension + context attributes. + type: object + data: + description: If String, expression which + selects parts of the states data output + to become the data of the produced + event. If object a custom object to + become the data of produced event. + type: object + eventRef: + description: Reference to a defined + unique event name in the events definition + type: string + required: + - eventRef + type: object + type: array + terminate: + description: If true, completes all execution + flows in the given workflow instance. + type: boolean + type: object + metadata: + additionalProperties: + type: object + description: Metadata information. + type: object + name: + description: Data condition name. + type: string + transition: + description: Workflow transition if condition + is evaluated to true + properties: + compensate: + default: false + description: If set to true, triggers workflow + compensation before this transition is taken. + Default is false. + type: boolean + nextState: + description: Name of the state to transition + to next. + type: string + produceEvents: + description: Array of producedEvent definitions. + Events to be produced before the transition + takes place. + items: + description: ProduceEvent Defines the event + (CloudEvent format) to be produced when + workflow execution completes or during + a workflow transitions. The eventRef property + must match the name of one of the defined + produced events in the events definition. + properties: + contextAttributes: + additionalProperties: + type: string + description: Add additional event extension + context attributes. + type: object + data: + description: If String, expression which + selects parts of the states data output + to become the data of the produced + event. If object a custom object to + become the data of produced event. + type: object + eventRef: + description: Reference to a defined + unique event name in the events definition + type: string + required: + - eventRef + type: object + type: array + required: + - nextState + type: object + required: + - condition + - end + type: object + type: array + defaultCondition: + description: Default transition of the workflow if there + is no matching data conditions. Can include a transition + or end definition. + properties: + end: + description: If this state an end state + x-kubernetes-preserve-unknown-fields: true + transition: + description: Serverless workflow states can have + one or more incoming and outgoing transitions + (from/to other states). Each state can define + a transition definition that is used to determine + which state to transition to next. + x-kubernetes-preserve-unknown-fields: true + type: object + eventConditions: + description: Defines conditions evaluated against events. + items: + description: EventCondition specify events which the + switch state must wait for. + properties: + end: + description: TODO End or Transition needs to be + exclusive tag, one or another should be set. + Explicit transition to end + x-kubernetes-preserve-unknown-fields: true + eventDataFilter: + description: Event data filter definition. + properties: + data: + description: Workflow expression that filters + of the event data (payload). + type: string + toStateData: + description: Workflow expression that selects + a state data element to which the action + results should be added/merged into. If + not specified denotes the top-level state + data element + type: string + useData: + description: If set to false, event payload + is not added/merged to state data. In this + case 'data' and 'toStateData' should be + ignored. Default is true. + type: boolean + type: object + eventRef: + description: References a unique event name in + the defined workflow events. + type: string + metadata: + description: Metadata information. + x-kubernetes-preserve-unknown-fields: true + name: + description: Event condition name. + type: string + transition: + description: Workflow transition if condition + is evaluated to true + x-kubernetes-preserve-unknown-fields: true + required: + - eventRef + type: object + type: array + timeouts: + description: SwitchState specific timeouts + properties: + eventTimeout: + description: 'Specify the expire value to transitions + to defaultCondition. When event-based conditions + do not arrive. NOTE: this is only available for + EventConditions' + type: string + stateExecTimeout: + description: Default workflow state execution timeout + (ISO 8601 duration format) + properties: + single: + description: Single state execution timeout, + not including retries (ISO 8601 duration format) + type: string + total: + description: Total state execution timeout, + including retries (ISO 8601 duration format) + type: string + required: + - total + type: object + type: object + required: + - defaultCondition + type: object + transition: + description: Next transition of the workflow after the time + delay. + x-kubernetes-preserve-unknown-fields: true + type: + description: stateType can be any of delay, callback, event, + foreach, inject, operation, parallel, sleep, switch + enum: + - delay + - callback + - event + - foreach + - inject + - operation + - parallel + - sleep + - switch + type: string + usedForCompensation: + description: If true, this state is used to compensate another + state. Default is false. + type: boolean + required: + - name + - type + type: object + minItems: 1 + type: array + x-kubernetes-preserve-unknown-fields: true + timeouts: + description: Defines the workflow default timeout settings. + properties: + actionExecTimeout: + description: ActionExecTimeout Single actions definition execution + timeout duration (ISO 8601 duration format). + type: string + branchExecTimeout: + description: BranchExecTimeout Single branch execution timeout + duration (ISO 8601 duration format). + type: string + eventTimeout: + description: EventTimeout Timeout duration to wait for consuming + defined events (ISO 8601 duration format). + type: string + stateExecTimeout: + description: StateExecTimeout Total state execution timeout + (including retries) (ISO 8601 duration format). + properties: + single: + description: Single state execution timeout, not including + retries (ISO 8601 duration format) + type: string + total: + description: Total state execution timeout, including + retries (ISO 8601 duration format) + type: string + required: + - total + type: object + workflowExecTimeout: + description: WorkflowExecTimeout Workflow execution timeout + duration (ISO 8601 duration format). If not specified should + be 'unlimited'. + properties: + duration: + default: unlimited + description: Workflow execution timeout duration (ISO + 8601 duration format). If not specified should be 'unlimited'. + type: string + interrupt: + description: If false, workflow instance is allowed to + finish current execution. If true, current workflow + execution is stopped immediately. Default is false. + type: boolean + runBefore: + description: Name of a workflow state to be executed before + workflow instance is terminated. + type: string + required: + - duration + type: object + type: object + required: + - states + type: object + resources: + description: Resources workflow resources that are linked to this + workflow definition. For example, a collection of OpenAPI specification + files. + properties: + configMaps: + items: + description: ConfigMapWorkflowResource ConfigMap local reference + holding one or more workflow resources, such as OpenAPI files + that will be mounted in the workflow application. + properties: + configMap: + description: ConfigMap the given configMap name in the same + workflow context to find the resource + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + x-kubernetes-map-type: atomic + workflowPath: + description: WorkflowPath path relative to the workflow + application root file system within the pod (//src/main/resources). Starting trailing slashes will + be removed. + type: string + required: + - configMap + type: object + type: array + type: object + required: + - flow + type: object + status: + description: SonataFlowStatus defines the observed state of SonataFlow + properties: + address: + description: Address is used as a part of Addressable interface (status.address.url) + for knative + properties: + CACerts: + description: CACerts is the Certification Authority (CA) certificates + in PEM format according to https://www.rfc-editor.org/rfc/rfc7468. + type: string + name: + description: Name is the name of the address. + type: string + url: + type: string + type: object + conditions: + description: The latest available observations of a resource's current + state. + items: + description: Condition describes the common structure for conditions + in our types + properties: + lastUpdateTime: + description: The last time this condition was updated. + format: date-time + type: string + message: + description: A human-readable message indicating details about + the transition. + type: string + reason: + description: The reason for the condition's last transition. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: Type condition for the given object + type: string + required: + - status + - type + type: object + type: array + endpoint: + description: Endpoint is an externally accessible URL of the workflow + type: string + lastTimeRecoverAttempt: + format: date-time + type: string + observedGeneration: + description: The generation observed by the deployment controller. + format: int64 + type: integer + recoverFailureAttempts: + description: keeps track of how many failure recovers a given workflow + had so far + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/config/crd-no-webhooks/kustomization.yaml b/config/crd-no-webhooks/kustomization.yaml new file mode 100644 index 000000000..744fd6694 --- /dev/null +++ b/config/crd-no-webhooks/kustomization.yaml @@ -0,0 +1,13 @@ +# 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/sonataflow.org_sonataflows.yaml +- bases/sonataflow.org_sonataflowbuilds.yaml +- bases/sonataflow.org_sonataflowplatforms.yaml +#+kubebuilder:scaffold:crdkustomizeresource + + +# the following config is for teaching kustomize how to do kustomization for CRDs. +configurations: +- kustomizeconfig.yaml diff --git a/config/crd-no-webhooks/kustomizeconfig.yaml b/config/crd-no-webhooks/kustomizeconfig.yaml new file mode 100644 index 000000000..ec5c150a9 --- /dev/null +++ b/config/crd-no-webhooks/kustomizeconfig.yaml @@ -0,0 +1,19 @@ +# 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/crd/kustomization.yaml b/config/crd/kustomization.yaml index a07d24bb8..46fbc88b1 100644 --- a/config/crd/kustomization.yaml +++ b/config/crd/kustomization.yaml @@ -10,16 +10,16 @@ resources: patchesStrategicMerge: # [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix. # patches here are for enabling the conversion webhook for each CRD -#- patches/webhook_in_workflows.yaml -#- patches/webhook_in_sonataflows.yaml -#- patches/webhook_in_sonataflowplatforms.yaml +- patches/cainjection_in_sonataflows.yaml +- patches/cainjection_in_sonataflowbuilds.yaml +- patches/webhook_in_sonataflowplatforms.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 -#- patches/cainjection_in_workflows.yaml -#- patches/cainjection_in_sonataflowworkflows.yaml -#- patches/cainjection_in_sonataflowplatforms.yaml +- patches/cainjection_in_sonataflows.yaml +- patches/cainjection_in_sonataflowbuilds.yaml +- patches/cainjection_in_sonataflowplatforms.yaml #+kubebuilder:scaffold:crdkustomizecainjectionpatch # the following config is for teaching kustomize how to do kustomization for CRDs. diff --git a/config/crd/patches/cainjection_in_sonataflows.yaml b/config/crd/patches/cainjection_in_sonataflows.yaml index 0f2efd86b..4b9aa140c 100644 --- a/config/crd/patches/cainjection_in_sonataflows.yaml +++ b/config/crd/patches/cainjection_in_sonataflows.yaml @@ -4,4 +4,4 @@ kind: CustomResourceDefinition metadata: annotations: cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) - name: sonataflowworkflows.sonataflow.org + name: sonataflows.sonataflow.org diff --git a/config/crd/patches/webhook_in_sonataflows.yaml b/config/crd/patches/webhook_in_sonataflows.yaml index d8550d047..9e9a98d35 100644 --- a/config/crd/patches/webhook_in_sonataflows.yaml +++ b/config/crd/patches/webhook_in_sonataflows.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: - name: sonataflowworkflows.sonataflow.org + name: sonataflows.sonataflow.org spec: conversion: strategy: Webhook diff --git a/config/default-no-webhooks/kustomization.yaml b/config/default-no-webhooks/kustomization.yaml new file mode 100644 index 000000000..94039d3a3 --- /dev/null +++ b/config/default-no-webhooks/kustomization.yaml @@ -0,0 +1,30 @@ +# Adds namespace to all resources. +namespace: sonataflow-operator-system + +# Value of this field is prepended to the +# names of all resources, e.g. a deployment named +# "wordpress" becomes "alices-wordpress". +# Note that it should also match with the prefix (text before '-') of the namespace +# field above. +namePrefix: sonataflow-operator- + +# Labels to add to all resources and selectors. +#commonLabels: +# someName: someValue + +bases: +- ../crd-no-webhooks +- ../rbac +- ../manager-no-webhooks +# [PROMETHEUS] To enable prometheus monitor, uncomment all sections with 'PROMETHEUS'. +#- ../prometheus + +patchesStrategicMerge: +# Protect the /metrics endpoint by putting it behind auth. +# If you want your controller-manager to expose the /metrics +# endpoint w/o any authn/z, please comment the following line. +- manager_auth_proxy_patch.yaml + +# Mount the controller config file for loading manager configurations +# through a ComponentConfig type +#- manager_config_patch.yaml diff --git a/config/default-no-webhooks/manager_auth_proxy_patch.yaml b/config/default-no-webhooks/manager_auth_proxy_patch.yaml new file mode 100644 index 000000000..96de46313 --- /dev/null +++ b/config/default-no-webhooks/manager_auth_proxy_patch.yaml @@ -0,0 +1,42 @@ +# This patch inject a sidecar container which is a HTTP proxy for the +# controller manager, it performs RBAC authorization against the Kubernetes API using SubjectAccessReviews. +apiVersion: apps/v1 +kind: Deployment +metadata: + name: controller-manager + namespace: system +spec: + template: + spec: + containers: + - name: kube-rbac-proxy + image: gcr.io/kubebuilder/kube-rbac-proxy:v0.13.0 + args: + - "--secure-listen-address=0.0.0.0:8443" + - "--upstream=http://127.0.0.1:8080/" + - "--logtostderr=true" + - "--v=0" + ports: + - containerPort: 8443 + protocol: TCP + name: https + resources: + limits: + cpu: 500m + memory: 128Mi + requests: + cpu: 5m + memory: 64Mi + securityContext: + allowPrivilegeEscalation: false + seccompProfile: + type: RuntimeDefault + capabilities: + drop: + - ALL + - name: manager + args: + - "--health-probe-bind-address=:8081" + - "--metrics-bind-address=127.0.0.1:8080" + - "--leader-elect" + - "--v=0" diff --git a/config/default-no-webhooks/manager_config_patch.yaml b/config/default-no-webhooks/manager_config_patch.yaml new file mode 100644 index 000000000..6c400155c --- /dev/null +++ b/config/default-no-webhooks/manager_config_patch.yaml @@ -0,0 +1,20 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: controller-manager + namespace: system +spec: + template: + spec: + containers: + - name: manager + args: + - "--config=controller_manager_config.yaml" + volumeMounts: + - name: manager-config + mountPath: /controller_manager_config.yaml + subPath: controller_manager_config.yaml + volumes: + - name: manager-config + configMap: + name: manager-config diff --git a/config/default/kustomization.yaml b/config/default/kustomization.yaml index 613c7e3b3..6cf1c3a0b 100644 --- a/config/default/kustomization.yaml +++ b/config/default/kustomization.yaml @@ -18,9 +18,9 @@ bases: - ../manager # [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in # crd/kustomization.yaml -#- ../webhook +- ../webhook # [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. 'WEBHOOK' components are required. -#- ../certmanager +- ../certmanager # [PROMETHEUS] To enable prometheus monitor, uncomment all sections with 'PROMETHEUS'. #- ../prometheus @@ -36,39 +36,39 @@ patchesStrategicMerge: # [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in # crd/kustomization.yaml -#- manager_webhook_patch.yaml +- manager_webhook_patch.yaml # [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. # Uncomment 'CERTMANAGER' sections in crd/kustomization.yaml to enable the CA injection in the admission webhooks. # 'CERTMANAGER' needs to be enabled to use ca injection -#- webhookcainjection_patch.yaml +- webhookcainjection_patch.yaml # the following config is for teaching kustomize how to do var substitution vars: # [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER' prefix. -#- name: CERTIFICATE_NAMESPACE # namespace of the certificate CR -# objref: -# kind: Certificate -# group: cert-manager.io -# version: v1 -# name: serving-cert # this name should match the one in certificate.yaml -# fieldref: -# fieldpath: metadata.namespace -#- name: CERTIFICATE_NAME -# objref: -# kind: Certificate -# group: cert-manager.io -# version: v1 -# name: serving-cert # this name should match the one in certificate.yaml -#- name: SERVICE_NAMESPACE # namespace of the service -# objref: -# kind: Service -# version: v1 -# name: webhook-service -# fieldref: -# fieldpath: metadata.namespace -#- name: SERVICE_NAME -# objref: -# kind: Service -# version: v1 -# name: webhook-service +- name: CERTIFICATE_NAMESPACE # namespace of the certificate CR + objref: + kind: Certificate + group: cert-manager.io + version: v1 + name: serving-cert # this name should match the one in certificate.yaml + fieldref: + fieldpath: metadata.namespace +- name: CERTIFICATE_NAME + objref: + kind: Certificate + group: cert-manager.io + version: v1 + name: serving-cert # this name should match the one in certificate.yaml +- name: SERVICE_NAMESPACE # namespace of the service + objref: + kind: Service + version: v1 + name: webhook-service + fieldref: + fieldpath: metadata.namespace +- name: SERVICE_NAME + objref: + kind: Service + version: v1 + name: webhook-service diff --git a/config/default/manager_webhook_patch.yaml b/config/default/manager_webhook_patch.yaml new file mode 100644 index 000000000..716560fc4 --- /dev/null +++ b/config/default/manager_webhook_patch.yaml @@ -0,0 +1,23 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: controller-manager + namespace: system +spec: + template: + spec: + containers: + - name: manager + ports: + - containerPort: 9443 + name: webhook-server + protocol: TCP + volumeMounts: + - mountPath: /tmp/k8s-webhook-server/serving-certs + name: cert + readOnly: true + volumes: + - name: cert + secret: + defaultMode: 420 + secretName: webhook-server-cert \ No newline at end of file diff --git a/config/default/webhookcainjection_patch.yaml b/config/default/webhookcainjection_patch.yaml new file mode 100644 index 000000000..53741b84f --- /dev/null +++ b/config/default/webhookcainjection_patch.yaml @@ -0,0 +1,30 @@ +# This patch add annotation to admission webhook config and +# the variables $(CERTIFICATE_NAMESPACE) and $(CERTIFICATE_NAME) will be substituted by kustomize. +# Uncomment to enable the mudating webhook +#apiVersion: admissionregistration.k8s.io/v1 +#kind: MutatingWebhookConfiguration +#metadata: +# labels: +# app.kubernetes.io/name: mutatingwebhookconfiguration +# app.kubernetes.io/instance: mutating-webhook-configuration +# app.kubernetes.io/component: webhook +# app.kubernetes.io/created-by: sonataflow +# app.kubernetes.io/part-of: sonataflow +# app.kubernetes.io/managed-by: kustomize +# name: mutating-webhook-configuration +# annotations: +# cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + labels: + app.kubernetes.io/name: validatingwebhookconfiguration + app.kubernetes.io/instance: validating-webhook-configuration + app.kubernetes.io/component: webhook + app.kubernetes.io/created-by: sonataflow + app.kubernetes.io/part-of: sonataflow + app.kubernetes.io/managed-by: kustomize + name: validating-webhook-configuration + annotations: + cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) \ No newline at end of file diff --git a/config/manager-no-webhooks/controller_manager_config.yaml b/config/manager-no-webhooks/controller_manager_config.yaml new file mode 100644 index 000000000..4cefd89bb --- /dev/null +++ b/config/manager-no-webhooks/controller_manager_config.yaml @@ -0,0 +1,11 @@ +apiVersion: controller-runtime.sigs.k8s.io/v1alpha1 +kind: ControllerManagerConfig +health: + healthProbeBindAddress: :8081 +metrics: + bindAddress: 127.0.0.1:8080 +webhook: + port: 9443 +leaderElection: + leaderElect: true + resourceName: 1be5e57d.kiegroup.org diff --git a/config/manager-no-webhooks/kustomization.yaml b/config/manager-no-webhooks/kustomization.yaml new file mode 100644 index 000000000..e1e555db2 --- /dev/null +++ b/config/manager-no-webhooks/kustomization.yaml @@ -0,0 +1,40 @@ +resources: +- manager.yaml + +generatorOptions: + disableNameSuffixHash: true + +configMapGenerator: +- files: + - controller_manager_config.yaml + name: manager-config +- files: + - Dockerfile=sonataflow_builder_dockerfile.yaml + literals: + - DEFAULT_BUILDER_RESOURCE_NAME=Dockerfile + - DEFAULT_WORKFLOW_EXTENSION=.sw.json + name: builder-config + +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +images: +- name: controller + newName: quay.io/kiegroup/kogito-serverless-operator-nightly + newTag: latest +patchesJson6902: +- patch: |- + - op: add + path: /spec/template/spec/containers/0/env + value: + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: ENABLE_WEBHOOKS + value: "false" + target: + group: apps + kind: Deployment + name: controller-manager + namespace: system + version: v1 diff --git a/config/manager-no-webhooks/manager.yaml b/config/manager-no-webhooks/manager.yaml new file mode 100644 index 000000000..b01554af6 --- /dev/null +++ b/config/manager-no-webhooks/manager.yaml @@ -0,0 +1,65 @@ +apiVersion: v1 +kind: Namespace +metadata: + labels: + control-plane: controller-manager + name: system +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: controller-manager + namespace: system + labels: + control-plane: controller-manager +spec: + selector: + matchLabels: + control-plane: controller-manager + replicas: 1 + template: + metadata: + annotations: + kubectl.kubernetes.io/default-container: manager + labels: + control-plane: controller-manager + spec: + securityContext: + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + containers: + - command: + - /usr/local/bin/manager + args: + - --leader-elect + - --v=2 + image: controller:latest + name: manager + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + livenessProbe: + httpGet: + path: /healthz + port: 8081 + initialDelaySeconds: 15 + periodSeconds: 20 + readinessProbe: + httpGet: + path: /readyz + port: 8081 + initialDelaySeconds: 5 + periodSeconds: 10 + # More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + resources: + limits: + cpu: 500m + memory: 128Mi + requests: + cpu: 10m + memory: 64Mi + serviceAccountName: controller-manager + terminationGracePeriodSeconds: 10 diff --git a/config/manager-no-webhooks/sonataflow_builder_dockerfile.yaml b/config/manager-no-webhooks/sonataflow_builder_dockerfile.yaml new file mode 100644 index 000000000..90b4a40e8 --- /dev/null +++ b/config/manager-no-webhooks/sonataflow_builder_dockerfile.yaml @@ -0,0 +1,31 @@ +FROM quay.io/kiegroup/kogito-swf-builder-nightly:latest AS builder + +# variables that can be overridden by the builder +# To add a Quarkus extension to your application +ARG QUARKUS_EXTENSIONS +# Args to pass to the Quarkus CLI add extension command +ARG QUARKUS_ADD_EXTENSION_ARGS + +# Copy from build context to skeleton resources project +COPY --chmod=644 * ./resources/ + +RUN /home/kogito/launch/build-app.sh ./resources + +#============================= +# Runtime Run +#============================= +FROM registry.access.redhat.com/ubi8/openjdk-11:latest + +ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en' + +# We make four distinct layers so if there are application changes the library layers can be re-used +COPY --from=builder --chown=185 /home/kogito/serverless-workflow-project/target/quarkus-app/lib/ /deployments/lib/ +COPY --from=builder --chown=185 /home/kogito/serverless-workflow-project/target/quarkus-app/*.jar /deployments/ +COPY --from=builder --chown=185 /home/kogito/serverless-workflow-project/target/quarkus-app/app/ /deployments/app/ +COPY --from=builder --chown=185 /home/kogito/serverless-workflow-project/target/quarkus-app/quarkus/ /deployments/quarkus/ + +EXPOSE 8080 +USER 185 +ENV AB_JOLOKIA_OFF="" +ENV JAVA_OPTS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager" +ENV JAVA_APP_JAR="/deployments/quarkus-run.jar" diff --git a/config/manifests/kustomization.yaml b/config/manifests/kustomization.yaml index 64d054689..135226490 100644 --- a/config/manifests/kustomization.yaml +++ b/config/manifests/kustomization.yaml @@ -9,19 +9,19 @@ resources: # [WEBHOOK] To enable webhooks, uncomment all the sections with [WEBHOOK] prefix. # Do NOT uncomment sections with prefix [CERTMANAGER], as OLM does not support cert-manager. # These patches remove the unnecessary "cert" volume and its manager container volumeMount. -#patchesJson6902: -#- target: -# group: apps -# version: v1 -# kind: Deployment -# name: controller-manager -# namespace: system -# patch: |- -# # Remove the manager container's "cert" volumeMount, since OLM will create and mount a set of certs. -# # Update the indices in this path if adding or removing containers/volumeMounts in the manager's Deployment. -# - op: remove -# path: /spec/template/spec/containers/1/volumeMounts/0 -# # Remove the "cert" volume, since OLM will create and mount a set of certs. -# # Update the indices in this path if adding or removing volumes in the manager's Deployment. -# - op: remove -# path: /spec/template/spec/volumes/0 +patchesJson6902: +- target: + group: apps + version: v1 + kind: Deployment + name: controller-manager + namespace: system + patch: |- + # Remove the manager container's "cert" volumeMount, since OLM will create and mount a set of certs. + # Update the indices in this path if adding or removing containers/volumeMounts in the manager's Deployment. + - op: remove + path: /spec/template/spec/containers/0/volumeMounts/0 + # Remove the "cert" volume, since OLM will create and mount a set of certs. + # Update the indices in this path if adding or removing volumes in the manager's Deployment. + - op: remove + path: /spec/template/spec/volumes/0 diff --git a/config/webhook/kustomization.yaml b/config/webhook/kustomization.yaml new file mode 100644 index 000000000..fbd74f349 --- /dev/null +++ b/config/webhook/kustomization.yaml @@ -0,0 +1,6 @@ +resources: + - manifests.yaml + - service.yaml + +configurations: + - kustomizeconfig.yaml \ No newline at end of file diff --git a/config/webhook/kustomizeconfig.yaml b/config/webhook/kustomizeconfig.yaml new file mode 100644 index 000000000..15185025d --- /dev/null +++ b/config/webhook/kustomizeconfig.yaml @@ -0,0 +1,25 @@ +# the following config is for teaching kustomize where to look at when substituting vars. +# It requires kustomize v2.1.0 or newer to work properly. +nameReference: + - kind: Service + version: v1 + fieldSpecs: + - kind: MutatingWebhookConfiguration + group: admissionregistration.k8s.io + path: webhooks/clientConfig/service/name + - kind: ValidatingWebhookConfiguration + group: admissionregistration.k8s.io + path: webhooks/clientConfig/service/name + +namespace: + - kind: MutatingWebhookConfiguration + group: admissionregistration.k8s.io + path: webhooks/clientConfig/service/namespace + create: true + - kind: ValidatingWebhookConfiguration + group: admissionregistration.k8s.io + path: webhooks/clientConfig/service/namespace + create: true + +varReference: + - path: metadata/annotations \ No newline at end of file diff --git a/config/webhook/manifests.yaml b/config/webhook/manifests.yaml new file mode 100644 index 000000000..616f532d1 --- /dev/null +++ b/config/webhook/manifests.yaml @@ -0,0 +1,28 @@ +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + creationTimestamp: null + name: validating-webhook-configuration +webhooks: +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: webhook-service + namespace: system + path: /validate-sonataflow-org-v1alpha08-sonataflow + failurePolicy: Fail + name: vsonataflow.kb.io + rules: + - apiGroups: + - sonataflow.org + apiVersions: + - v1alpha08 + operations: + - CREATE + - UPDATE + - DELETE + resources: + - sonataflows + sideEffects: None diff --git a/config/webhook/service.yaml b/config/webhook/service.yaml new file mode 100644 index 000000000..ccf809991 --- /dev/null +++ b/config/webhook/service.yaml @@ -0,0 +1,19 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/name: service + app.kubernetes.io/instance: webhook-service + app.kubernetes.io/component: webhook + app.kubernetes.io/created-by: sonataflow + app.kubernetes.io/part-of: sonataflow + app.kubernetes.io/managed-by: kustomize + name: webhook-service + namespace: system +spec: + ports: + - port: 443 + protocol: TCP + targetPort: 9443 + selector: + control-plane: controller-manager \ No newline at end of file diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index d5736b0a8..3a302429e 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -108,6 +108,14 @@ make run > **NOTE:** Run `make help` for more information on all potential `make` targets +> **NOTE:** The Webhook is disabled by default when running it locally, however, if you need to test it, just set +the ENABLE_WEBHOOKS env to true, like this example: +> ```bash +> make run ENABLE_WEBHOOKS=true +> ``` +> For this, please follow the steps described in this [link](https://book.kubebuilder.io/cronjob-tutorial/running.html#running-webhooks-locally). + + More information can be found via the [Kubebuilder Documentation](https://book.kubebuilder.io/introduction.html) ### How-tos @@ -128,6 +136,15 @@ make container-build #### Deploy +When not using OLM it is required to have certificates in place in order for the webhook to properly work. +It is recommended to use the CertManager operator to handle this task. +It is automatically done when executing the `make deploy` command. Or, manually, as described +[here](https://book.kubebuilder.io/cronjob-tutorial/running-webhook.html). + +The make goal `deploy` will check if the CertManager Operator is installed, if not, it will be installed for you, and, +when you're done, it will be cleaned up as part of the `undeploy` make goal. + + ```sh make deploy ``` diff --git a/hack/local/cert-manager.sh b/hack/local/cert-manager.sh new file mode 100755 index 000000000..630cfbb64 --- /dev/null +++ b/hack/local/cert-manager.sh @@ -0,0 +1,65 @@ +#!/usr/bin/env bash +# Copyright 2023 Red Hat, Inc. and/or its affiliates +# +# 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. + +CERT_MANAGER_INSTALLER="https://github.com/cert-manager/cert-manager/releases/download/v1.12.0/cert-manager.yaml" + +# Verify if there is any cert-manager operator installed +function verify() { + # get any pod that has the status different than Running + kubectl -n cert-manager rollout status deploy/cert-manager-webhook --timeout=120s + result_running=$(exec kubectl get pods --namespace cert-manager --field-selector=status.phase==Running --no-headers | wc -l | tr -d ' ') + if [ "${result_running}" != 3 ]; then + echo "cert manager is not ready, please verify." + kubectl get pods --namespace cert-manager + fi + echo "ready" +} + +function clean_up() { + i="--ignore-not-found=true" + kubectl delete $i mutatingwebhookconfiguration.admissionregistration.k8s.io/cert-manager-webhook + kubectl delete $i validatingwebhookconfiguration.admissionregistration.k8s.io/cert-manager-webhook +} + +case "$1" in + "install") + # make sure there is no previous webhooks installed: + clean_up + kubectl apply -f ${CERT_MANAGER_INSTALLER} + max_attempts=10 + counter=0 + while [ $counter -lt $max_attempts ]; do + is_ready=$(verify) + if [ "${is_ready}" == "ready" ]; then + break + else + counter=$((counter+1)) + # wait 3 seconds + sleep 3 + fi + done + ;; + "uninstall") + kubectl delete -f ${CERT_MANAGER_INSTALLER} | true + clean_up + ;; + "verify") + verify + ;; + *) + echo "Option not recognized, allowed values are [un]install and verify." + exit 1 + ;; +esac diff --git a/main.go b/main.go index 14f3ac113..68a2548d7 100644 --- a/main.go +++ b/main.go @@ -17,6 +17,7 @@ package main import ( "flag" "os" + "strconv" "k8s.io/klog/v2/klogr" @@ -46,6 +47,8 @@ var ( scheme = runtime.NewScheme() ) +const enableWebhookEnv = "ENABLE_WEBHOOKS" + func init() { utilruntime.Must(clientgoscheme.AddToScheme(scheme)) utilruntime.Must(operatorapi.AddToScheme(scheme)) @@ -100,6 +103,19 @@ func main() { os.Exit(1) } + // Setup webhooks + enable := true + env := os.Getenv(enableWebhookEnv) + if len(env) > 0 { + enable, _ = strconv.ParseBool(env) + } + if enable { + if err = (&operatorapi.SonataFlow{}).SetupWebhookWithManager(mgr); err != nil { + klog.V(log.E).ErrorS(err, "unable to create webhook", "webhook", "SonataFlow") + os.Exit(1) + } + } + if err = (&controllers.SonataFlowPlatformReconciler{ Client: mgr.GetClient(), Scheme: mgr.GetScheme(), diff --git a/operator-no-webhooks.yaml b/operator-no-webhooks.yaml new file mode 100644 index 000000000..bf2c986cd --- /dev/null +++ b/operator-no-webhooks.yaml @@ -0,0 +1,3628 @@ +apiVersion: v1 +kind: Namespace +metadata: + labels: + control-plane: controller-manager + name: sonataflow-operator-system +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.9.2 + creationTimestamp: null + name: sonataflowbuilds.sonataflow.org +spec: + group: sonataflow.org + names: + kind: SonataFlowBuild + listKind: SonataFlowBuildList + plural: sonataflowbuilds + shortNames: + - sfb + - sfbuild + - sfbuilds + singular: sonataflowbuild + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.imageTag + name: Image + type: string + - jsonPath: .status.buildPhase + name: Phase + type: string + name: v1alpha08 + schema: + openAPIV3Schema: + description: SonataFlowBuild is an internal custom resource to control workflow + build instances in the target platform + 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: SonataFlowBuildSpec an abstraction over the actual build + process performed by the platform. + properties: + arguments: + description: 'Arguments lists the command line arguments to send to + the internal builder command. Depending on the build method you + might set this attribute instead of BuildArgs. For example: ".spec.arguments=verbose=3". + Please see the SonataFlow guides.' + items: + type: string + type: array + buildArgs: + description: Optional build arguments that can be set to the internal + build (e.g. Docker ARG) + items: + description: EnvVar represents an environment variable present in + a Container. + properties: + name: + description: Name of the environment variable. Must be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded using + the previously defined environment variables in the container + and any service environment variables. If a variable cannot + be resolved, the reference in the input string will be unchanged. + Double $$ are reduced to a single $, which allows for escaping + the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the + string literal "$(VAR_NAME)". Escaped references will never + be expanded, regardless of whether the variable exists or + not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. Cannot + be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, `metadata.annotations['''']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, + status.podIP, status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath is + written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified + API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed + resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the pod's namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + envs: + description: Optional environment variables to add to the internal + build + items: + description: EnvVar represents an environment variable present in + a Container. + properties: + name: + description: Name of the environment variable. Must be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded using + the previously defined environment variables in the container + and any service environment variables. If a variable cannot + be resolved, the reference in the input string will be unchanged. + Double $$ are reduced to a single $, which allows for escaping + the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the + string literal "$(VAR_NAME)". Escaped references will never + be expanded, regardless of whether the variable exists or + not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. Cannot + be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, `metadata.annotations['''']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, + status.podIP, status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath is + written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified + API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed + resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the pod's namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + resources: + description: Resources optional compute resource requirements for + the builder + properties: + claims: + description: "Claims lists the names of resources, defined in + spec.resourceClaims, that are used by this container. \n This + is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be set + for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in pod.spec.resourceClaims + of the Pod where this field is used. It makes that resource + available inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute resources + allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + timeout: + description: Timeout defines the Build maximum execution duration. + The Build deadline is set to the Build start time plus the Timeout + duration. If the Build deadline is exceeded, the Build context is + canceled, and its phase set to BuildPhaseFailed. + format: duration + type: string + type: object + status: + description: SonataFlowBuildStatus defines the observed state of SonataFlowBuild + properties: + buildPhase: + description: Current phase of the build + type: string + error: + description: Last error found during build + type: string + imageTag: + description: The final image tag produced by this build instance + type: string + innerBuild: + description: InnerBuild is a reference to an internal build object, + which can be anything known only to internal builders. + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.9.2 + creationTimestamp: null + name: sonataflowplatforms.sonataflow.org +spec: + group: sonataflow.org + names: + kind: SonataFlowPlatform + listKind: SonataFlowPlatformList + plural: sonataflowplatforms + shortNames: + - sfp + - sfplatform + - sfplatforms + singular: sonataflowplatform + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.cluster + name: Cluster + type: string + - jsonPath: .status.conditions[?(@.type=='Succeed')].status + name: Ready + type: string + - jsonPath: .status.conditions[?(@.type=='Succeed')].reason + name: Reason + type: string + name: v1alpha08 + schema: + openAPIV3Schema: + description: SonataFlowPlatform is the descriptor for the workflow platform + infrastructure. + 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: SonataFlowPlatformSpec defines the desired state of SonataFlowPlatform + properties: + build: + description: Attributes for building workflows in the target platform + properties: + config: + description: Describes the platform configuration for building + workflows. + properties: + baseImage: + description: a base image that can be used as base layer for + all images. It can be useful if you want to provide some + custom base image with further utility software + type: string + registry: + description: Registry the registry where to publish the built + image + properties: + address: + description: the URI to access + type: string + ca: + description: the configmap which stores the Certificate + Authority + type: string + insecure: + description: if the container registry is insecure (ie, + http only) + type: boolean + organization: + description: the registry organization + type: string + secret: + description: the secret where credentials are stored + type: string + type: object + strategy: + description: BuildStrategy to use to build workflows in the + platform. Usually, the operator elect the strategy based + on the platform. Note that this field might be read only + in certain scenarios. + type: string + strategyOptions: + additionalProperties: + type: string + description: BuildStrategyOptions additional options to add + to the build strategy. See https://sonataflow.org/serverlessworkflow/main/cloud/operator/build-and-deploy-workflows.html + type: object + timeout: + description: how much time to wait before time out the build + process + type: string + type: object + template: + description: Describes a build template for building workflows. + Base for the internal SonataFlowBuild resource. + properties: + arguments: + description: 'Arguments lists the command line arguments to + send to the internal builder command. Depending on the build + method you might set this attribute instead of BuildArgs. + For example: ".spec.arguments=verbose=3". Please see the + SonataFlow guides.' + items: + type: string + type: array + buildArgs: + description: Optional build arguments that can be set to the + internal build (e.g. Docker ARG) + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must + be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables + in the container and any service environment variables. + If a variable cannot be resolved, the reference in + the input string will be unchanged. Double $$ are + reduced to a single $, which allows for escaping the + $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce + the string literal "$(VAR_NAME)". Escaped references + will never be expanded, regardless of whether the + variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or + its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: 'Selects a field of the pod: supports + metadata.name, metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in + the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, limits.ephemeral-storage, requests.cpu, + requests.memory and requests.ephemeral-storage) + are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of + the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + envs: + description: Optional environment variables to add to the + internal build + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must + be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables + in the container and any service environment variables. + If a variable cannot be resolved, the reference in + the input string will be unchanged. Double $$ are + reduced to a single $, which allows for escaping the + $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce + the string literal "$(VAR_NAME)". Escaped references + will never be expanded, regardless of whether the + variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or + its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: 'Selects a field of the pod: supports + metadata.name, metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in + the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, limits.ephemeral-storage, requests.cpu, + requests.memory and requests.ephemeral-storage) + are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of + the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + resources: + description: Resources optional compute resource requirements + for the builder + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. \n This field + is immutable. It can only be set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry + in pod.spec.resourceClaims of the Pod where this + field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of + compute resources required. If Requests is omitted for + a container, it defaults to Limits if that is explicitly + specified, otherwise to an implementation-defined value. + Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + timeout: + description: Timeout defines the Build maximum execution duration. + The Build deadline is set to the Build start time plus the + Timeout duration. If the Build deadline is exceeded, the + Build context is canceled, and its phase set to BuildPhaseFailed. + format: duration + type: string + type: object + type: object + devMode: + description: Attributes for running workflows in devmode (immutable, + no build required) + properties: + baseImage: + description: Base image to run the Workflow in dev mode instead + of the operator's default. + type: string + type: object + type: object + status: + description: SonataFlowPlatformStatus defines the observed state of SonataFlowPlatform + properties: + cluster: + description: Cluster what kind of cluster you're running (ie, plain + Kubernetes or OpenShift) + enum: + - kubernetes + - openshift + type: string + conditions: + description: The latest available observations of a resource's current + state. + items: + description: Condition describes the common structure for conditions + in our types + properties: + lastUpdateTime: + description: The last time this condition was updated. + format: date-time + type: string + message: + description: A human-readable message indicating details about + the transition. + type: string + reason: + description: The reason for the condition's last transition. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: Type condition for the given object + type: string + required: + - status + - type + type: object + type: array + info: + additionalProperties: + type: string + description: Info generic information related to the build + type: object + observedGeneration: + description: The generation observed by the deployment controller. + format: int64 + type: integer + version: + description: Version the operator version controlling this Platform + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.9.2 + creationTimestamp: null + name: sonataflows.sonataflow.org +spec: + group: sonataflow.org + names: + kind: SonataFlow + listKind: SonataFlowList + plural: sonataflows + shortNames: + - sf + - workflow + - workflows + singular: sonataflow + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.annotations.sonataflow\.org\/profile + name: Profile + type: string + - jsonPath: .metadata.annotations.sonataflow\.org\/version + name: Version + type: string + - jsonPath: .status.endpoint + name: URL + type: string + - jsonPath: .status.conditions[?(@.type=='Running')].status + name: Ready + type: string + - jsonPath: .status.conditions[?(@.type=='Running')].reason + name: Reason + type: string + name: v1alpha08 + schema: + openAPIV3Schema: + description: SonataFlow is the descriptor representation for a workflow application + based on the CNCF Serverless Workflow specification. + 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: SonataFlowSpec defines the desired state of SonataFlow + properties: + flow: + description: "Flow describes the contents of the Workflow definition + following the CNCF Serverless Workflow Specification. The attributes + not part of the flow are defined by the Custom Resource metadata + information, as follows: \n - Id, name, and key are replaced by + the Custom Resource's name. Must follow the Kubernetes naming patterns + (RFC1123). \n - Description can be added in the CR's annotation + field sonataflow.org/description \n - Version is also defined in + the CR's annotation, field sonataflow.org/version \n - SpecVersion + is in the CR's apiVersion, for example v1alpha08 means that it follows + the specification version 0.8." + properties: + annotations: + description: Annotations List of helpful terms describing the + workflows intended purpose, subject areas, or other important + qualities. + items: + type: string + type: array + auth: + description: Auth definitions can be used to define authentication + information that should be applied to resources defined in the + operation property of function definitions. It is not used as + authentication information for the function invocation, but + just to access the resource containing the function invocation + information. + x-kubernetes-preserve-unknown-fields: true + autoRetries: + description: AutoRetries If set to true, actions should automatically + be retried on unchecked errors. Default is false + type: boolean + constants: + additionalProperties: + 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: Constants Workflow constants are used to define static, + and immutable, data which is available to Workflow Expressions. + type: object + dataInputSchema: + description: DataInputSchema URI of the JSON Schema used to validate + the workflow data input + properties: + failOnValidationErrors: + type: boolean + schema: + type: string + required: + - failOnValidationErrors + - schema + type: object + errors: + description: Defines checked errors that can be explicitly handled + during workflow execution. + items: + description: Error declaration for workflow definitions + properties: + code: + description: Code OnError code. Can be used in addition + to the name to help runtimes resolve to technical errors/exceptions. + Should not be defined if error is set to '*'. + type: string + description: + description: OnError description. + type: string + name: + description: Name Domain-specific error name. + type: string + required: + - name + type: object + type: array + events: + items: + description: Event used to define events and their correlations + properties: + correlation: + description: Define event correlation rules for this event. + Only used for consumed events. + items: + description: Correlation define event correlation rules + for an event. Only used for `consumed` events + properties: + contextAttributeName: + description: CloudEvent Extension Context Attribute + name + type: string + contextAttributeValue: + description: CloudEvent Extension Context Attribute + value + type: string + required: + - contextAttributeName + type: object + type: array + dataOnly: + description: If `true`, only the Event payload is accessible + to consuming Workflow states. If `false`, both event payload + and context attributes should be accessible. Defaults + to true. + type: boolean + kind: + default: consumed + description: Defines the CloudEvent as either 'consumed' + or 'produced' by the workflow. Defaults to `consumed`. + enum: + - consumed + - produced + type: string + metadata: + additionalProperties: + type: object + description: Metadata information + type: object + name: + description: Unique event name. + type: string + source: + description: CloudEvent source. + type: string + type: + description: CloudEvent type. + type: string + required: + - name + - type + type: object + type: array + functions: + items: + description: Function ... + properties: + authRef: + description: References an auth definition name to be used + to access to resource defined in the operation parameter. + type: string + metadata: + additionalProperties: + type: object + description: Metadata information + type: object + name: + description: Unique function name + type: string + operation: + description: If type is `rest`, #. + If type is `rpc`, ##. + If type is `expression`, defines the workflow expression. + If the type is `custom`, #. + type: string + type: + default: rest + description: Defines the function type. Is either `custom`, + `rest`, `rpc`, `expression`, `graphql`, `odata` or `asyncapi`. + Default is `rest`. + enum: + - rest + - rpc + - expression + - graphql + - odata + - asyncapi + - custom + type: string + required: + - name + - operation + type: object + type: array + keepActive: + description: If "true", workflow instances is not terminated when + there are no active execution paths. Instance can be terminated + with "terminate end definition" or reaching defined "workflowExecTimeout" + type: boolean + metadata: + description: Metadata custom information shared with the runtime. + x-kubernetes-preserve-unknown-fields: true + retries: + items: + description: Retry ... + properties: + delay: + description: Time delay between retry attempts (ISO 8601 + duration format) + type: string + increment: + description: Static value by which the delay increases during + each attempt (ISO 8601 time format) + type: string + jitter: + description: 'If float type, maximum amount of random time + added or subtracted from the delay between each retry + relative to total delay (between 0 and 1). If string type, + absolute maximum amount of random time added or subtracted + from the delay between each retry (ISO 8601 duration format) + TODO: make iso8601duration compatible this type' + properties: + floatVal: + type: number + strVal: + type: string + type: + description: Type represents the stored type of Float32OrString. + format: int64 + type: integer + type: object + maxAttempts: + anyOf: + - type: integer + - type: string + description: Maximum number of retry attempts. + x-kubernetes-int-or-string: true + maxDelay: + description: Maximum time delay between retry attempts (ISO + 8601 duration format) + type: string + multiplier: + description: Numeric value, if specified the delay between + retries is multiplied by this value. + properties: + floatVal: + type: number + strVal: + type: string + type: + description: Type represents the stored type of Float32OrString. + format: int64 + type: integer + type: object + name: + description: Unique retry strategy name + type: string + required: + - maxAttempts + - name + type: object + type: array + secrets: + description: Secrets allow you to access sensitive information, + such as passwords, OAuth tokens, ssh keys, etc, inside your + Workflow Expressions. + items: + type: string + type: array + start: + description: Workflow start definition. + x-kubernetes-preserve-unknown-fields: true + states: + items: + properties: + callbackState: + description: callbackState executes a function and waits + for callback event that indicates completion of the task. + properties: + action: + description: Defines the action to be executed. + properties: + actionDataFilter: + description: Filter the state data to select only + the data that can be used within function definition + arguments using its fromStateData property. Filter + the action results to select only the result data + that should be added/merged back into the state + data using its results property. Select the part + of state data which the action data results should + be added/merged to using the toStateData property. + properties: + fromStateData: + description: Workflow expression that filters + state data that can be used by the action. + type: string + results: + description: Workflow expression that filters + the actions data results. + type: string + toStateData: + description: Workflow expression that selects + a state data element to which the action results + should be added/merged into. If not specified + denotes the top-level state data element. + type: string + useResults: + description: If set to false, action data results + are not added/merged to state data. In this + case 'results' and 'toStateData' should be + ignored. Default is true. + type: boolean + type: object + condition: + description: Expression, if defined, must evaluate + to true for this action to be performed. If false, + action is disregarded. + type: string + eventRef: + description: References a 'trigger' and 'result' + reusable event definitions. + properties: + contextAttributes: + additionalProperties: + type: object + description: Add additional extension context + attributes to the produced event. + type: object + data: + description: If string type, an expression which + selects parts of the states data output to + become the data (payload) of the event referenced + by triggerEventRef. If object type, a custom + object to become the data (payload) of the + event referenced by triggerEventRef. + type: object + invoke: + default: sync + description: Specifies if the function should + be invoked sync or async. Default is sync. + enum: + - async + - sync + type: string + resultEventRef: + description: Reference to the unique name of + a 'consumed' event definition + type: string + resultEventTimeout: + description: Maximum amount of time (ISO 8601 + format) to wait for the result event. If not + defined it be set to the actionExecutionTimeout + type: string + triggerEventRef: + description: Reference to the unique name of + a 'produced' event definition, + type: string + required: + - resultEventRef + - triggerEventRef + type: object + functionRef: + description: References a reusable function definition. + properties: + arguments: + additionalProperties: + type: object + description: 'Arguments (inputs) to be passed + to the referenced function TODO: validate + it as required if function type is graphql' + type: object + invoke: + default: sync + description: Specifies if the function should + be invoked sync or async. Default is sync. + enum: + - async + - sync + type: string + refName: + description: Name of the referenced function. + type: string + selectionSet: + description: 'Used if function type is graphql. + String containing a valid GraphQL selection + set. TODO: validate it as required if function + type is graphql' + type: string + required: + - refName + type: object + id: + description: Defines Unique action identifier. + type: string + name: + description: Defines Unique action name. + type: string + nonRetryableErrors: + description: List of unique references to defined + workflow errors for which the action should not + be retried. Used only when `autoRetries` is set + to `true` + items: + type: string + type: array + retryRef: + description: References a defined workflow retry + definition. If not defined uses the default runtime + retry definition. + type: string + retryableErrors: + description: List of unique references to defined + workflow errors for which the action should be + retried. Used only when `autoRetries` is set to + `false` + items: + type: string + type: array + sleep: + description: Defines time period workflow execution + should sleep before / after function execution. + properties: + after: + description: Defines amount of time (ISO 8601 + duration format) to sleep after function/subflow + invocation. Does not apply if 'eventRef' is + defined. + type: string + before: + description: Defines amount of time (ISO 8601 + duration format) to sleep before function/subflow + invocation. Does not apply if 'eventRef' is + defined. + type: string + type: object + subFlowRef: + description: References a workflow to be invoked. + properties: + invoke: + default: sync + description: Specifies if the subflow should + be invoked sync or async. Defaults to sync. + enum: + - async + - sync + type: string + onParentComplete: + default: terminate + description: onParentComplete specifies how + subflow execution should behave when parent + workflow completes if invoke is 'async'. Defaults + to terminate. + enum: + - terminate + - continue + type: string + version: + description: Sub-workflow version + type: string + workflowId: + description: Sub-workflow unique id + type: string + required: + - workflowId + type: object + type: object + eventDataFilter: + description: Event data filter definition. + properties: + data: + description: Workflow expression that filters of + the event data (payload). + type: string + toStateData: + description: Workflow expression that selects a + state data element to which the action results + should be added/merged into. If not specified + denotes the top-level state data element + type: string + useData: + description: If set to false, event payload is not + added/merged to state data. In this case 'data' + and 'toStateData' should be ignored. Default is + true. + type: boolean + type: object + eventRef: + description: References a unique callback event name + in the defined workflow events. + type: string + timeouts: + description: Time period to wait for incoming events + (ISO 8601 format) + properties: + actionExecTimeout: + description: Default single actions definition execution + timeout (ISO 8601 duration format) + type: string + eventTimeout: + description: Default timeout for consuming defined + events (ISO 8601 duration format) + type: string + stateExecTimeout: + description: Default workflow state execution timeout + (ISO 8601 duration format) + properties: + single: + description: Single state execution timeout, + not including retries (ISO 8601 duration format) + type: string + total: + description: Total state execution timeout, + including retries (ISO 8601 duration format) + type: string + required: + - total + type: object + type: object + required: + - action + - eventRef + type: object + compensatedBy: + description: Unique Name of a workflow state which is responsible + for compensation of this state. + type: string + delayState: + description: delayState Causes the workflow execution to + delay for a specified duration. + properties: + timeDelay: + description: Amount of time (ISO 8601 format) to delay + type: string + required: + - timeDelay + type: object + end: + description: State end definition. + x-kubernetes-preserve-unknown-fields: true + eventState: + description: event states await one or more events and perform + actions when they are received. If defined as the workflow + starting state, the event state definition controls when + the workflow instances should be created. + properties: + exclusive: + default: true + description: If true consuming one of the defined events + causes its associated actions to be performed. If + false all the defined events must be consumed in order + for actions to be performed. Defaults to true. + type: boolean + onEvents: + description: Define the events to be consumed and optional + actions to be performed. + items: + description: OnEvents define which actions are be + performed for the one or more events. + properties: + actionMode: + default: sequential + description: Should actions be performed sequentially + or in parallel. Default is sequential. + enum: + - sequential + - parallel + type: string + actions: + description: Actions to be performed if expression + matches + items: + description: Action specify invocations of services + or other workflows during workflow execution. + properties: + actionDataFilter: + description: Filter the state data to select + only the data that can be used within + function definition arguments using its + fromStateData property. Filter the action + results to select only the result data + that should be added/merged back into + the state data using its results property. + Select the part of state data which the + action data results should be added/merged + to using the toStateData property. + properties: + fromStateData: + description: Workflow expression that + filters state data that can be used + by the action. + type: string + results: + description: Workflow expression that + filters the actions data results. + type: string + toStateData: + description: Workflow expression that + selects a state data element to which + the action results should be added/merged + into. If not specified denotes the + top-level state data element. + type: string + useResults: + description: If set to false, action + data results are not added/merged + to state data. In this case 'results' + and 'toStateData' should be ignored. + Default is true. + type: boolean + type: object + condition: + description: Expression, if defined, must + evaluate to true for this action to be + performed. If false, action is disregarded. + type: string + eventRef: + description: References a 'trigger' and + 'result' reusable event definitions. + properties: + contextAttributes: + additionalProperties: + type: object + description: Add additional extension + context attributes to the produced + event. + type: object + data: + description: If string type, an expression + which selects parts of the states + data output to become the data (payload) + of the event referenced by triggerEventRef. + If object type, a custom object to + become the data (payload) of the event + referenced by triggerEventRef. + type: object + invoke: + default: sync + description: Specifies if the function + should be invoked sync or async. Default + is sync. + enum: + - async + - sync + type: string + resultEventRef: + description: Reference to the unique + name of a 'consumed' event definition + type: string + resultEventTimeout: + description: Maximum amount of time + (ISO 8601 format) to wait for the + result event. If not defined it be + set to the actionExecutionTimeout + type: string + triggerEventRef: + description: Reference to the unique + name of a 'produced' event definition, + type: string + required: + - resultEventRef + - triggerEventRef + type: object + functionRef: + description: References a reusable function + definition. + properties: + arguments: + additionalProperties: + type: object + description: 'Arguments (inputs) to + be passed to the referenced function + TODO: validate it as required if function + type is graphql' + type: object + invoke: + default: sync + description: Specifies if the function + should be invoked sync or async. Default + is sync. + enum: + - async + - sync + type: string + refName: + description: Name of the referenced + function. + type: string + selectionSet: + description: 'Used if function type + is graphql. String containing a valid + GraphQL selection set. TODO: validate + it as required if function type is + graphql' + type: string + required: + - refName + type: object + id: + description: Defines Unique action identifier. + type: string + name: + description: Defines Unique action name. + type: string + nonRetryableErrors: + description: List of unique references to + defined workflow errors for which the + action should not be retried. Used only + when `autoRetries` is set to `true` + items: + type: string + type: array + retryRef: + description: References a defined workflow + retry definition. If not defined uses + the default runtime retry definition. + type: string + retryableErrors: + description: List of unique references to + defined workflow errors for which the + action should be retried. Used only when + `autoRetries` is set to `false` + items: + type: string + type: array + sleep: + description: Defines time period workflow + execution should sleep before / after + function execution. + properties: + after: + description: Defines amount of time + (ISO 8601 duration format) to sleep + after function/subflow invocation. + Does not apply if 'eventRef' is defined. + type: string + before: + description: Defines amount of time + (ISO 8601 duration format) to sleep + before function/subflow invocation. + Does not apply if 'eventRef' is defined. + type: string + type: object + subFlowRef: + description: References a workflow to be + invoked. + properties: + invoke: + default: sync + description: Specifies if the subflow + should be invoked sync or async. Defaults + to sync. + enum: + - async + - sync + type: string + onParentComplete: + default: terminate + description: onParentComplete specifies + how subflow execution should behave + when parent workflow completes if + invoke is 'async'. Defaults to terminate. + enum: + - terminate + - continue + type: string + version: + description: Sub-workflow version + type: string + workflowId: + description: Sub-workflow unique id + type: string + required: + - workflowId + type: object + type: object + type: array + eventDataFilter: + description: eventDataFilter defines the callback + event data filter definition + properties: + data: + description: Workflow expression that filters + of the event data (payload). + type: string + toStateData: + description: Workflow expression that selects + a state data element to which the action + results should be added/merged into. If + not specified denotes the top-level state + data element + type: string + useData: + description: If set to false, event payload + is not added/merged to state data. In this + case 'data' and 'toStateData' should be + ignored. Default is true. + type: boolean + type: object + eventRefs: + description: References one or more unique event + names in the defined workflow events. + items: + type: string + minItems: 1 + type: array + required: + - eventRefs + type: object + minItems: 1 + type: array + timeouts: + description: State specific timeouts. + properties: + actionExecTimeout: + description: Default single actions definition execution + timeout (ISO 8601 duration format) + type: string + eventTimeout: + description: Default timeout for consuming defined + events (ISO 8601 duration format) + type: string + stateExecTimeout: + description: Default workflow state execution timeout + (ISO 8601 duration format) + properties: + single: + description: Single state execution timeout, + not including retries (ISO 8601 duration format) + type: string + total: + description: Total state execution timeout, + including retries (ISO 8601 duration format) + type: string + required: + - total + type: object + type: object + required: + - onEvents + type: object + forEachState: + description: forEachState used to execute actions for each + element of a data set. + properties: + actions: + description: Actions to be executed for each of the + elements of inputCollection. + items: + description: Action specify invocations of services + or other workflows during workflow execution. + properties: + actionDataFilter: + description: Filter the state data to select only + the data that can be used within function definition + arguments using its fromStateData property. + Filter the action results to select only the + result data that should be added/merged back + into the state data using its results property. + Select the part of state data which the action + data results should be added/merged to using + the toStateData property. + properties: + fromStateData: + description: Workflow expression that filters + state data that can be used by the action. + type: string + results: + description: Workflow expression that filters + the actions data results. + type: string + toStateData: + description: Workflow expression that selects + a state data element to which the action + results should be added/merged into. If + not specified denotes the top-level state + data element. + type: string + useResults: + description: If set to false, action data + results are not added/merged to state data. + In this case 'results' and 'toStateData' + should be ignored. Default is true. + type: boolean + type: object + condition: + description: Expression, if defined, must evaluate + to true for this action to be performed. If + false, action is disregarded. + type: string + eventRef: + description: References a 'trigger' and 'result' + reusable event definitions. + properties: + contextAttributes: + additionalProperties: + type: object + description: Add additional extension context + attributes to the produced event. + type: object + data: + description: If string type, an expression + which selects parts of the states data output + to become the data (payload) of the event + referenced by triggerEventRef. If object + type, a custom object to become the data + (payload) of the event referenced by triggerEventRef. + type: object + invoke: + default: sync + description: Specifies if the function should + be invoked sync or async. Default is sync. + enum: + - async + - sync + type: string + resultEventRef: + description: Reference to the unique name + of a 'consumed' event definition + type: string + resultEventTimeout: + description: Maximum amount of time (ISO 8601 + format) to wait for the result event. If + not defined it be set to the actionExecutionTimeout + type: string + triggerEventRef: + description: Reference to the unique name + of a 'produced' event definition, + type: string + required: + - resultEventRef + - triggerEventRef + type: object + functionRef: + description: References a reusable function definition. + properties: + arguments: + additionalProperties: + type: object + description: 'Arguments (inputs) to be passed + to the referenced function TODO: validate + it as required if function type is graphql' + type: object + invoke: + default: sync + description: Specifies if the function should + be invoked sync or async. Default is sync. + enum: + - async + - sync + type: string + refName: + description: Name of the referenced function. + type: string + selectionSet: + description: 'Used if function type is graphql. + String containing a valid GraphQL selection + set. TODO: validate it as required if function + type is graphql' + type: string + required: + - refName + type: object + id: + description: Defines Unique action identifier. + type: string + name: + description: Defines Unique action name. + type: string + nonRetryableErrors: + description: List of unique references to defined + workflow errors for which the action should + not be retried. Used only when `autoRetries` + is set to `true` + items: + type: string + type: array + retryRef: + description: References a defined workflow retry + definition. If not defined uses the default + runtime retry definition. + type: string + retryableErrors: + description: List of unique references to defined + workflow errors for which the action should + be retried. Used only when `autoRetries` is + set to `false` + items: + type: string + type: array + sleep: + description: Defines time period workflow execution + should sleep before / after function execution. + properties: + after: + description: Defines amount of time (ISO 8601 + duration format) to sleep after function/subflow + invocation. Does not apply if 'eventRef' + is defined. + type: string + before: + description: Defines amount of time (ISO 8601 + duration format) to sleep before function/subflow + invocation. Does not apply if 'eventRef' + is defined. + type: string + type: object + subFlowRef: + description: References a workflow to be invoked. + properties: + invoke: + default: sync + description: Specifies if the subflow should + be invoked sync or async. Defaults to sync. + enum: + - async + - sync + type: string + onParentComplete: + default: terminate + description: onParentComplete specifies how + subflow execution should behave when parent + workflow completes if invoke is 'async'. + Defaults to terminate. + enum: + - terminate + - continue + type: string + version: + description: Sub-workflow version + type: string + workflowId: + description: Sub-workflow unique id + type: string + required: + - workflowId + type: object + type: object + minItems: 0 + type: array + batchSize: + anyOf: + - type: integer + - type: string + description: Specifies how many iterations may run in + parallel at the same time. Used if mode property is + set to parallel (default). If not specified, its value + should be the size of the inputCollection. + x-kubernetes-int-or-string: true + inputCollection: + description: Workflow expression selecting an array + element of the states' data. + type: string + iterationParam: + description: Name of the iteration parameter that can + be referenced in actions/workflow. For each parallel + iteration, this param should contain a unique element + of the inputCollection array. + type: string + mode: + default: parallel + description: Specifies how iterations are to be performed + (sequential or in parallel), defaults to parallel. + enum: + - sequential + - parallel + type: string + outputCollection: + description: Workflow expression specifying an array + element of the states data to add the results of each + iteration. + type: string + timeouts: + description: State specific timeout. + properties: + actionExecTimeout: + description: Default single actions definition execution + timeout (ISO 8601 duration format) + type: string + stateExecTimeout: + description: Default workflow state execution timeout + (ISO 8601 duration format) + properties: + single: + description: Single state execution timeout, + not including retries (ISO 8601 duration format) + type: string + total: + description: Total state execution timeout, + including retries (ISO 8601 duration format) + type: string + required: + - total + type: object + type: object + required: + - inputCollection + type: object + id: + description: Unique State id. + type: string + injectState: + description: injectState used to inject static data into + state data input. + properties: + data: + additionalProperties: + type: object + description: JSON object which can be set as state's + data input and can be manipulated via filter + minProperties: 1 + type: object + timeouts: + description: State specific timeouts + properties: + stateExecTimeout: + description: Default workflow state execution timeout + (ISO 8601 duration format) + properties: + single: + description: Single state execution timeout, + not including retries (ISO 8601 duration format) + type: string + total: + description: Total state execution timeout, + including retries (ISO 8601 duration format) + type: string + required: + - total + type: object + type: object + required: + - data + type: object + metadata: + additionalProperties: + type: object + description: Metadata information. + type: object + name: + description: State name. + type: string + onErrors: + description: States error handling and retries definitions. + items: + description: OnError ... + properties: + end: + description: End workflow execution in case of this + error. If retryRef is defined, this ends workflow + only if retries were unsuccessful. + x-kubernetes-preserve-unknown-fields: true + errorRef: + description: ErrorRef Reference to a unique workflow + error definition. Used of errorRefs is not used + type: string + errorRefs: + description: ErrorRefs References one or more workflow + error definitions. Used if errorRef is not used + items: + type: string + type: array + transition: + description: Transition to next state to handle the + error. If retryRef is defined, this transition is + taken only if retries were unsuccessful. + x-kubernetes-preserve-unknown-fields: true + type: object + type: array + operationState: + description: operationState defines a set of actions to + be performed in sequence or in parallel. + properties: + actionMode: + default: sequential + description: Specifies whether actions are performed + in sequence or in parallel, defaults to sequential. + enum: + - sequential + - parallel + type: string + actions: + description: Actions to be performed + items: + description: Action specify invocations of services + or other workflows during workflow execution. + properties: + actionDataFilter: + description: Filter the state data to select only + the data that can be used within function definition + arguments using its fromStateData property. + Filter the action results to select only the + result data that should be added/merged back + into the state data using its results property. + Select the part of state data which the action + data results should be added/merged to using + the toStateData property. + properties: + fromStateData: + description: Workflow expression that filters + state data that can be used by the action. + type: string + results: + description: Workflow expression that filters + the actions data results. + type: string + toStateData: + description: Workflow expression that selects + a state data element to which the action + results should be added/merged into. If + not specified denotes the top-level state + data element. + type: string + useResults: + description: If set to false, action data + results are not added/merged to state data. + In this case 'results' and 'toStateData' + should be ignored. Default is true. + type: boolean + type: object + condition: + description: Expression, if defined, must evaluate + to true for this action to be performed. If + false, action is disregarded. + type: string + eventRef: + description: References a 'trigger' and 'result' + reusable event definitions. + properties: + contextAttributes: + additionalProperties: + type: object + description: Add additional extension context + attributes to the produced event. + type: object + data: + description: If string type, an expression + which selects parts of the states data output + to become the data (payload) of the event + referenced by triggerEventRef. If object + type, a custom object to become the data + (payload) of the event referenced by triggerEventRef. + type: object + invoke: + default: sync + description: Specifies if the function should + be invoked sync or async. Default is sync. + enum: + - async + - sync + type: string + resultEventRef: + description: Reference to the unique name + of a 'consumed' event definition + type: string + resultEventTimeout: + description: Maximum amount of time (ISO 8601 + format) to wait for the result event. If + not defined it be set to the actionExecutionTimeout + type: string + triggerEventRef: + description: Reference to the unique name + of a 'produced' event definition, + type: string + required: + - resultEventRef + - triggerEventRef + type: object + functionRef: + description: References a reusable function definition. + properties: + arguments: + additionalProperties: + type: object + description: 'Arguments (inputs) to be passed + to the referenced function TODO: validate + it as required if function type is graphql' + type: object + invoke: + default: sync + description: Specifies if the function should + be invoked sync or async. Default is sync. + enum: + - async + - sync + type: string + refName: + description: Name of the referenced function. + type: string + selectionSet: + description: 'Used if function type is graphql. + String containing a valid GraphQL selection + set. TODO: validate it as required if function + type is graphql' + type: string + required: + - refName + type: object + id: + description: Defines Unique action identifier. + type: string + name: + description: Defines Unique action name. + type: string + nonRetryableErrors: + description: List of unique references to defined + workflow errors for which the action should + not be retried. Used only when `autoRetries` + is set to `true` + items: + type: string + type: array + retryRef: + description: References a defined workflow retry + definition. If not defined uses the default + runtime retry definition. + type: string + retryableErrors: + description: List of unique references to defined + workflow errors for which the action should + be retried. Used only when `autoRetries` is + set to `false` + items: + type: string + type: array + sleep: + description: Defines time period workflow execution + should sleep before / after function execution. + properties: + after: + description: Defines amount of time (ISO 8601 + duration format) to sleep after function/subflow + invocation. Does not apply if 'eventRef' + is defined. + type: string + before: + description: Defines amount of time (ISO 8601 + duration format) to sleep before function/subflow + invocation. Does not apply if 'eventRef' + is defined. + type: string + type: object + subFlowRef: + description: References a workflow to be invoked. + properties: + invoke: + default: sync + description: Specifies if the subflow should + be invoked sync or async. Defaults to sync. + enum: + - async + - sync + type: string + onParentComplete: + default: terminate + description: onParentComplete specifies how + subflow execution should behave when parent + workflow completes if invoke is 'async'. + Defaults to terminate. + enum: + - terminate + - continue + type: string + version: + description: Sub-workflow version + type: string + workflowId: + description: Sub-workflow unique id + type: string + required: + - workflowId + type: object + type: object + minItems: 0 + type: array + timeouts: + description: State specific timeouts + properties: + actionExecTimeout: + description: Default single actions definition execution + timeout (ISO 8601 duration format) + type: string + stateExecTimeout: + description: Defines workflow state execution timeout. + properties: + single: + description: Single state execution timeout, + not including retries (ISO 8601 duration format) + type: string + total: + description: Total state execution timeout, + including retries (ISO 8601 duration format) + type: string + required: + - total + type: object + type: object + required: + - actions + type: object + parallelState: + description: parallelState Consists of a number of states + that are executed in parallel. + properties: + branches: + description: List of branches for this parallel state. + items: + description: Branch Definition + properties: + actions: + description: Actions to be executed in this branch + items: + description: Action specify invocations of services + or other workflows during workflow execution. + properties: + actionDataFilter: + description: Filter the state data to select + only the data that can be used within + function definition arguments using its + fromStateData property. Filter the action + results to select only the result data + that should be added/merged back into + the state data using its results property. + Select the part of state data which the + action data results should be added/merged + to using the toStateData property. + properties: + fromStateData: + description: Workflow expression that + filters state data that can be used + by the action. + type: string + results: + description: Workflow expression that + filters the actions data results. + type: string + toStateData: + description: Workflow expression that + selects a state data element to which + the action results should be added/merged + into. If not specified denotes the + top-level state data element. + type: string + useResults: + description: If set to false, action + data results are not added/merged + to state data. In this case 'results' + and 'toStateData' should be ignored. + Default is true. + type: boolean + type: object + condition: + description: Expression, if defined, must + evaluate to true for this action to be + performed. If false, action is disregarded. + type: string + eventRef: + description: References a 'trigger' and + 'result' reusable event definitions. + properties: + contextAttributes: + additionalProperties: + type: object + description: Add additional extension + context attributes to the produced + event. + type: object + data: + description: If string type, an expression + which selects parts of the states + data output to become the data (payload) + of the event referenced by triggerEventRef. + If object type, a custom object to + become the data (payload) of the event + referenced by triggerEventRef. + type: object + invoke: + default: sync + description: Specifies if the function + should be invoked sync or async. Default + is sync. + enum: + - async + - sync + type: string + resultEventRef: + description: Reference to the unique + name of a 'consumed' event definition + type: string + resultEventTimeout: + description: Maximum amount of time + (ISO 8601 format) to wait for the + result event. If not defined it be + set to the actionExecutionTimeout + type: string + triggerEventRef: + description: Reference to the unique + name of a 'produced' event definition, + type: string + required: + - resultEventRef + - triggerEventRef + type: object + functionRef: + description: References a reusable function + definition. + properties: + arguments: + additionalProperties: + type: object + description: 'Arguments (inputs) to + be passed to the referenced function + TODO: validate it as required if function + type is graphql' + type: object + invoke: + default: sync + description: Specifies if the function + should be invoked sync or async. Default + is sync. + enum: + - async + - sync + type: string + refName: + description: Name of the referenced + function. + type: string + selectionSet: + description: 'Used if function type + is graphql. String containing a valid + GraphQL selection set. TODO: validate + it as required if function type is + graphql' + type: string + required: + - refName + type: object + id: + description: Defines Unique action identifier. + type: string + name: + description: Defines Unique action name. + type: string + nonRetryableErrors: + description: List of unique references to + defined workflow errors for which the + action should not be retried. Used only + when `autoRetries` is set to `true` + items: + type: string + type: array + retryRef: + description: References a defined workflow + retry definition. If not defined uses + the default runtime retry definition. + type: string + retryableErrors: + description: List of unique references to + defined workflow errors for which the + action should be retried. Used only when + `autoRetries` is set to `false` + items: + type: string + type: array + sleep: + description: Defines time period workflow + execution should sleep before / after + function execution. + properties: + after: + description: Defines amount of time + (ISO 8601 duration format) to sleep + after function/subflow invocation. + Does not apply if 'eventRef' is defined. + type: string + before: + description: Defines amount of time + (ISO 8601 duration format) to sleep + before function/subflow invocation. + Does not apply if 'eventRef' is defined. + type: string + type: object + subFlowRef: + description: References a workflow to be + invoked. + properties: + invoke: + default: sync + description: Specifies if the subflow + should be invoked sync or async. Defaults + to sync. + enum: + - async + - sync + type: string + onParentComplete: + default: terminate + description: onParentComplete specifies + how subflow execution should behave + when parent workflow completes if + invoke is 'async'. Defaults to terminate. + enum: + - terminate + - continue + type: string + version: + description: Sub-workflow version + type: string + workflowId: + description: Sub-workflow unique id + type: string + required: + - workflowId + type: object + type: object + minItems: 1 + type: array + name: + description: Branch name + type: string + timeouts: + description: Branch specific timeout settings + properties: + actionExecTimeout: + description: Single actions definition execution + timeout duration (ISO 8601 duration format) + type: string + branchExecTimeout: + description: Single branch execution timeout + duration (ISO 8601 duration format) + type: string + type: object + required: + - actions + - name + type: object + minItems: 1 + type: array + completionType: + default: allOf + description: Option types on how to complete branch + execution. Defaults to `allOf`. + enum: + - allOf + - atLeast + type: string + numCompleted: + anyOf: + - type: integer + - type: string + description: 'Used when branchCompletionType is set + to atLeast to specify the least number of branches + that must complete in order for the state to transition/end. + TODO: change this field to unmarshal result as int' + x-kubernetes-int-or-string: true + timeouts: + description: State specific timeouts + properties: + branchExecTimeout: + description: Default single branch execution timeout + (ISO 8601 duration format) + type: string + stateExecTimeout: + description: Default workflow state execution timeout + (ISO 8601 duration format) + properties: + single: + description: Single state execution timeout, + not including retries (ISO 8601 duration format) + type: string + total: + description: Total state execution timeout, + including retries (ISO 8601 duration format) + type: string + required: + - total + type: object + type: object + required: + - branches + type: object + sleepState: + description: sleepState suspends workflow execution for + a given time duration. + properties: + duration: + description: Duration (ISO 8601 duration format) to + sleep + type: string + timeouts: + description: Timeouts State specific timeouts + properties: + stateExecTimeout: + description: Default workflow state execution timeout + (ISO 8601 duration format) + properties: + single: + description: Single state execution timeout, + not including retries (ISO 8601 duration format) + type: string + total: + description: Total state execution timeout, + including retries (ISO 8601 duration format) + type: string + required: + - total + type: object + type: object + required: + - duration + type: object + stateDataFilter: + description: State data filter. + properties: + input: + description: Workflow expression to filter the state + data input + type: string + output: + description: Workflow expression that filters the state + data output + type: string + type: object + switchState: + description: 'switchState is workflow''s gateways: direct + transitions onf a workflow based on certain conditions.' + properties: + dataConditions: + description: Defines conditions evaluated against data + items: + description: DataCondition specify a data-based condition + statement which causes a transition to another workflow + state if evaluated to true. + properties: + condition: + description: Workflow expression evaluated against + state data. Must evaluate to true or false. + type: string + end: + description: TODO End or Transition needs to be + exclusive tag, one or another should be set. + Explicit transition to end + properties: + compensate: + description: If set to true, triggers workflow + compensation before workflow execution completes. + Default is false. + type: boolean + continueAs: + description: Defines that current workflow + execution should stop, and execution should + continue as a new workflow instance of the + provided id + properties: + data: + description: If string type, an expression + which selects parts of the states data + output to become the workflow data input + of continued execution. If object type, + a custom object to become the workflow + data input of the continued execution + type: object + version: + description: Version of the workflow to + continue execution as. + type: string + workflowExecTimeout: + description: WorkflowExecTimeout Workflow + execution timeout to be used by the + workflow continuing execution. Overwrites + any specific settings set by that workflow + properties: + duration: + default: unlimited + description: Workflow execution timeout + duration (ISO 8601 duration format). + If not specified should be 'unlimited'. + type: string + interrupt: + description: If false, workflow instance + is allowed to finish current execution. + If true, current workflow execution + is stopped immediately. Default + is false. + type: boolean + runBefore: + description: Name of a workflow state + to be executed before workflow instance + is terminated. + type: string + required: + - duration + type: object + workflowId: + description: Unique id of the workflow + to continue execution as. + type: string + required: + - workflowId + type: object + produceEvents: + description: Array of producedEvent definitions. + Defines events that should be produced. + items: + description: ProduceEvent Defines the event + (CloudEvent format) to be produced when + workflow execution completes or during + a workflow transitions. The eventRef property + must match the name of one of the defined + produced events in the events definition. + properties: + contextAttributes: + additionalProperties: + type: string + description: Add additional event extension + context attributes. + type: object + data: + description: If String, expression which + selects parts of the states data output + to become the data of the produced + event. If object a custom object to + become the data of produced event. + type: object + eventRef: + description: Reference to a defined + unique event name in the events definition + type: string + required: + - eventRef + type: object + type: array + terminate: + description: If true, completes all execution + flows in the given workflow instance. + type: boolean + type: object + metadata: + additionalProperties: + type: object + description: Metadata information. + type: object + name: + description: Data condition name. + type: string + transition: + description: Workflow transition if condition + is evaluated to true + properties: + compensate: + default: false + description: If set to true, triggers workflow + compensation before this transition is taken. + Default is false. + type: boolean + nextState: + description: Name of the state to transition + to next. + type: string + produceEvents: + description: Array of producedEvent definitions. + Events to be produced before the transition + takes place. + items: + description: ProduceEvent Defines the event + (CloudEvent format) to be produced when + workflow execution completes or during + a workflow transitions. The eventRef property + must match the name of one of the defined + produced events in the events definition. + properties: + contextAttributes: + additionalProperties: + type: string + description: Add additional event extension + context attributes. + type: object + data: + description: If String, expression which + selects parts of the states data output + to become the data of the produced + event. If object a custom object to + become the data of produced event. + type: object + eventRef: + description: Reference to a defined + unique event name in the events definition + type: string + required: + - eventRef + type: object + type: array + required: + - nextState + type: object + required: + - condition + - end + type: object + type: array + defaultCondition: + description: Default transition of the workflow if there + is no matching data conditions. Can include a transition + or end definition. + properties: + end: + description: If this state an end state + x-kubernetes-preserve-unknown-fields: true + transition: + description: Serverless workflow states can have + one or more incoming and outgoing transitions + (from/to other states). Each state can define + a transition definition that is used to determine + which state to transition to next. + x-kubernetes-preserve-unknown-fields: true + type: object + eventConditions: + description: Defines conditions evaluated against events. + items: + description: EventCondition specify events which the + switch state must wait for. + properties: + end: + description: TODO End or Transition needs to be + exclusive tag, one or another should be set. + Explicit transition to end + x-kubernetes-preserve-unknown-fields: true + eventDataFilter: + description: Event data filter definition. + properties: + data: + description: Workflow expression that filters + of the event data (payload). + type: string + toStateData: + description: Workflow expression that selects + a state data element to which the action + results should be added/merged into. If + not specified denotes the top-level state + data element + type: string + useData: + description: If set to false, event payload + is not added/merged to state data. In this + case 'data' and 'toStateData' should be + ignored. Default is true. + type: boolean + type: object + eventRef: + description: References a unique event name in + the defined workflow events. + type: string + metadata: + description: Metadata information. + x-kubernetes-preserve-unknown-fields: true + name: + description: Event condition name. + type: string + transition: + description: Workflow transition if condition + is evaluated to true + x-kubernetes-preserve-unknown-fields: true + required: + - eventRef + type: object + type: array + timeouts: + description: SwitchState specific timeouts + properties: + eventTimeout: + description: 'Specify the expire value to transitions + to defaultCondition. When event-based conditions + do not arrive. NOTE: this is only available for + EventConditions' + type: string + stateExecTimeout: + description: Default workflow state execution timeout + (ISO 8601 duration format) + properties: + single: + description: Single state execution timeout, + not including retries (ISO 8601 duration format) + type: string + total: + description: Total state execution timeout, + including retries (ISO 8601 duration format) + type: string + required: + - total + type: object + type: object + required: + - defaultCondition + type: object + transition: + description: Next transition of the workflow after the time + delay. + x-kubernetes-preserve-unknown-fields: true + type: + description: stateType can be any of delay, callback, event, + foreach, inject, operation, parallel, sleep, switch + enum: + - delay + - callback + - event + - foreach + - inject + - operation + - parallel + - sleep + - switch + type: string + usedForCompensation: + description: If true, this state is used to compensate another + state. Default is false. + type: boolean + required: + - name + - type + type: object + minItems: 1 + type: array + x-kubernetes-preserve-unknown-fields: true + timeouts: + description: Defines the workflow default timeout settings. + properties: + actionExecTimeout: + description: ActionExecTimeout Single actions definition execution + timeout duration (ISO 8601 duration format). + type: string + branchExecTimeout: + description: BranchExecTimeout Single branch execution timeout + duration (ISO 8601 duration format). + type: string + eventTimeout: + description: EventTimeout Timeout duration to wait for consuming + defined events (ISO 8601 duration format). + type: string + stateExecTimeout: + description: StateExecTimeout Total state execution timeout + (including retries) (ISO 8601 duration format). + properties: + single: + description: Single state execution timeout, not including + retries (ISO 8601 duration format) + type: string + total: + description: Total state execution timeout, including + retries (ISO 8601 duration format) + type: string + required: + - total + type: object + workflowExecTimeout: + description: WorkflowExecTimeout Workflow execution timeout + duration (ISO 8601 duration format). If not specified should + be 'unlimited'. + properties: + duration: + default: unlimited + description: Workflow execution timeout duration (ISO + 8601 duration format). If not specified should be 'unlimited'. + type: string + interrupt: + description: If false, workflow instance is allowed to + finish current execution. If true, current workflow + execution is stopped immediately. Default is false. + type: boolean + runBefore: + description: Name of a workflow state to be executed before + workflow instance is terminated. + type: string + required: + - duration + type: object + type: object + required: + - states + type: object + resources: + description: Resources workflow resources that are linked to this + workflow definition. For example, a collection of OpenAPI specification + files. + properties: + configMaps: + items: + description: ConfigMapWorkflowResource ConfigMap local reference + holding one or more workflow resources, such as OpenAPI files + that will be mounted in the workflow application. + properties: + configMap: + description: ConfigMap the given configMap name in the same + workflow context to find the resource + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + x-kubernetes-map-type: atomic + workflowPath: + description: WorkflowPath path relative to the workflow + application root file system within the pod (//src/main/resources). Starting trailing slashes will + be removed. + type: string + required: + - configMap + type: object + type: array + type: object + required: + - flow + type: object + status: + description: SonataFlowStatus defines the observed state of SonataFlow + properties: + address: + description: Address is used as a part of Addressable interface (status.address.url) + for knative + properties: + CACerts: + description: CACerts is the Certification Authority (CA) certificates + in PEM format according to https://www.rfc-editor.org/rfc/rfc7468. + type: string + name: + description: Name is the name of the address. + type: string + url: + type: string + type: object + conditions: + description: The latest available observations of a resource's current + state. + items: + description: Condition describes the common structure for conditions + in our types + properties: + lastUpdateTime: + description: The last time this condition was updated. + format: date-time + type: string + message: + description: A human-readable message indicating details about + the transition. + type: string + reason: + description: The reason for the condition's last transition. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: Type condition for the given object + type: string + required: + - status + - type + type: object + type: array + endpoint: + description: Endpoint is an externally accessible URL of the workflow + type: string + lastTimeRecoverAttempt: + format: date-time + type: string + observedGeneration: + description: The generation observed by the deployment controller. + format: int64 + type: integer + recoverFailureAttempts: + description: keeps track of how many failure recovers a given workflow + had so far + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: sonataflow-operator-controller-manager + namespace: sonataflow-operator-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: sonataflow-operator-leader-election-role + namespace: sonataflow-operator-system +rules: +- apiGroups: + - "" + resources: + - configmaps + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - "" + resources: + - events + verbs: + - create + - patch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: sonataflow-operator-builder-manager-role +rules: +- apiGroups: + - "" + resources: + - configmaps + - pods + - pods/exec + - services + - services/finalizers + - namespaces + - serviceaccounts + - persistentvolumeclaims + - secrets + - events + - deployments + - nodes + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch +- apiGroups: + - apps + resources: + - configmaps + - pods + - pods/exec + - services + - services/finalizers + - namespaces + - serviceaccounts + - persistentvolumeclaims + - secrets + - events + - deployments + - nodes + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch +- apiGroups: + - rbac.authorization.k8s.io + resources: + - roles + - rolebindings + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: sonataflow-operator-leases +rules: +- apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + creationTimestamp: null + name: sonataflow-operator-manager-role +rules: +- apiGroups: + - sonataflow.org + resources: + - sonataflowbuilds + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - sonataflow.org + resources: + - sonataflowbuilds/finalizers + verbs: + - update +- apiGroups: + - sonataflow.org + resources: + - sonataflowbuilds/status + verbs: + - get + - patch + - update +- apiGroups: + - sonataflow.org + resources: + - sonataflowplatforms + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - sonataflow.org + resources: + - sonataflowplatforms/finalizers + verbs: + - update +- apiGroups: + - sonataflow.org + resources: + - sonataflowplatforms/status + verbs: + - get + - patch + - update +- apiGroups: + - sonataflow.org + resources: + - sonataflows + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - sonataflow.org + resources: + - sonataflows/finalizers + verbs: + - update +- apiGroups: + - sonataflow.org + resources: + - sonataflows/status + verbs: + - get + - patch + - update +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: sonataflow-operator-metrics-reader +rules: +- nonResourceURLs: + - /metrics + verbs: + - get +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: sonataflow-operator-openshift-manager-role +rules: +- apiGroups: + - route.openshift.io + resources: + - route + - routes + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch +- apiGroups: + - route.openshift.io + resources: + - route/finalizers + - routes/finalizers + verbs: + - get + - list + - create + - update + - delete + - deletecollection + - patch + - watch +- apiGroups: + - image.openshift.io + resources: + - imagestreams + - imagestreamtags + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch +- apiGroups: + - image.openshift.io + resources: + - imagestreams/finalizers + - imagestreamtags/finalizers + verbs: + - get + - list + - create + - update + - delete + - deletecollection + - patch + - watch +- apiGroups: + - build.openshift.io + resources: + - buildconfigs + - builds + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch +- apiGroups: + - build.openshift.io + resources: + - buildconfigs/finalizers + - builds/finalizers + verbs: + - get + - list + - create + - update + - delete + - deletecollection + - patch + - watch +- apiGroups: + - build.openshift.io + resources: + - buildconfigs/instantiatebinary + verbs: + - create +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: sonataflow-operator-proxy-role +rules: +- apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create +- apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: sonataflow-operator-leader-election-rolebinding + namespace: sonataflow-operator-system +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: sonataflow-operator-leader-election-role +subjects: +- kind: ServiceAccount + name: sonataflow-operator-controller-manager + namespace: sonataflow-operator-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: sonataflow-operator-builder-manager-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: sonataflow-operator-builder-manager-role +subjects: +- kind: ServiceAccount + name: sonataflow-operator-controller-manager + namespace: sonataflow-operator-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: sonataflow-operator-leases-binding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: sonataflow-operator-leases +subjects: +- kind: ServiceAccount + name: sonataflow-operator-controller-manager + namespace: sonataflow-operator-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: sonataflow-operator-manager-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: sonataflow-operator-manager-role +subjects: +- kind: ServiceAccount + name: sonataflow-operator-controller-manager + namespace: sonataflow-operator-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: sonataflow-operator-openshift-manager-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: sonataflow-operator-openshift-manager-role +subjects: +- kind: ServiceAccount + name: sonataflow-operator-controller-manager + namespace: sonataflow-operator-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: sonataflow-operator-proxy-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: sonataflow-operator-proxy-role +subjects: +- kind: ServiceAccount + name: sonataflow-operator-controller-manager + namespace: sonataflow-operator-system +--- +apiVersion: v1 +data: + DEFAULT_BUILDER_RESOURCE_NAME: Dockerfile + DEFAULT_WORKFLOW_EXTENSION: .sw.json + Dockerfile: "FROM quay.io/kiegroup/kogito-swf-builder-nightly:latest AS builder\n\n# + variables that can be overridden by the builder\n# To add a Quarkus extension + to your application\nARG QUARKUS_EXTENSIONS\n# Args to pass to the Quarkus CLI + add extension command\nARG QUARKUS_ADD_EXTENSION_ARGS\n\n# Copy from build context + to skeleton resources project\nCOPY --chmod=644 * ./resources/\n\nRUN /home/kogito/launch/build-app.sh + ./resources\n \n#=============================\n# Runtime Run\n#=============================\nFROM + registry.access.redhat.com/ubi8/openjdk-11:latest\n\nENV LANG='en_US.UTF-8' LANGUAGE='en_US:en'\n + \ \n# We make four distinct layers so if there are application changes the library + layers can be re-used\nCOPY --from=builder --chown=185 /home/kogito/serverless-workflow-project/target/quarkus-app/lib/ + /deployments/lib/\nCOPY --from=builder --chown=185 /home/kogito/serverless-workflow-project/target/quarkus-app/*.jar + /deployments/\nCOPY --from=builder --chown=185 /home/kogito/serverless-workflow-project/target/quarkus-app/app/ + /deployments/app/\nCOPY --from=builder --chown=185 /home/kogito/serverless-workflow-project/target/quarkus-app/quarkus/ + /deployments/quarkus/\n\nEXPOSE 8080\nUSER 185\nENV AB_JOLOKIA_OFF=\"\"\nENV JAVA_OPTS=\"-Dquarkus.http.host=0.0.0.0 + -Djava.util.logging.manager=org.jboss.logmanager.LogManager\"\nENV JAVA_APP_JAR=\"/deployments/quarkus-run.jar\"\n" +kind: ConfigMap +metadata: + name: sonataflow-operator-builder-config + namespace: sonataflow-operator-system +--- +apiVersion: v1 +data: + controller_manager_config.yaml: | + apiVersion: controller-runtime.sigs.k8s.io/v1alpha1 + kind: ControllerManagerConfig + health: + healthProbeBindAddress: :8081 + metrics: + bindAddress: 127.0.0.1:8080 + webhook: + port: 9443 + leaderElection: + leaderElect: true + resourceName: 1be5e57d.kiegroup.org +kind: ConfigMap +metadata: + name: sonataflow-operator-manager-config + namespace: sonataflow-operator-system +--- +apiVersion: v1 +kind: Service +metadata: + labels: + control-plane: controller-manager + name: sonataflow-operator-controller-manager-metrics-service + namespace: sonataflow-operator-system +spec: + ports: + - name: https + port: 8443 + protocol: TCP + targetPort: https + selector: + control-plane: controller-manager +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + control-plane: controller-manager + name: sonataflow-operator-controller-manager + namespace: sonataflow-operator-system +spec: + replicas: 1 + selector: + matchLabels: + control-plane: controller-manager + template: + metadata: + annotations: + kubectl.kubernetes.io/default-container: manager + labels: + control-plane: controller-manager + spec: + containers: + - args: + - --secure-listen-address=0.0.0.0:8443 + - --upstream=http://127.0.0.1:8080/ + - --logtostderr=true + - --v=0 + image: gcr.io/kubebuilder/kube-rbac-proxy:v0.13.0 + name: kube-rbac-proxy + ports: + - containerPort: 8443 + name: https + protocol: TCP + resources: + limits: + cpu: 500m + memory: 128Mi + requests: + cpu: 5m + memory: 64Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + seccompProfile: + type: RuntimeDefault + - args: + - --health-probe-bind-address=:8081 + - --metrics-bind-address=127.0.0.1:8080 + - --leader-elect + - --v=0 + command: + - /usr/local/bin/manager + env: + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: ENABLE_WEBHOOKS + value: "false" + image: quay.io/kiegroup/kogito-serverless-operator-nightly:latest + livenessProbe: + httpGet: + path: /healthz + port: 8081 + initialDelaySeconds: 15 + periodSeconds: 20 + name: manager + readinessProbe: + httpGet: + path: /readyz + port: 8081 + initialDelaySeconds: 5 + periodSeconds: 10 + resources: + limits: + cpu: 500m + memory: 128Mi + requests: + cpu: 10m + memory: 64Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + securityContext: + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + serviceAccountName: sonataflow-operator-controller-manager + terminationGracePeriodSeconds: 10 diff --git a/operator.yaml b/operator.yaml index d8dd93d53..f494e7ce4 100644 --- a/operator.yaml +++ b/operator.yaml @@ -9,8 +9,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: + cert-manager.io/inject-ca-from: sonataflow-operator-system/sonataflow-operator-serving-cert controller-gen.kubebuilder.io/version: v0.9.2 - creationTimestamp: null name: sonataflowbuilds.sonataflow.org spec: group: sonataflow.org @@ -367,10 +367,20 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: + cert-manager.io/inject-ca-from: sonataflow-operator-system/sonataflow-operator-serving-cert controller-gen.kubebuilder.io/version: v0.9.2 - creationTimestamp: null name: sonataflowplatforms.sonataflow.org spec: + conversion: + strategy: Webhook + webhook: + clientConfig: + service: + name: sonataflow-operator-webhook-service + namespace: sonataflow-operator-system + path: /convert + conversionReviewVersions: + - v1 group: sonataflow.org names: kind: SonataFlowPlatform @@ -847,8 +857,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: + cert-manager.io/inject-ca-from: sonataflow-operator-system/sonataflow-operator-serving-cert controller-gen.kubebuilder.io/version: v0.9.2 - creationTimestamp: null name: sonataflows.sonataflow.org spec: group: sonataflow.org @@ -3535,6 +3545,26 @@ spec: selector: control-plane: controller-manager --- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: webhook + app.kubernetes.io/created-by: sonataflow + app.kubernetes.io/instance: webhook-service + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: service + app.kubernetes.io/part-of: sonataflow + name: sonataflow-operator-webhook-service + namespace: sonataflow-operator-system +spec: + ports: + - port: 443 + protocol: TCP + targetPort: 9443 + selector: + control-plane: controller-manager +--- apiVersion: apps/v1 kind: Deployment metadata: @@ -3555,31 +3585,6 @@ spec: control-plane: controller-manager spec: containers: - - args: - - --secure-listen-address=0.0.0.0:8443 - - --upstream=http://127.0.0.1:8080/ - - --logtostderr=true - - --v=0 - image: gcr.io/kubebuilder/kube-rbac-proxy:v0.13.0 - name: kube-rbac-proxy - ports: - - containerPort: 8443 - name: https - protocol: TCP - resources: - limits: - cpu: 500m - memory: 128Mi - requests: - cpu: 5m - memory: 64Mi - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - ALL - seccompProfile: - type: RuntimeDefault - args: - --health-probe-bind-address=:8081 - --metrics-bind-address=127.0.0.1:8080 @@ -3600,6 +3605,10 @@ spec: initialDelaySeconds: 15 periodSeconds: 20 name: manager + ports: + - containerPort: 9443 + name: webhook-server + protocol: TCP readinessProbe: httpGet: path: /readyz @@ -3618,9 +3627,115 @@ spec: capabilities: drop: - ALL + volumeMounts: + - mountPath: /tmp/k8s-webhook-server/serving-certs + name: cert + readOnly: true + - args: + - --secure-listen-address=0.0.0.0:8443 + - --upstream=http://127.0.0.1:8080/ + - --logtostderr=true + - --v=0 + image: gcr.io/kubebuilder/kube-rbac-proxy:v0.13.0 + name: kube-rbac-proxy + ports: + - containerPort: 8443 + name: https + protocol: TCP + resources: + limits: + cpu: 500m + memory: 128Mi + requests: + cpu: 5m + memory: 64Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + seccompProfile: + type: RuntimeDefault securityContext: runAsNonRoot: true seccompProfile: type: RuntimeDefault serviceAccountName: sonataflow-operator-controller-manager terminationGracePeriodSeconds: 10 + volumes: + - name: cert + secret: + defaultMode: 420 + secretName: webhook-server-cert +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + labels: + app.kubernetes.io/component: certificate + app.kubernetes.io/created-by: sonataflow + app.kubernetes.io/instance: serving-cert + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: certificate + app.kubernetes.io/part-of: sonataflow + name: sonataflow-operator-serving-cert + namespace: sonataflow-operator-system +spec: + dnsNames: + - sonataflow-operator-webhook-service.sonataflow-operator-system.svc + - sonataflow-operator-webhook-service.sonataflow-operator-system.svc.cluster.local + issuerRef: + kind: Issuer + name: sonataflow-operator-selfsigned-issuer + secretName: webhook-server-cert +--- +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + labels: + app.kubernetes.io/component: certificate + app.kubernetes.io/created-by: sonataflow + app.kubernetes.io/instance: selfsigned-issuer + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: issuer + app.kubernetes.io/part-of: sonataflow + name: sonataflow-operator-selfsigned-issuer + namespace: sonataflow-operator-system +spec: + selfSigned: {} +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + annotations: + cert-manager.io/inject-ca-from: sonataflow-operator-system/sonataflow-operator-serving-cert + labels: + app.kubernetes.io/component: webhook + app.kubernetes.io/created-by: sonataflow + app.kubernetes.io/instance: validating-webhook-configuration + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: validatingwebhookconfiguration + app.kubernetes.io/part-of: sonataflow + name: sonataflow-operator-validating-webhook-configuration +webhooks: +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: sonataflow-operator-webhook-service + namespace: sonataflow-operator-system + path: /validate-sonataflow-org-v1alpha08-sonataflow + failurePolicy: Fail + name: vsonataflow.kb.io + rules: + - apiGroups: + - sonataflow.org + apiVersions: + - v1alpha08 + operations: + - CREATE + - UPDATE + - DELETE + resources: + - sonataflows + sideEffects: None diff --git a/test/e2e/utils.go b/test/e2e/utils.go new file mode 100644 index 000000000..b7603732a --- /dev/null +++ b/test/e2e/utils.go @@ -0,0 +1,93 @@ +// Copyright 2023 Red Hat, Inc. and/or its affiliates +// +// 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 e2e + +import ( + "fmt" + "net/url" + "os" + "os/exec" + "strconv" + "strings" + + "github.com/kiegroup/kogito-serverless-operator/test" + "github.com/kiegroup/kogito-serverless-operator/test/utils" + + //nolint:golint + //nolint:revive + . "github.com/onsi/ginkgo/v2" +) + +// namespace store the ns where the Operator and Operand will be executed +const namespace = "sonataflow-operator-system" + +const ( + minikubePlatform = "minikube" + openshiftPlatform = "openshift" +) + +func verifyWorkflowIsInRunningState(workflowName string) bool { + cmd := exec.Command("kubectl", "get", "workflow", workflowName, "-n", namespace, "-o", "jsonpath={.status.conditions[?(@.type=='Running')].status}") + if response, err := utils.Run(cmd); err != nil { + GinkgoWriter.Println(fmt.Errorf("failed to check if greeting workflow is running: %v", err)) + return false + } else { + GinkgoWriter.Println(fmt.Sprintf("Got response %s", response)) + + if len(strings.TrimSpace(string(response))) > 0 { + status, err := strconv.ParseBool(string(response)) + if err != nil { + GinkgoWriter.Println(fmt.Errorf("failed to parse result %v", err)) + return false + } + return status + } + return false + } +} + +func verifyWorkflowIsAddressable(workflowName string) bool { + cmd := exec.Command("kubectl", "get", "workflow", workflowName, "-n", namespace, "-o", "jsonpath={.status.address.url}") + if response, err := utils.Run(cmd); err != nil { + GinkgoWriter.Println(fmt.Errorf("failed to check if greeting workflow is running: %v", err)) + return false + } else { + GinkgoWriter.Println(fmt.Sprintf("Got response %s", response)) + if len(strings.TrimSpace(string(response))) > 0 { + _, err := url.ParseRequestURI(string(response)) + if err != nil { + GinkgoWriter.Println(fmt.Errorf("failed to parse result %v", err)) + return false + } + // The response is a valid URL so the test is passed + return true + } + return false + } +} + +func getSonataFlowPlatformFilename() string { + if getClusterPlatform() == openshiftPlatform { + return test.GetPlatformOpenshiftE2eTest() + } + return test.GetPlatformMinikubeE2eTest() +} + +func getClusterPlatform() string { + if v, ok := os.LookupEnv("CLUSTER_PLATFORM"); ok { + return v + } + return minikubePlatform +} diff --git a/test/e2e/workflow_nowebhooks_test.go b/test/e2e/workflow_nowebhooks_test.go new file mode 100644 index 000000000..6244067ae --- /dev/null +++ b/test/e2e/workflow_nowebhooks_test.go @@ -0,0 +1,172 @@ +// Copyright 2022 Red Hat, Inc. and/or its affiliates +// +// 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 e2e + +import ( + "fmt" + "os/exec" + "path/filepath" + "time" + + "github.com/kiegroup/kogito-serverless-operator/test" + "github.com/kiegroup/kogito-serverless-operator/test/utils" + + //nolint:golint + //nolint:revive + . "github.com/onsi/ginkgo/v2" + + //nolint:golint + //nolint:revive + . "github.com/onsi/gomega" +) + +var _ = Describe("SonataFlow Operator - no webhooks", Serial, func() { + + Describe("ensure that Operator and Operand(s) can run in restricted namespaces - no webhooks", Ordered, func() { + It("Prepare the environment - no webhooks", func() { + var controllerPodName string + operatorImageName, err := utils.GetOperatorImageName() + ExpectWithOffset(1, err).NotTo(HaveOccurred()) + + By("deploying the controller-manager") + cmd := exec.Command("make", "deploy-no-webhooks", fmt.Sprintf("IMG=%s", operatorImageName)) + outputMake, err := utils.Run(cmd) + fmt.Println(string(outputMake)) + ExpectWithOffset(1, err).NotTo(HaveOccurred()) + + By("validating that the controller-manager pod is running as expected - no webhooks") + verifyControllerUp := func() error { + var podOutput []byte + var err error + + if utils.IsDebugEnabled() { + err = utils.OutputAllPods() + err = utils.OutputAllEvents(namespace) + } + + // Get pod name + cmd = exec.Command("kubectl", "get", + "pods", "-l", "control-plane=controller-manager", + "-o", "go-template={{ range .items }}{{ if not .metadata.deletionTimestamp }}{{ .metadata.name }}"+ + "{{ \"\\n\" }}{{ end }}{{ end }}", + "-n", namespace, + ) + podOutput, err = utils.Run(cmd) + fmt.Println(string(podOutput)) + ExpectWithOffset(2, err).NotTo(HaveOccurred()) + podNames := utils.GetNonEmptyLines(string(podOutput)) + if len(podNames) != 1 { + return fmt.Errorf("expect 1 controller pods running, but got %d", len(podNames)) + } + controllerPodName = podNames[0] + ExpectWithOffset(2, controllerPodName).Should(ContainSubstring("controller-manager")) + + // Validate pod status + cmd = exec.Command("kubectl", "get", + "pods", controllerPodName, "-o", "jsonpath={.status.phase}", + "-n", namespace, + ) + status, err := utils.Run(cmd) + fmt.Println(string(status)) + ExpectWithOffset(2, err).NotTo(HaveOccurred()) + if string(status) != "Running" { + return fmt.Errorf("controller pod in %s status", status) + } + return nil + } + EventuallyWithOffset(1, verifyControllerUp, time.Minute, time.Second).Should(Succeed()) + }) + + // ============= SONATAFLOW OPERATOR TESTS ============= + + projectDir, _ := utils.GetProjectDir() + + It("should create a basic platform for Minikube - no webhooks", func() { + By("creating an instance of the SonataFlowPlatform") + EventuallyWithOffset(1, func() error { + cmd := exec.Command("kubectl", "apply", "-f", filepath.Join(projectDir, + getSonataFlowPlatformFilename()), "-n", namespace) + _, err := utils.Run(cmd) + return err + }, time.Minute, time.Second).Should(Succeed()) + }) + + It("should successfully deploy the Greeting Workflow in prod mode and verify if it's running - no webhooks", func() { + By("creating external resources DataInputSchema configMap - no webhooks") + EventuallyWithOffset(1, func() error { + cmd := exec.Command("kubectl", "apply", "-f", filepath.Join(projectDir, + "test/testdata/"+test.SonataFlowGreetingsDataInputSchemaConfig), "-n", namespace) + _, err := utils.Run(cmd) + return err + }, time.Minute, time.Second).Should(Succeed()) + + By("creating an instance of the SonataFlow Operand(CR) - no webhooks") + EventuallyWithOffset(1, func() error { + cmd := exec.Command("kubectl", "apply", "-f", filepath.Join(projectDir, + "test/testdata/"+test.SonataFlowGreetingsWithDataInputSchemaCR), "-n", namespace) + _, err := utils.Run(cmd) + return err + }, time.Minute, time.Second).Should(Succeed()) + + By("check the workflow is in running state - no webhooks") + EventuallyWithOffset(1, func() bool { return verifyWorkflowIsInRunningState("greeting") }, 15*time.Minute, 30*time.Second).Should(BeTrue()) + + EventuallyWithOffset(1, func() error { + cmd := exec.Command("kubectl", "delete", "-f", filepath.Join(projectDir, + "test/testdata/"+test.SonataFlowGreetingsWithDataInputSchemaCR), "-n", namespace) + _, err := utils.Run(cmd) + return err + }, time.Minute, time.Second).Should(Succeed()) + }) + + It("should successfully deploy the orderprocessing workflow in devmode and verify if it's running - no webhooks", func() { + + By("creating an instance of the SonataFlow Workflow in DevMode - no webhooks") + EventuallyWithOffset(1, func() error { + cmd := exec.Command("kubectl", "apply", "-f", filepath.Join(projectDir, + test.GetSonataFlowE2eOrderProcessingFolder()), "-n", namespace) + _, err := utils.Run(cmd) + return err + }, time.Minute, time.Second).Should(Succeed()) + + By("check the workflow is in running state - no webhooks") + EventuallyWithOffset(1, func() bool { return verifyWorkflowIsInRunningState("orderprocessing") }, 15*time.Minute, 30*time.Second).Should(BeTrue()) + + cmdLog := exec.Command("kubectl", "logs", "orderprocessing", "-n", namespace) + if responseLog, errLog := utils.Run(cmdLog); errLog == nil { + GinkgoWriter.Println(fmt.Sprintf("devmode podlog %s", responseLog)) + } + + By("check that the workflow is addressable - no webhooks") + EventuallyWithOffset(1, func() bool { return verifyWorkflowIsAddressable("orderprocessing") }, 5*time.Minute, 30*time.Second).Should(BeTrue()) + + EventuallyWithOffset(1, func() error { + cmd := exec.Command("kubectl", "delete", "-f", filepath.Join(projectDir, + test.GetSonataFlowE2eOrderProcessingFolder()), "-n", namespace) + _, err := utils.Run(cmd) + return err + }, time.Minute, time.Second).Should(Succeed()) + }) + + AfterAll(func() { + By("removing manager namespace - no webhooks") + cmd := exec.Command("make", "undeploy") + _, _ = utils.Run(cmd) + By("uninstalling CRDs") + cmd = exec.Command("make", "uninstall") + _, _ = utils.Run(cmd) + }) + }) +}) diff --git a/test/e2e/workflow_test.go b/test/e2e/workflow_test.go index 7ccc3382d..cdbcc4b89 100644 --- a/test/e2e/workflow_test.go +++ b/test/e2e/workflow_test.go @@ -16,12 +16,8 @@ package e2e import ( "fmt" - "net/url" - "os" "os/exec" "path/filepath" - "strconv" - "strings" "time" "github.com/kiegroup/kogito-serverless-operator/test" @@ -36,139 +32,121 @@ import ( . "github.com/onsi/gomega" ) -// namespace store the ns where the Operator and Operand will be executed -const namespace = "sonataflow-operator-system" - -const ( - minikubePlatform = "minikube" - openshiftPlatform = "openshift" -) - -var _ = Describe("SonataFlow Operator", Ordered, func() { +var _ = Describe("SonataFlow Operator", Serial, func() { + + Describe("ensure that Operator and Operand(s) can run in restricted namespaces", Ordered, func() { + It("Prepare the environment", func() { + // Now, let's ensure that all namespaces can raise a Warn when we apply the manifests + // and that the namespace where the Operator and Operand will run are enforced as + // restricted so that we can ensure that both can be admitted and run with the enforcement + + // See: https://kubernetes.io/docs/tutorials/security/seccomp/ + + /* + TODO: Uncomment to enable when https://issues.redhat.com/browse/KOGITO-9110 will be available + By("labeling all namespaces to warn when we apply the manifest if would violate the PodStandards") + cmd = exec.Command("kubectl", "label", "--overwrite", "ns", "--all", + "pod-security.kubernetes.io/audit=restricted", + "pod-security.kubernetes.io/enforce-version=v1.22", + "pod-security.kubernetes.io/warn=restricted") + _, err := utils.Run(cmd) + ExpectWithOffset(1, err).NotTo(HaveOccurred()) + + By("labeling enforce the namespace where the Operator and Operand(s) will run") + cmd = exec.Command("kubectl", "label", "--overwrite", "ns", namespace, + "pod-security.kubernetes.io/audit=restricted", + "pod-security.kubernetes.io/enforce-version=v1.22", + "pod-security.kubernetes.io/enforce=restricted") + _, err = utils.Run(cmd) + Expect(err).To(Not(HaveOccurred())) + + */ + + var controllerPodName string + operatorImageName, err := utils.GetOperatorImageName() + ExpectWithOffset(1, err).NotTo(HaveOccurred()) - BeforeAll(func() { + By("deploying the controller-manager") + cmd := exec.Command("make", "deploy", fmt.Sprintf("IMG=%s", operatorImageName)) + outputMake, err := utils.Run(cmd) + fmt.Println(string(outputMake)) + ExpectWithOffset(1, err).NotTo(HaveOccurred()) - // Now, let's ensure that all namespaces can raise a Warn when we apply the manifests - // and that the namespace where the Operator and Operand will run are enforced as - // restricted so that we can ensure that both can be admitted and run with the enforcement + /* // TODO: Uncomment to enable when https://issues.redhat.com/browse/KOGITO-9110 will be available - // See: https://kubernetes.io/docs/tutorials/security/seccomp/ + By("validating that manager Pod/container(s) are restricted") + // Get Podsecurity violation lines + lines, err := utils.StringToLines(string(outputMake)) + ExpectWithOffset(1, err).NotTo(HaveOccurred()) + var violationLines []string + applySeccompProfilePatch := false + for _, line := range lines { + if strings.Contains(line, "Warning: would violate PodSecurity") { + if strings.Contains(line, "must set securityContext.seccompProfile.type to") { + // Ignore this violation as it is expected + applySeccompProfilePatch = true + } else { + violationLines = append(violationLines, line) + } + } + } + Expect(violationLines).To(BeEmpty()) - /* - TODO: Uncomment to enable when https://issues.redhat.com/browse/KOGITO-9110 will be available - By("labeling all namespaces to warn when we apply the manifest if would violate the PodStandards") - cmd = exec.Command("kubectl", "label", "--overwrite", "ns", "--all", - "pod-security.kubernetes.io/audit=restricted", - "pod-security.kubernetes.io/enforce-version=v1.22", - "pod-security.kubernetes.io/warn=restricted") + if applySeccompProfilePatch { + By("Applying seccompProfile") + cmd = exec.Command("kubectl", "patch", "deployment", "sonataflow-operator-controller-manager", "-p", `{"spec":{"template":{"spec":{"securityContext":{"seccompProfile":{"type":"RuntimeDefault"}}}}}}`, "-n", namespace) _, err := utils.Run(cmd) - ExpectWithOffset(1, err).NotTo(HaveOccurred()) - - By("labeling enforce the namespace where the Operator and Operand(s) will run") - cmd = exec.Command("kubectl", "label", "--overwrite", "ns", namespace, - "pod-security.kubernetes.io/audit=restricted", - "pod-security.kubernetes.io/enforce-version=v1.22", - "pod-security.kubernetes.io/enforce=restricted") - _, err = utils.Run(cmd) - Expect(err).To(Not(HaveOccurred())) - - */ - - var controllerPodName string - operatorImageName, err := utils.GetOperatorImageName() - ExpectWithOffset(1, err).NotTo(HaveOccurred()) - - By("deploying the controller-manager") - cmd := exec.Command("make", "deploy", fmt.Sprintf("IMG=%s", operatorImageName)) - - outputMake, err := utils.Run(cmd) - fmt.Println(string(outputMake)) - ExpectWithOffset(1, err).NotTo(HaveOccurred()) - - /* // TODO: Uncomment to enable when https://issues.redhat.com/browse/KOGITO-9110 will be available - - By("validating that manager Pod/container(s) are restricted") - // Get Podsecurity violation lines - lines, err := utils.StringToLines(string(outputMake)) - ExpectWithOffset(1, err).NotTo(HaveOccurred()) - var violationLines []string - applySeccompProfilePatch := false - for _, line := range lines { - if strings.Contains(line, "Warning: would violate PodSecurity") { - if strings.Contains(line, "must set securityContext.seccompProfile.type to") { - // Ignore this violation as it is expected - applySeccompProfilePatch = true - } else { - violationLines = append(violationLines, line) + if utils.IsDebugEnabled() { + err = utils.OutputDeployment(namespace, "sonataflow-operator-controller-manager") } + ExpectWithOffset(1, err).NotTo(HaveOccurred()) } - } - Expect(violationLines).To(BeEmpty()) - - if applySeccompProfilePatch { - By("Applying seccompProfile") - cmd = exec.Command("kubectl", "patch", "deployment", "sonataflow-operator-controller-manager", "-p", `{"spec":{"template":{"spec":{"securityContext":{"seccompProfile":{"type":"RuntimeDefault"}}}}}}`, "-n", namespace) - _, err := utils.Run(cmd) - if utils.IsDebugEnabled() { - err = utils.OutputDeployment(namespace, "sonataflow-operator-controller-manager") - } - ExpectWithOffset(1, err).NotTo(HaveOccurred()) - } - */ + */ - By("validating that the controller-manager pod is running as expected") - verifyControllerUp := func() error { - var podOutput []byte - var err error + By("validating that the controller-manager pod is running as expected") + verifyControllerUp := func() error { + var podOutput []byte + var err error - if utils.IsDebugEnabled() { - err = utils.OutputAllPods() - err = utils.OutputAllEvents(namespace) - } + if utils.IsDebugEnabled() { + err = utils.OutputAllPods() + err = utils.OutputAllEvents(namespace) + } - // Get pod name - cmd = exec.Command("kubectl", "get", - "pods", "-l", "control-plane=controller-manager", - "-o", "go-template={{ range .items }}{{ if not .metadata.deletionTimestamp }}{{ .metadata.name }}"+ - "{{ \"\\n\" }}{{ end }}{{ end }}", - "-n", namespace, - ) - podOutput, err = utils.Run(cmd) - fmt.Println(string(podOutput)) - ExpectWithOffset(2, err).NotTo(HaveOccurred()) - podNames := utils.GetNonEmptyLines(string(podOutput)) - if len(podNames) != 1 { - return fmt.Errorf("expect 1 controller pods running, but got %d", len(podNames)) - } - controllerPodName = podNames[0] - ExpectWithOffset(2, controllerPodName).Should(ContainSubstring("controller-manager")) - - // Validate pod status - cmd = exec.Command("kubectl", "get", - "pods", controllerPodName, "-o", "jsonpath={.status.phase}", - "-n", namespace, - ) - status, err := utils.Run(cmd) - fmt.Println(string(status)) - ExpectWithOffset(2, err).NotTo(HaveOccurred()) - if string(status) != "Running" { - return fmt.Errorf("controller pod in %s status", status) + // Get pod name + cmd = exec.Command("kubectl", "get", + "pods", "-l", "control-plane=controller-manager", + "-o", "go-template={{ range .items }}{{ if not .metadata.deletionTimestamp }}{{ .metadata.name }}"+ + "{{ \"\\n\" }}{{ end }}{{ end }}", + "-n", namespace, + ) + podOutput, err = utils.Run(cmd) + fmt.Println(string(podOutput)) + ExpectWithOffset(2, err).NotTo(HaveOccurred()) + podNames := utils.GetNonEmptyLines(string(podOutput)) + if len(podNames) != 1 { + return fmt.Errorf("expect 1 controller pods running, but got %d", len(podNames)) + } + controllerPodName = podNames[0] + ExpectWithOffset(2, controllerPodName).Should(ContainSubstring("controller-manager")) + + // Validate pod status + cmd = exec.Command("kubectl", "get", + "pods", controllerPodName, "-o", "jsonpath={.status.phase}", + "-n", namespace, + ) + status, err := utils.Run(cmd) + fmt.Println(string(status)) + ExpectWithOffset(2, err).NotTo(HaveOccurred()) + if string(status) != "Running" { + return fmt.Errorf("controller pod in %s status", status) + } + return nil } - return nil - } - EventuallyWithOffset(1, verifyControllerUp, time.Minute, time.Second).Should(Succeed()) - }) - - AfterAll(func() { - By("removing manager namespace") - cmd := exec.Command("make", "undeploy") - _, _ = utils.Run(cmd) - By("uninstalling CRDs") - cmd = exec.Command("make", "uninstall") - _, _ = utils.Run(cmd) - }) + EventuallyWithOffset(1, verifyControllerUp, time.Minute, time.Second).Should(Succeed()) + }) - Describe("ensure that Operator and Operand(s) can run in restricted namespaces", func() { + // ============= SONATAFLOW OPERATOR TESTS ============= projectDir, _ := utils.GetProjectDir() It("should create a basic platform for Minikube", func() { @@ -220,7 +198,7 @@ var _ = Describe("SonataFlow Operator", Ordered, func() { }, time.Minute, time.Second).Should(Succeed()) By("check the workflow is in running state") - EventuallyWithOffset(1, func() bool { return verifyWorkflowIsInRunningState("orderprocessing") }, 5*time.Minute, 30*time.Second).Should(BeTrue()) + EventuallyWithOffset(1, func() bool { return verifyWorkflowIsInRunningState("orderprocessing") }, 15*time.Minute, 30*time.Second).Should(BeTrue()) cmdLog := exec.Command("kubectl", "logs", "orderprocessing", "-n", namespace) if responseLog, errLog := utils.Run(cmdLog); errLog == nil { @@ -237,59 +215,14 @@ var _ = Describe("SonataFlow Operator", Ordered, func() { return err }, time.Minute, time.Second).Should(Succeed()) }) + + AfterAll(func() { + By("removing manager namespace") + cmd := exec.Command("make", "undeploy") + _, _ = utils.Run(cmd) + By("uninstalling CRDs") + cmd = exec.Command("make", "uninstall") + _, _ = utils.Run(cmd) + }) }) }) - -func verifyWorkflowIsInRunningState(workflowName string) bool { - cmd := exec.Command("kubectl", "get", "workflow", workflowName, "-n", namespace, "-o", "jsonpath={.status.conditions[?(@.type=='Running')].status}") - if response, err := utils.Run(cmd); err != nil { - GinkgoWriter.Println(fmt.Errorf("failed to check if greeting workflow is running: %v", err)) - return false - } else { - GinkgoWriter.Println(fmt.Sprintf("Got response %s", response)) - - if len(strings.TrimSpace(string(response))) > 0 { - status, err := strconv.ParseBool(string(response)) - if err != nil { - GinkgoWriter.Println(fmt.Errorf("failed to parse result %v", err)) - return false - } - return status - } - return false - } -} - -func verifyWorkflowIsAddressable(workflowName string) bool { - cmd := exec.Command("kubectl", "get", "workflow", workflowName, "-n", namespace, "-o", "jsonpath={.status.address.url}") - if response, err := utils.Run(cmd); err != nil { - GinkgoWriter.Println(fmt.Errorf("failed to check if greeting workflow is running: %v", err)) - return false - } else { - GinkgoWriter.Println(fmt.Sprintf("Got response %s", response)) - if len(strings.TrimSpace(string(response))) > 0 { - _, err := url.ParseRequestURI(string(response)) - if err != nil { - GinkgoWriter.Println(fmt.Errorf("failed to parse result %v", err)) - return false - } - // The response is a valid URL so the test is passed - return true - } - return false - } -} - -func getSonataFlowPlatformFilename() string { - if getClusterPlatform() == openshiftPlatform { - return test.GetPlatformOpenshiftE2eTest() - } - return test.GetPlatformMinikubeE2eTest() -} - -func getClusterPlatform() string { - if v, ok := os.LookupEnv("CLUSTER_PLATFORM"); ok { - return v - } - return minikubePlatform -}