diff --git a/.gitignore b/.gitignore index c7948bf53..414655ca3 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,5 @@ /.idea/ /.vscode/ /target/ + +e2e-test-report.xml diff --git a/api/go.mod b/api/go.mod index c042cf35a..0f5a255bb 100644 --- a/api/go.mod +++ b/api/go.mod @@ -64,7 +64,7 @@ require ( golang.org/x/time v0.3.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/protobuf v1.31.0 // indirect + google.golang.org/protobuf v1.33.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/api/go.sum b/api/go.sum index efd315a8e..4f6bbea50 100644 --- a/api/go.sum +++ b/api/go.sum @@ -265,7 +265,7 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba 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.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= 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= diff --git a/api/metadata/annotations.go b/api/metadata/annotations.go index 55f60ea56..a0980ab94 100644 --- a/api/metadata/annotations.go +++ b/api/metadata/annotations.go @@ -41,6 +41,19 @@ const ( SpecVersion = "0.8" ) +type QuarkusProfileType string + +func (p QuarkusProfileType) String() string { + return string(p) +} + +const ( + // QuarkusDevProfile the profile used by quarkus in devmode + QuarkusDevProfile QuarkusProfileType = "dev" + // QuarkusProdProfile the profile used by quarkus in an immutable image + QuarkusProdProfile QuarkusProfileType = "prod" +) + type ProfileType string func (p ProfileType) String() string { @@ -48,6 +61,15 @@ func (p ProfileType) String() string { } const ( - DevProfile ProfileType = "dev" + // DevProfile deploys a mutable workflow that can be changed based on .spec.flow definitions CR change. + DevProfile ProfileType = "dev" + // Deprecated: use PreviewProfile. ProdProfile ProfileType = "prod" + // PreviewProfile is the default profile if none is set. + // The operator will use the platform to do a minimal image build for users to preview an immutable app deployed in the cluster. + // Not suitable for production use cases since the managed build has configuration and resources limitations. + PreviewProfile ProfileType = "preview" + // GitOpsProfile signs the operator that the application image is built externally, skipping any internal managed build. + // Ideally used in production use cases + GitOpsProfile ProfileType = "gitops" ) diff --git a/api/v1alpha08/sonataflow_types.go b/api/v1alpha08/sonataflow_types.go index ac32fe357..3237fc1f5 100644 --- a/api/v1alpha08/sonataflow_types.go +++ b/api/v1alpha08/sonataflow_types.go @@ -680,6 +680,9 @@ type SonataFlowStatus struct { // Endpoint is an externally accessible URL of the workflow //+operator-sdk:csv:customresourcedefinitions:type=status,displayName="endpoint" Endpoint *apis.URL `json:"endpoint,omitempty"` + // Services displays which platform services are being used by this workflow + //+operator-sdk:csv:customresourcedefinitions:type=status,displayName="services" + Services *PlatformServicesStatus `json:"services,omitempty"` } func (s *SonataFlowStatus) GetTopLevelConditionType() api.ConditionType { diff --git a/api/v1alpha08/sonataflowplatform_types.go b/api/v1alpha08/sonataflowplatform_types.go index c702c149b..9dfff7ce6 100644 --- a/api/v1alpha08/sonataflowplatform_types.go +++ b/api/v1alpha08/sonataflowplatform_types.go @@ -113,7 +113,7 @@ type PlatformServicesStatus struct { // PlatformServiceRefStatus displays information on a cluster-wide service // +k8s:openapi-gen=true type PlatformServiceRefStatus struct { - // Url displays the base url of a cluster-wide service + // Url displays the base url of the service Url string `json:"url,omitempty"` } diff --git a/api/v1alpha08/zz_generated.deepcopy.go b/api/v1alpha08/zz_generated.deepcopy.go index fb2db1872..b311b3a83 100644 --- a/api/v1alpha08/zz_generated.deepcopy.go +++ b/api/v1alpha08/zz_generated.deepcopy.go @@ -1203,6 +1203,11 @@ func (in *SonataFlowStatus) DeepCopyInto(out *SonataFlowStatus) { *out = new(apis.URL) (*in).DeepCopyInto(*out) } + if in.Services != nil { + in, out := &in.Services, &out.Services + *out = new(PlatformServicesStatus) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SonataFlowStatus. diff --git a/bddframework/go.mod b/bddframework/go.mod index fa6bd8461..db09ebb29 100644 --- a/bddframework/go.mod +++ b/bddframework/go.mod @@ -113,7 +113,7 @@ require ( google.golang.org/genproto/googleapis/api v0.0.0-20231002182017-d307bd883b97 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20231009173412-8bfb1ae86b6c // indirect google.golang.org/grpc v1.58.3 // indirect - google.golang.org/protobuf v1.31.0 // indirect + google.golang.org/protobuf v1.33.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/src-d/go-billy.v4 v4.3.2 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect diff --git a/bddframework/go.sum b/bddframework/go.sum index 38b0bee35..fa1eb9ad9 100644 --- a/bddframework/go.sum +++ b/bddframework/go.sum @@ -1386,7 +1386,7 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba 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.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/bundle/manifests/sonataflow-operator.clusterserviceversion.yaml b/bundle/manifests/sonataflow-operator.clusterserviceversion.yaml index 7597683f5..a4ce43c40 100644 --- a/bundle/manifests/sonataflow-operator.clusterserviceversion.yaml +++ b/bundle/manifests/sonataflow-operator.clusterserviceversion.yaml @@ -329,6 +329,10 @@ spec: so far displayName: recoverFailureAttempts path: recoverFailureAttempts + - description: Services displays which platform services are being used by this + workflow + displayName: services + path: services version: v1alpha08 description: |- SonataFlow Kubernetes Operator for deploying workflow applications diff --git a/bundle/manifests/sonataflow.org_sonataflowplatforms.yaml b/bundle/manifests/sonataflow.org_sonataflowplatforms.yaml index 1752ac7c2..29791ec82 100644 --- a/bundle/manifests/sonataflow.org_sonataflowplatforms.yaml +++ b/bundle/manifests/sonataflow.org_sonataflowplatforms.yaml @@ -16270,8 +16270,7 @@ spec: Data Index service properties: url: - description: Url displays the base url of a cluster-wide - service + description: Url displays the base url of the service type: string type: object jobServiceRef: @@ -16279,8 +16278,7 @@ spec: Job Service properties: url: - description: Url displays the base url of a cluster-wide - service + description: Url displays the base url of the service type: string type: object type: object diff --git a/bundle/manifests/sonataflow.org_sonataflows.yaml b/bundle/manifests/sonataflow.org_sonataflows.yaml index 6836cd493..eaf80c918 100644 --- a/bundle/manifests/sonataflow.org_sonataflows.yaml +++ b/bundle/manifests/sonataflow.org_sonataflows.yaml @@ -9456,6 +9456,27 @@ spec: description: keeps track of how many failure recovers a given workflow had so far type: integer + services: + description: Services displays which platform services are being used + by this workflow + properties: + dataIndexRef: + description: DataIndexRef displays information on the cluster-wide + Data Index service + properties: + url: + description: Url displays the base url of the service + type: string + type: object + jobServiceRef: + description: JobServiceRef displays information on the cluster-wide + Job Service + properties: + url: + description: Url displays the base url of the service + type: string + type: object + type: object type: object type: object served: true diff --git a/config/crd/bases/sonataflow.org_sonataflowplatforms.yaml b/config/crd/bases/sonataflow.org_sonataflowplatforms.yaml index a1cb0213b..8d4338331 100644 --- a/config/crd/bases/sonataflow.org_sonataflowplatforms.yaml +++ b/config/crd/bases/sonataflow.org_sonataflowplatforms.yaml @@ -16271,8 +16271,7 @@ spec: Data Index service properties: url: - description: Url displays the base url of a cluster-wide - service + description: Url displays the base url of the service type: string type: object jobServiceRef: @@ -16280,8 +16279,7 @@ spec: Job Service properties: url: - description: Url displays the base url of a cluster-wide - service + description: Url displays the base url of the service type: string type: object type: object diff --git a/config/crd/bases/sonataflow.org_sonataflows.yaml b/config/crd/bases/sonataflow.org_sonataflows.yaml index a9df118fd..1557c3b86 100644 --- a/config/crd/bases/sonataflow.org_sonataflows.yaml +++ b/config/crd/bases/sonataflow.org_sonataflows.yaml @@ -9457,6 +9457,27 @@ spec: description: keeps track of how many failure recovers a given workflow had so far type: integer + services: + description: Services displays which platform services are being used + by this workflow + properties: + dataIndexRef: + description: DataIndexRef displays information on the cluster-wide + Data Index service + properties: + url: + description: Url displays the base url of the service + type: string + type: object + jobServiceRef: + description: JobServiceRef displays information on the cluster-wide + Job Service + properties: + url: + description: Url displays the base url of the service + type: string + type: object + type: object type: object type: object served: true diff --git a/config/manifests/bases/sonataflow-operator.clusterserviceversion.yaml b/config/manifests/bases/sonataflow-operator.clusterserviceversion.yaml index 089ae24b4..c61183d84 100644 --- a/config/manifests/bases/sonataflow-operator.clusterserviceversion.yaml +++ b/config/manifests/bases/sonataflow-operator.clusterserviceversion.yaml @@ -213,6 +213,10 @@ spec: so far displayName: recoverFailureAttempts path: recoverFailureAttempts + - description: Services displays which platform services are being used by this + workflow + displayName: services + path: services version: v1alpha08 description: |- SonataFlow Kubernetes Operator for deploying workflow applications diff --git a/container-builder/go.mod b/container-builder/go.mod index a5cfbe71c..fc52361c8 100644 --- a/container-builder/go.mod +++ b/container-builder/go.mod @@ -3,7 +3,7 @@ module github.com/apache/incubator-kie-kogito-serverless-operator/container-buil go 1.21 require ( - github.com/docker/docker v24.0.7+incompatible + github.com/docker/docker v24.0.9+incompatible github.com/docker/go-connections v0.4.1-0.20210727194412-58542c764a11 github.com/google/uuid v1.3.1 github.com/hashicorp/go-version v1.6.0 @@ -76,7 +76,7 @@ require ( golang.org/x/tools v0.14.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/protobuf v1.31.0 // indirect + google.golang.org/protobuf v1.33.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/container-builder/go.sum b/container-builder/go.sum index 98907ed61..b4e1a2085 100644 --- a/container-builder/go.sum +++ b/container-builder/go.sum @@ -1,14 +1,17 @@ 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/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= +github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= +github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OpenPeeDeeP/depguard v1.0.0/go.mod h1:7/4sitnI9YlQgTLLk734QlzXT8DuHVnAyztLplQjk+o= github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= 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= @@ -24,11 +27,12 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/docker/distribution v0.0.0-20171011171712-7484e51bf6af/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v24.0.7+incompatible h1:Wo6l37AuwP3JaMnZa226lzVXGA3F9Ig1seQen0cKYlM= -github.com/docker/docker v24.0.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v24.0.9+incompatible h1:HPGzNmwfLZWdxHqK9/II92pyi1EpYKsAqcl4G0Of9v0= +github.com/docker/docker v24.0.9+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.1-0.20210727194412-58542c764a11 h1:IPrmumsT9t5BS7XcPhgsCTlkWbYg80SEXUzDpReaU6Y= github.com/docker/go-connections v0.4.1-0.20210727194412-58542c764a11/go.mod h1:a6bNUGTbQBsY6VRHTr4h/rkOXjl244DyRD0tx3fgq4Q= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= @@ -37,6 +41,7 @@ github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 h1:UhxFibDNY/bfvqU github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= github.com/emicklei/go-restful/v3 v3.10.2 h1:hIovbnmBTLjHXkqEBUz3HGpXZdM7ZrE9fJIZIqlJLqE= +github.com/emicklei/go-restful/v3 v3.10.2/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= @@ -46,6 +51,7 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7 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.7.0 h1:nJqP7uwL84RJInrohHfW0Fx3awjbm8qZeFv0nW9SYGc= +github.com/evanphx/json-patch/v5 v5.7.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= github.com/fatih/color v1.6.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/flowstack/go-jsonschema v0.1.1/go.mod h1:yL7fNggx1o8rm9RlgXv7hTBWxdBM0rVwpMwimd3F3N0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= @@ -58,13 +64,18 @@ github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbV 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-logr/zapr v1.2.4/go.mod h1:FyHWQIzQORZ0QVE1BtVHv3cKtNLuXsbNLtpuhNapBOA= github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= github.com/go-openapi/jsonpointer v0.20.0 h1:ESKJdU9ASRfaPNOPRx12IUyA1vn3R9GiE3KYD14BXdQ= +github.com/go-openapi/jsonpointer v0.20.0/go.mod h1:6PGzBjjIIumbLYysB73Klnms1mwnU4G3YHOECG3CedA= github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= +github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU= +github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/go-toolsmith/astcast v1.0.0/go.mod h1:mt2OdQTeAQcY4DQgPSArJjHCcOwlX+Wl/kwN+LbLGQ4= github.com/go-toolsmith/astcopy v1.0.0/go.mod h1:vrgyG+5Bxrnz4MZWPF+pI4R8h3qKRjjyvV/DSez4WVQ= github.com/go-toolsmith/astequal v0.0.0-20180903214952-dcb477bfacd6/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CYFJ99GVbS5lDKY= @@ -128,13 +139,17 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw 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/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/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-20230705174524-200ffdc848b8 h1:n6vlPhxsA+BW/XsS5+uqi7GyzaLa5MH7qlSLBZtRdiA= +github.com/google/pprof v0.0.0-20230705174524-200ffdc848b8/go.mod h1:Jh3hGz2jkYak8qXPD19ryItVnUgpgeqzdkY/D0EaeuA= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= +github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= @@ -148,6 +163,7 @@ github.com/heroku/docker-registry-client v0.0.0-20211012143308-9463674c8930 h1:m github.com/heroku/docker-registry-client v0.0.0-20211012143308-9463674c8930/go.mod h1:Yho0S7KhsnHQRCC5lDraYF1SsLMeWtf/tKdufKu3TJA= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= +github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= 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= @@ -167,6 +183,7 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN 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.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= 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= @@ -188,6 +205,7 @@ github.com/mitchellh/mapstructure v0.0.0-20180220230111-00c29f56e238/go.mod h1:F github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8= github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= github.com/moby/term v0.0.0-20221205130635-1aeaba878587 h1:HfkjXDfhgVaN5rmueG8cL8KKeFNecRCXFhaJ2qZ5SKA= +github.com/moby/term v0.0.0-20221205130635-1aeaba878587/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= 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= @@ -203,9 +221,11 @@ github.com/nbutton23/zxcvbn-go v0.0.0-20171102151520-eafdab6b0663/go.mod h1:o96d github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4= +github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.2/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.30.0 h1:hvMK7xYz4D3HapigLTeGdId/NcfQx1VHMJc60ew99+8= +github.com/onsi/gomega v1.30.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= @@ -217,15 +237,21 @@ 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/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_golang v1.17.0 h1:rl2sfwZMtSthVU752MqfjQozy7blglC+1SOtjMAMh+Q= +github.com/prometheus/client_golang v1.17.0/go.mod h1:VeL+gMmOAxkS2IqfCq0ZmHSL+LjWfWDUmp1mBz9JgUY= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.4.1-0.20230718164431-9a2bf3000d16 h1:v7DLqVdK4VrYkVD5diGdl4sxJurKJEMnODWRJlxV9oM= +github.com/prometheus/client_model v0.4.1-0.20230718164431-9a2bf3000d16/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY= +github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= github.com/prometheus/procfs v0.11.1 h1:xRC8Iq1yyca5ypa9n1EZnWZkt7dwcoRPQwX/5gwaUuI= +github.com/prometheus/procfs v0.11.1/go.mod h1:eesXgaPo1q7lBpVMoMy0ZOFTth9hBn4W/y0/p/ScXhY= github.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c/go.mod h1:5STLWrekHfjyYwxBRVRXNOSewLJ3PWfDJd1VyTS21fI= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= +github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= github.com/ryanuber/go-glob v0.0.0-20170128012129-256dc444b735/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= github.com/shirou/gopsutil v0.0.0-20180427012116-c95755e4bcd7/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc= @@ -261,6 +287,7 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ 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.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/timakin/bodyclose v0.0.0-20190721030226-87058b9bfcec/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk= github.com/ultraware/funlen v0.0.1/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lPbfaF6xhA= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= @@ -274,8 +301,11 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de 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/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= +go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= +go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -287,6 +317,7 @@ golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHl 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.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY= +golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20170915142106-8351a756f30f/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 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= @@ -308,6 +339,7 @@ golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= 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.13.0 h1:jDDenyj+WgFtmV3zYVoi8aE2BwtXFLWOA67ZfNWftiY= +golang.org/x/oauth2 v0.13.0/go.mod h1:/JMhi4ZRXAf4HG9LiNmxvk+45+96RUlVThiH8FzNBn0= 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= @@ -315,6 +347,7 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ 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.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ= +golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20171026204733-164713f0dfce/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -333,8 +366,10 @@ golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= +golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4= +golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= golang.org/x/text v0.0.0-20170915090833-1cbadb444a80/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 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= @@ -342,6 +377,7 @@ 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.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= 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-20170915040203-e531a2a1c15f/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -362,11 +398,13 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn 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.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc= +golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= 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.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw= +gomodules.xyz/jsonpatch/v2 v2.4.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= @@ -395,7 +433,8 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba 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.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= +google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= 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= @@ -424,14 +463,21 @@ gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= 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.6 h1:PBWu/lywJe2qQcshMjubzcBg7+XDZOo7O8JJAWuYtUo= +k8s.io/api v0.27.6/go.mod h1:AQYj0UsFCp3qJE7bOVnUuy4orCsXVkvHefnbYQiNWgk= k8s.io/apiextensions-apiserver v0.27.6 h1:mOwSBJtThZhpJr+8gEkc3wFDIjq87E3JspR5mtZxIg8= +k8s.io/apiextensions-apiserver v0.27.6/go.mod h1:AVNlLYRrESG5Poo6ASRUhY2pvoKPcNt8y/IuZ4lx3o8= k8s.io/apimachinery v0.27.6 h1:mGU8jmBq5o8mWBov+mLjdTBcU+etTE19waies4AQ6NE= +k8s.io/apimachinery v0.27.6/go.mod h1:XNfZ6xklnMCOGGFNqXG7bUrQCoR04dh/E7FprV6pb+E= k8s.io/client-go v0.27.6 h1:vzI8804gpUtpMCNaFjIFyJrifH7u//LJCJPy8fQuYQg= +k8s.io/client-go v0.27.6/go.mod h1:PMsXcDKiJTW7PHJ64oEsIUJF319wm+EFlCj76oE5QXM= k8s.io/component-base v0.27.6 h1:hF5WxX7Tpi9/dXAbLjPVkIA6CA6Pi6r9JOHyo0uCDYI= +k8s.io/component-base v0.27.6/go.mod h1:NvjLtaneUeb0GgMPpCBF+4LNB9GuhDHi16uUTjBhQfU= 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-20230525220651-2546d827e515 h1:OmK1d0WrkD3IPfkskvroRykOulHVHf0s0ZIFRjyt+UI= +k8s.io/kube-openapi v0.0.0-20230525220651-2546d827e515/go.mod h1:kzo02I3kQ4BTtEfVLaPbjvCkX97YqGve33wzlb3fofQ= k8s.io/utils v0.0.0-20230711102312-30195339c3c7 h1:ZgnF1KZsYxWIifwSNZFZgNtWE89WI5yiP5WwlfDoIyc= +k8s.io/utils v0.0.0-20230711102312-30195339c3c7/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc= mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4= mvdan.cc/unparam v0.0.0-20190209190245-fbb59629db34/go.mod h1:H6SUd1XjIs+qQCyskXg5OFSrilMRUkD8ePJpHKDPaeY= @@ -440,6 +486,7 @@ sigs.k8s.io/controller-runtime v0.15.0/go.mod h1:7ngYvp1MLT+9GeZ+6lH3LOlcHkp/+tz 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.3.0 h1:UZbZAZfX0wV2zr7YZorDz6GXROfDFj6LvqCRm4VUVKk= +sigs.k8s.io/structured-merge-diff/v4 v4.3.0/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0= diff --git a/controllers/builder/openshiftbuilder.go b/controllers/builder/openshiftbuilder.go index 79ada8fe1..55c1fc2db 100644 --- a/controllers/builder/openshiftbuilder.go +++ b/controllers/builder/openshiftbuilder.go @@ -117,8 +117,8 @@ func (o *openshiftBuilderManager) Schedule(build *operatorapi.SonataFlowBuild) e if err = o.addExternalResources(bc, workflow); err != nil { return err } - workflowproj.SetDefaultLabels(workflow, is) - workflowproj.SetDefaultLabels(workflow, bc) + workflowproj.SetMergedLabels(workflow, is) + workflowproj.SetMergedLabels(workflow, bc) if err = controllerutil.SetControllerReference(build, bc, o.buildManagerContext.client.Scheme()); err != nil { return err } diff --git a/controllers/platform/services/properties.go b/controllers/platform/services/properties.go index 02fc65002..1d9e784e4 100644 --- a/controllers/platform/services/properties.go +++ b/controllers/platform/services/properties.go @@ -24,14 +24,14 @@ import ( "net/url" "strings" - "github.com/apache/incubator-kie-kogito-serverless-operator/controllers/profiles" - "github.com/apache/incubator-kie-kogito-serverless-operator/controllers/workflowdef" "github.com/apache/incubator-kie-kogito-serverless-operator/log" "github.com/apache/incubator-kie-kogito-serverless-operator/utils" "k8s.io/klog/v2" operatorapi "github.com/apache/incubator-kie-kogito-serverless-operator/api/v1alpha08" + "github.com/apache/incubator-kie-kogito-serverless-operator/controllers/profiles" "github.com/apache/incubator-kie-kogito-serverless-operator/controllers/profiles/common/constants" + "github.com/apache/incubator-kie-kogito-serverless-operator/controllers/workflowdef" "github.com/magiconair/properties" ) @@ -162,21 +162,21 @@ func GenerateDataIndexWorkflowProperties(workflow *operatorapi.SonataFlow, platf props.Set(constants.KogitoProcessDefinitionsEventsEnabled, "false") props.Set(constants.KogitoProcessInstancesEventsEnabled, "false") di := NewDataIndexHandler(platform) - if workflow != nil && !profiles.IsDevProfile(workflow) && di.IsServiceEnabled() { - props.Set(constants.KogitoProcessDefinitionsEventsEnabled, "true") - props.Set(constants.KogitoProcessDefinitionsEventsErrorsEnabled, "true") - props.Set(constants.KogitoProcessInstancesEventsEnabled, "true") - props.Set(constants.KogitoDataIndexHealthCheckEnabled, "true") - di := NewDataIndexHandler(platform) - p, err := di.GenerateWorkflowProperties() - if err != nil { - return nil, err + if !profiles.IsDevProfile(workflow) && workflow != nil && workflow.Status.Services != nil && workflow.Status.Services.DataIndexRef != nil { + serviceBaseUrl := workflow.Status.Services.DataIndexRef.Url + if di.IsServiceEnabled() && len(serviceBaseUrl) > 0 { + props.Set(constants.KogitoProcessDefinitionsEventsEnabled, "true") + props.Set(constants.KogitoProcessInstancesEventsEnabled, "true") + props.Set(constants.KogitoProcessDefinitionsEventsErrorsEnabled, "true") + props.Set(constants.KogitoDataIndexHealthCheckEnabled, "true") + props.Set(constants.KogitoDataIndexURL, serviceBaseUrl) + props.Set(constants.KogitoProcessDefinitionsEventsURL, serviceBaseUrl+constants.KogitoProcessDefinitionsEventsPath) + props.Set(constants.KogitoProcessInstancesEventsURL, serviceBaseUrl+constants.KogitoProcessInstancesEventsPath) } - props.Merge(p) } props.Sort() - return props, nil + return props, nil } // GenerateJobServiceWorkflowProperties returns the set of application properties required for the workflow to interact @@ -188,16 +188,17 @@ func GenerateJobServiceWorkflowProperties(workflow *operatorapi.SonataFlow, plat props.Set(constants.JobServiceRequestEventsConnector, constants.QuarkusHTTP) props.Set(constants.JobServiceRequestEventsURL, fmt.Sprintf("%s://localhost/v2/jobs/events", constants.JobServiceURLProtocol)) js := NewJobServiceHandler(platform) - if workflow != nil && !profiles.IsDevProfile(workflow) && js.IsServiceEnabled() { - if workflowdef.HasTimeouts(workflow) { - props.Set(constants.KogitoJobServiceHealthCheckEnabled, "true") - } - p, err := js.GenerateWorkflowProperties() - if err != nil { - return nil, err + if !profiles.IsDevProfile(workflow) && workflow != nil && workflow.Status.Services != nil && workflow.Status.Services.JobServiceRef != nil { + serviceBaseUrl := workflow.Status.Services.JobServiceRef.Url + if js.IsServiceEnabled() && len(serviceBaseUrl) > 0 { + if workflowdef.HasTimeouts(workflow) { + props.Set(constants.KogitoJobServiceHealthCheckEnabled, "true") + } + props.Set(constants.KogitoJobServiceURL, serviceBaseUrl) + props.Set(constants.JobServiceRequestEventsURL, serviceBaseUrl+constants.JobServiceJobEventsPath) } - props.Merge(p) } props.Sort() + return props, nil } diff --git a/controllers/platform/services/services.go b/controllers/platform/services/services.go index 4b442c6a1..55e7e72aa 100644 --- a/controllers/platform/services/services.go +++ b/controllers/platform/services/services.go @@ -26,6 +26,7 @@ import ( "k8s.io/apimachinery/pkg/api/resource" operatorapi "github.com/apache/incubator-kie-kogito-serverless-operator/api/v1alpha08" + "github.com/apache/incubator-kie-kogito-serverless-operator/controllers/profiles" "github.com/apache/incubator-kie-kogito-serverless-operator/controllers/profiles/common/constants" "github.com/apache/incubator-kie-kogito-serverless-operator/controllers/profiles/common/persistence" "github.com/magiconair/properties" @@ -68,8 +69,6 @@ type PlatformServiceHandler interface { // MergePodSpec performs a merge with override between the podSpec argument and the expected values based on the service's pod template specification. The returning // object is the result of the merge MergePodSpec(podSpec corev1.PodSpec) (corev1.PodSpec, error) - // GenerateWorkflowProperties returns a property object that contains the service's application properties required by workflows - GenerateWorkflowProperties() (*properties.Properties, error) // GenerateServiceProperties returns a property object that contains the application properties required by the service deployment GenerateServiceProperties() (*properties.Properties, error) @@ -83,9 +82,11 @@ type PlatformServiceHandler interface { GetServiceBaseUrl() string // IsServiceEnabled returns true if the service is enabled in either the spec or the status.clusterPlatformRef. IsServiceEnabled() bool - // SetServiceUrlInStatus sets the service url in status. if reconciled instance does not have service set in spec AND + // SetServiceUrlInPlatformStatus sets the service url in the platform's status. if reconciled instance does not have service set in spec AND // if cluster referenced platform has said service enabled, use the cluster platform's service - SetServiceUrlInStatus(clusterRefPlatform *operatorapi.SonataFlowPlatform) + SetServiceUrlInPlatformStatus(clusterRefPlatform *operatorapi.SonataFlowPlatform) + // SetServiceUrlInWorkflowStatus sets the service url in a workflow's status. + SetServiceUrlInWorkflowStatus(workflow *operatorapi.SonataFlow) } type DataIndexHandler struct { @@ -116,7 +117,7 @@ func (d DataIndexHandler) GetServiceName() string { return fmt.Sprintf("%s-%s", d.platform.Name, constants.DataIndexServiceName) } -func (d DataIndexHandler) SetServiceUrlInStatus(clusterRefPlatform *operatorapi.SonataFlowPlatform) { +func (d DataIndexHandler) SetServiceUrlInPlatformStatus(clusterRefPlatform *operatorapi.SonataFlowPlatform) { psDI := NewDataIndexHandler(clusterRefPlatform) if !isServicesSet(d.platform) && psDI.IsServiceEnabledInSpec() { if d.platform.Status.ClusterPlatformRef != nil { @@ -130,6 +131,17 @@ func (d DataIndexHandler) SetServiceUrlInStatus(clusterRefPlatform *operatorapi. } } +func (d DataIndexHandler) SetServiceUrlInWorkflowStatus(workflow *operatorapi.SonataFlow) { + if !profiles.IsDevProfile(workflow) && d.IsServiceEnabled() { + if workflow.Status.Services == nil { + workflow.Status.Services = &operatorapi.PlatformServicesStatus{} + } + workflow.Status.Services.DataIndexRef = &operatorapi.PlatformServiceRefStatus{ + Url: d.GetServiceBaseUrl(), + } + } +} + func (d DataIndexHandler) IsServiceSetInSpec() bool { return isDataIndexSet(d.platform) } @@ -235,16 +247,6 @@ func (d DataIndexHandler) GetServiceCmName() string { return fmt.Sprintf("%s-props", d.GetServiceName()) } -func (d DataIndexHandler) GenerateWorkflowProperties() (*properties.Properties, error) { - props := properties.NewProperties() - if d.IsServiceEnabled() { - props.Set(constants.KogitoDataIndexURL, d.GetServiceBaseUrl()) - props.Set(constants.KogitoProcessDefinitionsEventsURL, d.GetServiceBaseUrl()+constants.KogitoProcessDefinitionsEventsPath) - props.Set(constants.KogitoProcessInstancesEventsURL, d.GetServiceBaseUrl()+constants.KogitoProcessInstancesEventsPath) - } - return props, nil -} - func (d DataIndexHandler) GenerateServiceProperties() (*properties.Properties, error) { props := properties.NewProperties() props.Set(constants.KogitoServiceURLProperty, d.GetLocalServiceBaseUrl()) @@ -284,7 +286,7 @@ func (j JobServiceHandler) GetServiceCmName() string { return fmt.Sprintf("%s-props", j.GetServiceName()) } -func (j JobServiceHandler) SetServiceUrlInStatus(clusterRefPlatform *operatorapi.SonataFlowPlatform) { +func (j JobServiceHandler) SetServiceUrlInPlatformStatus(clusterRefPlatform *operatorapi.SonataFlowPlatform) { psJS := NewJobServiceHandler(clusterRefPlatform) if !isServicesSet(j.platform) && psJS.IsServiceEnabledInSpec() { if j.platform.Status.ClusterPlatformRef != nil { @@ -298,6 +300,17 @@ func (j JobServiceHandler) SetServiceUrlInStatus(clusterRefPlatform *operatorapi } } +func (j JobServiceHandler) SetServiceUrlInWorkflowStatus(workflow *operatorapi.SonataFlow) { + if !profiles.IsDevProfile(workflow) && j.IsServiceEnabled() { + if workflow.Status.Services == nil { + workflow.Status.Services = &operatorapi.PlatformServicesStatus{} + } + workflow.Status.Services.JobServiceRef = &operatorapi.PlatformServiceRefStatus{ + Url: j.GetServiceBaseUrl(), + } + } +} + func (j JobServiceHandler) IsServiceSetInSpec() bool { return isJobServiceSet(j.platform) } @@ -416,13 +429,13 @@ func (j JobServiceHandler) GenerateServiceProperties() (*properties.Properties, return props, nil } -func (j JobServiceHandler) GenerateWorkflowProperties() (*properties.Properties, error) { - props := properties.NewProperties() - if j.IsServiceEnabled() { - props.Set(constants.KogitoJobServiceURL, j.GetServiceBaseUrl()) - props.Set(constants.JobServiceRequestEventsURL, j.GetServiceBaseUrl()+constants.JobServiceJobEventsPath) - } - return props, nil +func SetServiceUrlsInWorkflowStatus(pl *operatorapi.SonataFlowPlatform, workflow *operatorapi.SonataFlow) { + tpsDI := NewDataIndexHandler(pl) + tpsJS := NewJobServiceHandler(pl) + + workflow.Status.Services = nil + tpsDI.SetServiceUrlInWorkflowStatus(workflow) + tpsJS.SetServiceUrlInWorkflowStatus(workflow) } func isDataIndexEnabled(platform *operatorapi.SonataFlowPlatform) bool { diff --git a/controllers/profiles/common/object_creators.go b/controllers/profiles/common/object_creators.go index 4b28e9806..61ea65db9 100644 --- a/controllers/profiles/common/object_creators.go +++ b/controllers/profiles/common/object_creators.go @@ -75,7 +75,7 @@ const ( // DeploymentCreator is an objectCreator for a base Kubernetes Deployments for profiles that need to deploy the workflow on a vanilla deployment. // It serves as a basis for a basic Quarkus Java application, expected to listen on http 8080. func DeploymentCreator(workflow *operatorapi.SonataFlow, plf *operatorapi.SonataFlowPlatform) (client.Object, error) { - lbl := workflowproj.GetDefaultLabels(workflow) + lbl := workflowproj.GetMergedLabels(workflow) deployment := &appsv1.Deployment{ ObjectMeta: metav1.ObjectMeta{ @@ -192,7 +192,7 @@ func defaultContainer(workflow *operatorapi.SonataFlow, plf *operatorapi.SonataF // ServiceCreator is an objectCreator for a basic Service aiming a vanilla Kubernetes Deployment. // It maps the default HTTP port (80) to the target Java application webserver on port 8080. func ServiceCreator(workflow *operatorapi.SonataFlow) (client.Object, error) { - lbl := workflowproj.GetDefaultLabels(workflow) + lbl := workflowproj.GetMergedLabels(workflow) service := &corev1.Service{ ObjectMeta: metav1.ObjectMeta{ @@ -216,7 +216,7 @@ func ServiceCreator(workflow *operatorapi.SonataFlow) (client.Object, error) { // SinkBindingCreator is an ObjectsCreator for SinkBinding. // It will create v1.SinkBinding based on events defined in workflow. func SinkBindingCreator(workflow *operatorapi.SonataFlow) (client.Object, error) { - lbl := workflowproj.GetDefaultLabels(workflow) + lbl := workflowproj.GetMergedLabels(workflow) // skip if no produced event is found if workflow.Spec.Sink == nil || !workflowdef.ContainsEventKind(workflow, cncfmodel.EventKindProduced) { @@ -253,7 +253,7 @@ func SinkBindingCreator(workflow *operatorapi.SonataFlow) (client.Object, error) // It will create a list of eventingv1.Trigger based on events defined in workflow. func TriggersCreator(workflow *operatorapi.SonataFlow) ([]client.Object, error) { var resultObjects []client.Object - lbl := workflowproj.GetDefaultLabels(workflow) + lbl := workflowproj.GetMergedLabels(workflow) //consumed events := workflow.Spec.Flow.Events diff --git a/controllers/profiles/common/object_creators_test.go b/controllers/profiles/common/object_creators_test.go index 236aa025c..7a35bd481 100644 --- a/controllers/profiles/common/object_creators_test.go +++ b/controllers/profiles/common/object_creators_test.go @@ -192,6 +192,8 @@ func Test_ensureWorkflowSinkBindingIsCreated(t *testing.T) { assert.NotNil(t, reflectSinkBinding.Spec) assert.NotEmpty(t, reflectSinkBinding.Spec.Sink) assert.Equal(t, reflectSinkBinding.Spec.Sink.Ref.Kind, "Broker") + assert.NotNil(t, reflectSinkBinding.GetLabels()) + assert.Equal(t, reflectSinkBinding.ObjectMeta.Labels, map[string]string{"app": "vet", "sonataflow.org/workflow-app": "vet"}) } func Test_ensureWorkflowTriggersAreCreated(t *testing.T) { @@ -204,6 +206,8 @@ func Test_ensureWorkflowTriggersAreCreated(t *testing.T) { assert.Len(t, triggers, 2) for _, trigger := range triggers { assert.Contains(t, []string{"vet-vetappointmentrequestreceived-trigger", "vet-vetappointmentinfo-trigger"}, trigger.GetName()) + assert.NotNil(t, trigger.GetLabels()) + assert.Equal(t, trigger.GetLabels(), map[string]string{"app": "vet", "sonataflow.org/workflow-app": "vet"}) } } diff --git a/controllers/profiles/common/properties/application_test.go b/controllers/profiles/common/properties/application_test.go index 7133db17e..93700bafa 100644 --- a/controllers/profiles/common/properties/application_test.go +++ b/controllers/profiles/common/properties/application_test.go @@ -30,6 +30,7 @@ import ( "github.com/apache/incubator-kie-kogito-serverless-operator/api/metadata" operatorapi "github.com/apache/incubator-kie-kogito-serverless-operator/api/v1alpha08" "github.com/apache/incubator-kie-kogito-serverless-operator/controllers/discovery" + "github.com/apache/incubator-kie-kogito-serverless-operator/controllers/platform/services" "github.com/apache/incubator-kie-kogito-serverless-operator/controllers/profiles/common/constants" "github.com/magiconair/properties" @@ -211,6 +212,8 @@ func Test_appPropertyHandler_WithServicesWithUserOverrides(t *testing.T) { }, } + services.SetServiceUrlsInWorkflowStatus(platform, workflow) + assert.Nil(t, workflow.Status.Services) props, err := NewAppPropertyHandler(workflow, platform) assert.NoError(t, err) generatedProps, propsErr := properties.LoadString(props.WithUserProperties(userProperties).Build()) @@ -235,7 +238,11 @@ func Test_appPropertyHandler_WithServicesWithUserOverrides(t *testing.T) { assert.Equal(t, "false", generatedProps.GetString(constants.KogitoUserTasksEventsEnabled, "")) // prod profile enables config of outgoing events url - workflow.SetAnnotations(map[string]string{metadata.Profile: string(metadata.ProdProfile)}) + workflow.SetAnnotations(map[string]string{metadata.Profile: string(metadata.PreviewProfile)}) + services.SetServiceUrlsInWorkflowStatus(platform, workflow) + assert.NotNil(t, workflow.Status.Services) + assert.NotNil(t, workflow.Status.Services.JobServiceRef) + assert.NotNil(t, workflow.Status.Services.DataIndexRef) props, err = NewAppPropertyHandler(workflow, platform) assert.NoError(t, err) generatedProps, propsErr = properties.LoadString(props.WithUserProperties(userProperties).Build()) @@ -259,6 +266,10 @@ func Test_appPropertyHandler_WithServicesWithUserOverrides(t *testing.T) { // disabling data index bypasses config of outgoing events url platform.Spec.Services.DataIndex.Enabled = nil + services.SetServiceUrlsInWorkflowStatus(platform, workflow) + assert.NotNil(t, workflow.Status.Services) + assert.NotNil(t, workflow.Status.Services.JobServiceRef) + assert.Nil(t, workflow.Status.Services.DataIndexRef) props, err = NewAppPropertyHandler(workflow, platform) assert.NoError(t, err) generatedProps, propsErr = properties.LoadString(props.WithUserProperties(userProperties).Build()) @@ -277,6 +288,8 @@ func Test_appPropertyHandler_WithServicesWithUserOverrides(t *testing.T) { // disabling job service bypasses config of outgoing events url platform.Spec.Services.JobService.Enabled = nil + services.SetServiceUrlsInWorkflowStatus(platform, workflow) + assert.Nil(t, workflow.Status.Services) props, err = NewAppPropertyHandler(workflow, platform) assert.NoError(t, err) generatedProps, propsErr = properties.LoadString(props.WithUserProperties(userProperties).Build()) @@ -303,6 +316,7 @@ var _ = Describe("Platform properties", func() { DescribeTable("only job services when the spec", func(wf *operatorapi.SonataFlow, plfm *operatorapi.SonataFlowPlatform, expectedProperties *properties.Properties) { + services.SetServiceUrlsInWorkflowStatus(plfm, wf) handler, err := NewAppPropertyHandler(wf, plfm) Expect(err).NotTo(HaveOccurred()) p, err := properties.LoadString(handler.Build()) @@ -315,7 +329,7 @@ var _ = Describe("Platform properties", func() { generatePlatform(setJobServiceEnabledValue(&disabled), setPlatformNamespace("default"), setPlatformName("foo")), generateJobServiceWorkflowDevProperties()), Entry("has enabled field set to false and workflow with production profile", - generateFlow(setProfileInFlow(metadata.ProdProfile), setWorkflowName("foo"), setWorkflowNamespace("default")), + generateFlow(setProfileInFlow(metadata.PreviewProfile), setWorkflowName("foo"), setWorkflowNamespace("default")), generatePlatform(setJobServiceEnabledValue(&disabled), setPlatformNamespace("default"), setPlatformName("foo")), generateJobServiceWorkflowDevProperties()), Entry("has enabled field undefined and workflow with dev profile", @@ -323,7 +337,7 @@ var _ = Describe("Platform properties", func() { generatePlatform(setJobServiceEnabledValue(nil), setPlatformNamespace("default"), setPlatformName("foo")), generateJobServiceWorkflowDevProperties()), Entry("has enabled field undefined and workflow with production profile", - generateFlow(setProfileInFlow(metadata.ProdProfile), setWorkflowName("foo"), setWorkflowNamespace("default")), + generateFlow(setProfileInFlow(metadata.PreviewProfile), setWorkflowName("foo"), setWorkflowNamespace("default")), generatePlatform(setJobServiceEnabledValue(nil), setPlatformNamespace("default"), setPlatformName("foo")), generateJobServiceWorkflowDevProperties()), Entry("has enabled field set to true and workflow with dev profile", @@ -331,7 +345,7 @@ var _ = Describe("Platform properties", func() { generatePlatform(setJobServiceEnabledValue(&enabled), setPlatformName("foo"), setPlatformNamespace("default")), generateJobServiceWorkflowDevProperties()), Entry("has enabled field set to true and workflow with production profile", - generateFlow(setProfileInFlow(metadata.ProdProfile), setWorkflowName("foo"), setWorkflowNamespace("default")), + generateFlow(setProfileInFlow(metadata.PreviewProfile), setWorkflowName("foo"), setWorkflowNamespace("default")), generatePlatform(setJobServiceEnabledValue(&enabled), setPlatformName("foo"), setPlatformNamespace("default")), generateJobServiceWorkflowProductionProperties()), Entry("has enabled field set to true and workflow with no profile", @@ -350,6 +364,7 @@ var _ = Describe("Platform properties", func() { DescribeTable("only data index service when the spec", func(wf *operatorapi.SonataFlow, plfm *operatorapi.SonataFlowPlatform, expectedProperties *properties.Properties) { + services.SetServiceUrlsInWorkflowStatus(plfm, wf) handler, err := NewAppPropertyHandler(wf, plfm) Expect(err).NotTo(HaveOccurred()) p, err := properties.LoadString(handler.Build()) @@ -362,7 +377,7 @@ var _ = Describe("Platform properties", func() { generatePlatform(setDataIndexEnabledValue(&disabled), setPlatformNamespace("default"), setPlatformName("foo")), generateDataIndexWorkflowDevProperties()), Entry("has enabled field set to false and workflow with production profile", - generateFlow(setProfileInFlow(metadata.ProdProfile), setWorkflowName("foo"), setWorkflowNamespace("default")), + generateFlow(setProfileInFlow(metadata.PreviewProfile), setWorkflowName("foo"), setWorkflowNamespace("default")), generatePlatform(setDataIndexEnabledValue(&disabled), setPlatformNamespace("default"), setPlatformName("foo")), generateDataIndexWorkflowDevProperties()), Entry("has enabled field undefined and workflow with dev profile", @@ -370,7 +385,7 @@ var _ = Describe("Platform properties", func() { generatePlatform(setDataIndexEnabledValue(nil), setPlatformNamespace("default"), setPlatformName("foo")), generateDataIndexWorkflowDevProperties()), Entry("has enabled field undefined and workflow with production profile", - generateFlow(setProfileInFlow(metadata.ProdProfile), setWorkflowName("foo"), setWorkflowNamespace("default")), + generateFlow(setProfileInFlow(metadata.PreviewProfile), setWorkflowName("foo"), setWorkflowNamespace("default")), generatePlatform(setDataIndexEnabledValue(nil), setPlatformNamespace("default"), setPlatformName("foo")), generateDataIndexWorkflowDevProperties()), Entry("has enabled field set to true and workflow with dev profile", @@ -378,7 +393,7 @@ var _ = Describe("Platform properties", func() { generatePlatform(setDataIndexEnabledValue(&enabled), setPlatformNamespace("default"), setPlatformName("foo")), generateDataIndexWorkflowDevProperties()), Entry("has enabled field set to true and workflow with production profile", - generateFlow(setProfileInFlow(metadata.ProdProfile), setWorkflowName("foo"), setWorkflowNamespace("default")), + generateFlow(setProfileInFlow(metadata.PreviewProfile), setWorkflowName("foo"), setWorkflowNamespace("default")), generatePlatform(setDataIndexEnabledValue(&enabled), setPlatformNamespace("default"), setPlatformName("foo")), generateDataIndexWorkflowProductionProperties()), Entry("has enabled field set to false and workflow with no profile", @@ -396,6 +411,7 @@ var _ = Describe("Platform properties", func() { ) DescribeTable("both Data Index and Job Services are available and", func(wf *operatorapi.SonataFlow, plfm *operatorapi.SonataFlowPlatform, expectedProperties *properties.Properties) { + services.SetServiceUrlsInWorkflowStatus(plfm, wf) handler, err := NewAppPropertyHandler(wf, plfm) Expect(err).NotTo(HaveOccurred()) p, err := properties.LoadString(handler.Build()) @@ -408,7 +424,7 @@ var _ = Describe("Platform properties", func() { generatePlatform(setPlatformNamespace("default"), setPlatformName("foo")), generateDataIndexAndJobServiceWorkflowDevProperties()), Entry("both are undefined and workflow in prod profile", - generateFlow(setProfileInFlow(metadata.ProdProfile), setWorkflowName("foo"), setWorkflowNamespace("default")), + generateFlow(setProfileInFlow(metadata.PreviewProfile), setWorkflowName("foo"), setWorkflowNamespace("default")), generatePlatform(setPlatformNamespace("default"), setPlatformName("foo")), generateDataIndexAndJobServiceWorkflowDevProperties()), Entry("both have enabled field set to true and workflow with dev profile", @@ -416,7 +432,7 @@ var _ = Describe("Platform properties", func() { generatePlatform(setJobServiceEnabledValue(&enabled), setDataIndexEnabledValue(&enabled), setPlatformName("foo"), setPlatformNamespace("default")), generateDataIndexAndJobServiceWorkflowDevProperties()), Entry("both have enabled field set to true and workflow with production profile", - generateFlow(setProfileInFlow(metadata.ProdProfile), setWorkflowName("foo"), setWorkflowNamespace("default")), + generateFlow(setProfileInFlow(metadata.PreviewProfile), setWorkflowName("foo"), setWorkflowNamespace("default")), generatePlatform(setJobServiceEnabledValue(&enabled), setDataIndexEnabledValue(&enabled), setPlatformName("foo"), setPlatformNamespace("default")), generateDataIndexAndJobServiceWorkflowProductionProperties()), Entry("both have enabled field undefined and workflow with dev profile", @@ -424,7 +440,7 @@ var _ = Describe("Platform properties", func() { generatePlatform(setJobServiceEnabledValue(nil), setDataIndexEnabledValue(nil), setPlatformName("foo"), setPlatformNamespace("default")), generateDataIndexAndJobServiceWorkflowDevProperties()), Entry("both have enabled field undefined and workflow with production profile", - generateFlow(setProfileInFlow(metadata.ProdProfile), setWorkflowName("foo"), setWorkflowNamespace("default")), + generateFlow(setProfileInFlow(metadata.PreviewProfile), setWorkflowName("foo"), setWorkflowNamespace("default")), generatePlatform(setJobServiceEnabledValue(nil), setDataIndexEnabledValue(nil), setPlatformName("foo"), setPlatformNamespace("default"), setJobServiceJDBC("jdbc:postgresql://postgres:5432/sonataflow?currentSchema=myschema")), generateDataIndexAndJobServiceWorkflowDevProperties()), Entry("both have enabled field set to false and workflow with dev profile", @@ -432,7 +448,7 @@ var _ = Describe("Platform properties", func() { generatePlatform(setJobServiceEnabledValue(&disabled), setDataIndexEnabledValue(&disabled), setPlatformName("foo"), setPlatformNamespace("default"), setJobServiceJDBC("jdbc:postgresql://postgres:5432/sonataflow?currentSchema=myschema")), generateDataIndexAndJobServiceWorkflowDevProperties()), Entry("both have enabled field set to false and workflow with production profile", - generateFlow(setProfileInFlow(metadata.ProdProfile), setWorkflowName("foo"), setWorkflowNamespace("default")), + generateFlow(setProfileInFlow(metadata.PreviewProfile), setWorkflowName("foo"), setWorkflowNamespace("default")), generatePlatform(setJobServiceEnabledValue(&disabled), setDataIndexEnabledValue(&disabled), setPlatformName("foo"), setPlatformNamespace("default"), setJobServiceJDBC("jdbc:postgresql://postgres:5432/sonataflow?currentSchema=myschema")), generateDataIndexAndJobServiceWorkflowDevProperties()), Entry("both have enabled field set to false and workflow with no profile", diff --git a/controllers/profiles/common/reconciler.go b/controllers/profiles/common/reconciler.go index b2800005b..8af936995 100644 --- a/controllers/profiles/common/reconciler.go +++ b/controllers/profiles/common/reconciler.go @@ -26,6 +26,8 @@ import ( "k8s.io/client-go/rest" "github.com/apache/incubator-kie-kogito-serverless-operator/controllers/discovery" + "github.com/apache/incubator-kie-kogito-serverless-operator/controllers/platform" + "github.com/apache/incubator-kie-kogito-serverless-operator/controllers/platform/services" "k8s.io/client-go/tools/record" @@ -49,7 +51,12 @@ type StateSupport struct { // PerformStatusUpdate updates the SonataFlow Status conditions func (s *StateSupport) PerformStatusUpdate(ctx context.Context, workflow *operatorapi.SonataFlow) (bool, error) { var err error + pl, err := platform.GetActivePlatform(ctx, s.C, workflow.Namespace) + if err != nil { + return false, err + } workflow.Status.ObservedGeneration = workflow.Generation + services.SetServiceUrlsInWorkflowStatus(pl, workflow) if err = s.C.Status().Update(ctx, workflow); err != nil { klog.V(log.E).ErrorS(err, "Failed to update Workflow status") return false, err diff --git a/controllers/profiles/dev/object_creators_dev.go b/controllers/profiles/dev/object_creators_dev.go index 63b7b8fe3..0d947c0f3 100644 --- a/controllers/profiles/dev/object_creators_dev.go +++ b/controllers/profiles/dev/object_creators_dev.go @@ -80,7 +80,6 @@ func workflowDefConfigMapCreator(workflow *operatorapi.SonataFlow) (client.Objec if err != nil { return nil, err } - workflowproj.SetDefaultLabels(workflow, configMap) return configMap, nil } diff --git a/controllers/profiles/dev/object_creators_dev_test.go b/controllers/profiles/dev/object_creators_dev_test.go index 8209940a2..25fdc8ee2 100644 --- a/controllers/profiles/dev/object_creators_dev_test.go +++ b/controllers/profiles/dev/object_creators_dev_test.go @@ -41,4 +41,7 @@ func Test_ensureWorkflowDevServiceIsExposed(t *testing.T) { assert.NotNil(t, reflectService.Spec.Type) assert.NotEmpty(t, reflectService.Spec.Type) assert.Equal(t, reflectService.Spec.Type, v1.ServiceTypeNodePort) + assert.NotNil(t, reflectService.ObjectMeta) + assert.NotNil(t, reflectService.ObjectMeta.Labels) + assert.Equal(t, reflectService.ObjectMeta.Labels, map[string]string{"test": "test", "app": "greeting", "sonataflow.org/workflow-app": "greeting"}) } diff --git a/controllers/profiles/factory/factory.go b/controllers/profiles/factory/factory.go index b459c4fe2..d54b0df33 100644 --- a/controllers/profiles/factory/factory.go +++ b/controllers/profiles/factory/factory.go @@ -20,29 +20,30 @@ package factory import ( + "github.com/apache/incubator-kie-kogito-serverless-operator/controllers/profiles/gitops" + "github.com/apache/incubator-kie-kogito-serverless-operator/controllers/profiles/preview" + "github.com/apache/incubator-kie-kogito-serverless-operator/log" "k8s.io/client-go/rest" "k8s.io/client-go/tools/record" + "k8s.io/klog/v2" "sigs.k8s.io/controller-runtime/pkg/client" "github.com/apache/incubator-kie-kogito-serverless-operator/api/metadata" operatorapi "github.com/apache/incubator-kie-kogito-serverless-operator/api/v1alpha08" "github.com/apache/incubator-kie-kogito-serverless-operator/controllers/profiles" "github.com/apache/incubator-kie-kogito-serverless-operator/controllers/profiles/dev" - "github.com/apache/incubator-kie-kogito-serverless-operator/controllers/profiles/prod" ) const ( - defaultProfile = metadata.ProdProfile - // internal profile - opsProfile metadata.ProfileType = "prod_for_ops" + defaultProfile = metadata.PreviewProfile ) type reconcilerBuilder func(client client.Client, cfg *rest.Config, recorder record.EventRecorder) profiles.ProfileReconciler var profileBuilders = map[metadata.ProfileType]reconcilerBuilder{ - metadata.ProdProfile: prod.NewProfileReconciler, - metadata.DevProfile: dev.NewProfileReconciler, - opsProfile: prod.NewProfileForOpsReconciler, + metadata.PreviewProfile: preview.NewProfileReconciler, + metadata.DevProfile: dev.NewProfileReconciler, + metadata.GitOpsProfile: gitops.NewProfileForOpsReconciler, } func profileBuilder(workflow *operatorapi.SonataFlow) reconcilerBuilder { @@ -50,10 +51,18 @@ func profileBuilder(workflow *operatorapi.SonataFlow) reconcilerBuilder { if len(profile) == 0 { profile = defaultProfile.String() } - if profile == metadata.ProdProfile.String() && workflow.HasContainerSpecImage() { - return profileBuilders[opsProfile] + // keep backward compatibility + if profile == metadata.ProdProfile.String() { + klog.V(log.W).Infof("Profile %s is deprecated, please use '%s' instead.", metadata.ProdProfile, metadata.PreviewProfile) + profile = metadata.PreviewProfile.String() + } + // Enforce GitOps profile if the .spec.podTemplate.container.image is set in the Preview profile. + if (profile == metadata.PreviewProfile.String() || profile == metadata.ProdProfile.String()) && workflow.HasContainerSpecImage() { + workflow.Annotations[metadata.Profile] = metadata.GitOpsProfile.String() + return profileBuilders[metadata.GitOpsProfile] } if _, ok := profileBuilders[metadata.ProfileType(profile)]; !ok { + klog.V(log.W).Infof("Profile %s not supported, please use '%s' or '%s'. Falling back to %s", profile, metadata.PreviewProfile, metadata.DevProfile, defaultProfile) return profileBuilders[defaultProfile] } return profileBuilders[metadata.ProfileType(profile)] diff --git a/controllers/profiles/gitops/alias.go b/controllers/profiles/gitops/alias.go new file mode 100644 index 000000000..97b183475 --- /dev/null +++ b/controllers/profiles/gitops/alias.go @@ -0,0 +1,25 @@ +// Copyright 2024 Apache Software Foundation (ASF) +// +// 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 gitops + +import "github.com/apache/incubator-kie-kogito-serverless-operator/controllers/profiles/preview" + +// Aliases to preview profile package to avoid cluttering this package with references to preview profile. +// It makes easier to maintain and understand where it comes the references. + +var newDeploymentReconciler = preview.NewDeploymentReconciler +var newObjectEnsurers = preview.NewObjectEnsurers + +type objectEnsurers = preview.ObjectEnsurers diff --git a/controllers/profiles/gitops/profile_gitops.go b/controllers/profiles/gitops/profile_gitops.go new file mode 100644 index 000000000..41c0e8a1c --- /dev/null +++ b/controllers/profiles/gitops/profile_gitops.go @@ -0,0 +1,56 @@ +// Copyright 2024 Apache Software Foundation (ASF) +// +// 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 gitops + +import ( + "github.com/apache/incubator-kie-kogito-serverless-operator/api/metadata" + "github.com/apache/incubator-kie-kogito-serverless-operator/controllers/discovery" + "github.com/apache/incubator-kie-kogito-serverless-operator/controllers/profiles" + "github.com/apache/incubator-kie-kogito-serverless-operator/controllers/profiles/common" + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/record" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +var _ profiles.ProfileReconciler = &gitOpsProfile{} + +type gitOpsProfile struct { + common.Reconciler +} + +// NewProfileForOpsReconciler creates an alternative prod profile that won't require to build the workflow image in order to deploy +// the workflow application. It assumes that the image has been built somewhere else. +func NewProfileForOpsReconciler(client client.Client, cfg *rest.Config, recorder record.EventRecorder) profiles.ProfileReconciler { + support := &common.StateSupport{ + C: client, + Cfg: cfg, + Catalog: discovery.NewServiceCatalogForConfig(client, cfg), + Recorder: recorder, + } + // the reconciliation state machine + stateMachine := common.NewReconciliationStateMachine( + &ensureBuildSkipped{StateSupport: support}, + &followDeployWorkflowState{StateSupport: support, ensurers: newObjectEnsurers(support)}, + ) + reconciler := &gitOpsProfile{ + Reconciler: common.NewReconciler(support, stateMachine), + } + + return reconciler +} + +func (p gitOpsProfile) GetProfile() metadata.ProfileType { + return metadata.GitOpsProfile +} diff --git a/controllers/profiles/gitops/profile_gitops_test.go b/controllers/profiles/gitops/profile_gitops_test.go new file mode 100644 index 000000000..9287cbc2b --- /dev/null +++ b/controllers/profiles/gitops/profile_gitops_test.go @@ -0,0 +1,68 @@ +// Copyright 2024 Apache Software Foundation (ASF) +// +// 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 gitops + +import ( + "context" + "testing" + + "github.com/apache/incubator-kie-kogito-serverless-operator/api" + operatorapi "github.com/apache/incubator-kie-kogito-serverless-operator/api/v1alpha08" + "github.com/apache/incubator-kie-kogito-serverless-operator/test" + "github.com/stretchr/testify/assert" + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + "k8s.io/client-go/rest" + clientruntime "sigs.k8s.io/controller-runtime/pkg/client" +) + +func Test_Reconciler_ProdOps(t *testing.T) { + workflow := test.GetBaseSonataFlowWithProdOpsProfile(t.Name()) + workflow.Spec.PodTemplate.PodSpec.InitContainers = append(workflow.Spec.PodTemplate.PodSpec.InitContainers, corev1.Container{ + Name: "check-postgres", + Image: "registry.access.redhat.com/ubi9/ubi-micro:latest", + Command: []string{"sh", "-c", "until (echo 1 > /dev/tcp/postgres.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local/5432) >/dev/null 2>&1; do echo \"Waiting for postgres server\"; sleep 3; done;"}, + }) + client := test.NewSonataFlowClientBuilder(). + WithRuntimeObjects(workflow). + WithStatusSubresource(workflow, &operatorapi.SonataFlowBuild{}).Build() + result, err := NewProfileForOpsReconciler(client, &rest.Config{}, test.NewFakeRecorder()).Reconcile(context.TODO(), workflow) + assert.NoError(t, err) + + assert.NotNil(t, result.RequeueAfter) + assert.True(t, workflow.Status.GetCondition(api.BuiltConditionType).IsFalse()) + assert.Equal(t, api.BuildSkippedReason, workflow.Status.GetCondition(api.BuiltConditionType).Reason) + // We need the deployment controller to tell us that the workflow is ready + // Since we don't have it in a mocked env, the result must be ready == false + assert.False(t, workflow.Status.IsReady()) + + // Reconcile again to run the deployment handler + result, err = NewProfileForOpsReconciler(client, &rest.Config{}, test.NewFakeRecorder()).Reconcile(context.TODO(), workflow) + assert.NoError(t, err) + + // Let's check for the right creation of the workflow (one CM volume, one container with a custom image) + deployment := &appsv1.Deployment{} + err = client.Get(context.TODO(), clientruntime.ObjectKeyFromObject(workflow), deployment) + assert.NoError(t, err) + + assert.Len(t, deployment.Spec.Template.Spec.Volumes, 1) + assert.Len(t, deployment.Spec.Template.Spec.Containers, 1) + assert.Len(t, deployment.Spec.Template.Spec.InitContainers, 1) + assert.Len(t, deployment.Spec.Template.Spec.Containers[0].VolumeMounts, 1) + + assert.NotNil(t, deployment.ObjectMeta) + assert.NotNil(t, deployment.ObjectMeta.Labels) + assert.Equal(t, deployment.ObjectMeta.Labels, map[string]string{"test": "test", "app": "simple", "sonataflow.org/workflow-app": "simple"}) +} diff --git a/controllers/profiles/prod/states_prod_nobuild.go b/controllers/profiles/gitops/states_gitops.go similarity index 97% rename from controllers/profiles/prod/states_prod_nobuild.go rename to controllers/profiles/gitops/states_gitops.go index 46449ce1f..b355be4dd 100644 --- a/controllers/profiles/prod/states_prod_nobuild.go +++ b/controllers/profiles/gitops/states_gitops.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package prod +package gitops import ( "context" @@ -62,7 +62,7 @@ func (f *followDeployWorkflowState) CanReconcile(workflow *operatorapi.SonataFlo } func (f *followDeployWorkflowState) Do(ctx context.Context, workflow *operatorapi.SonataFlow) (ctrl.Result, []client.Object, error) { - return newDeploymentReconciler(f.StateSupport, f.ensurers).reconcile(ctx, workflow) + return newDeploymentReconciler(f.StateSupport, f.ensurers).Reconcile(ctx, workflow) } func (f *followDeployWorkflowState) PostReconcile(ctx context.Context, workflow *operatorapi.SonataFlow) error { diff --git a/controllers/profiles/prod/deployment_handler.go b/controllers/profiles/preview/deployment_handler.go similarity index 92% rename from controllers/profiles/prod/deployment_handler.go rename to controllers/profiles/preview/deployment_handler.go index af999e5aa..5fce26885 100644 --- a/controllers/profiles/prod/deployment_handler.go +++ b/controllers/profiles/preview/deployment_handler.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package prod +package preview import ( "context" @@ -31,23 +31,23 @@ import ( "github.com/apache/incubator-kie-kogito-serverless-operator/utils" ) -type deploymentReconciler struct { +type DeploymentReconciler struct { *common.StateSupport - ensurers *objectEnsurers + ensurers *ObjectEnsurers } -func newDeploymentReconciler(stateSupport *common.StateSupport, ensurer *objectEnsurers) *deploymentReconciler { - return &deploymentReconciler{ +func NewDeploymentReconciler(stateSupport *common.StateSupport, ensurer *ObjectEnsurers) *DeploymentReconciler { + return &DeploymentReconciler{ StateSupport: stateSupport, ensurers: ensurer, } } -func (d *deploymentReconciler) reconcile(ctx context.Context, workflow *operatorapi.SonataFlow) (reconcile.Result, []client.Object, error) { +func (d *DeploymentReconciler) Reconcile(ctx context.Context, workflow *operatorapi.SonataFlow) (reconcile.Result, []client.Object, error) { return d.reconcileWithBuiltImage(ctx, workflow, "") } -func (d *deploymentReconciler) reconcileWithBuiltImage(ctx context.Context, workflow *operatorapi.SonataFlow, image string) (reconcile.Result, []client.Object, error) { +func (d *DeploymentReconciler) reconcileWithBuiltImage(ctx context.Context, workflow *operatorapi.SonataFlow, image string) (reconcile.Result, []client.Object, error) { pl, _ := platform.GetActivePlatform(ctx, d.C, workflow.Namespace) userPropsCM, _, err := d.ensurers.userPropsConfigMap.Ensure(ctx, workflow) if err != nil { @@ -110,7 +110,7 @@ func (d *deploymentReconciler) reconcileWithBuiltImage(ctx context.Context, work return result, objs, nil } -func (d *deploymentReconciler) getDeploymentMutateVisitors( +func (d *DeploymentReconciler) getDeploymentMutateVisitors( workflow *operatorapi.SonataFlow, plf *operatorapi.SonataFlowPlatform, image string, diff --git a/controllers/profiles/prod/deployment_handler_test.go b/controllers/profiles/preview/deployment_handler_test.go similarity index 91% rename from controllers/profiles/prod/deployment_handler_test.go rename to controllers/profiles/preview/deployment_handler_test.go index a133b9635..d70436d7b 100644 --- a/controllers/profiles/prod/deployment_handler_test.go +++ b/controllers/profiles/preview/deployment_handler_test.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package prod +package preview import ( "context" @@ -38,9 +38,9 @@ func Test_CheckPodTemplateChangesReflectDeployment(t *testing.T) { WithStatusSubresource(workflow). Build() stateSupport := fakeReconcilerSupport(client) - handler := newDeploymentReconciler(stateSupport, newObjectEnsurers(stateSupport)) + handler := NewDeploymentReconciler(stateSupport, NewObjectEnsurers(stateSupport)) - result, objects, err := handler.reconcile(context.TODO(), workflow) + result, objects, err := handler.Reconcile(context.TODO(), workflow) assert.NoError(t, err) assert.NotEmpty(t, objects) assert.True(t, result.Requeue) @@ -49,7 +49,7 @@ func Test_CheckPodTemplateChangesReflectDeployment(t *testing.T) { expectedImg := "quay.io/apache/my-new-workflow:1.0.0" workflow.Spec.PodTemplate.Container.Image = expectedImg utilruntime.Must(client.Update(context.TODO(), workflow)) - result, objects, err = handler.reconcile(context.TODO(), workflow) + result, objects, err = handler.Reconcile(context.TODO(), workflow) assert.NoError(t, err) assert.NotEmpty(t, objects) assert.True(t, result.Requeue) @@ -71,9 +71,9 @@ func Test_CheckDeploymentRolloutAfterCMChange(t *testing.T) { WithStatusSubresource(workflow). Build() stateSupport := fakeReconcilerSupport(client) - handler := newDeploymentReconciler(stateSupport, newObjectEnsurers(stateSupport)) + handler := NewDeploymentReconciler(stateSupport, NewObjectEnsurers(stateSupport)) - result, objects, err := handler.reconcile(context.TODO(), workflow) + result, objects, err := handler.Reconcile(context.TODO(), workflow) assert.NoError(t, err) assert.NotEmpty(t, objects) assert.True(t, result.Requeue) @@ -108,7 +108,7 @@ func Test_CheckDeploymentRolloutAfterCMChange(t *testing.T) { props.MustSet("test.property", "test.value") userPropsCM.Data[workflowproj.ApplicationPropertiesFileName] = props.String() utilruntime.Must(client.Update(context.TODO(), userPropsCM)) - result, objects, err = handler.reconcile(context.TODO(), workflow) + result, objects, err = handler.Reconcile(context.TODO(), workflow) assert.NoError(t, err) assert.NotEmpty(t, objects) assert.True(t, result.Requeue) @@ -133,9 +133,9 @@ func Test_CheckDeploymentUnchangedAfterCMChangeOtherKeys(t *testing.T) { WithStatusSubresource(workflow). Build() stateSupport := fakeReconcilerSupport(client) - handler := newDeploymentReconciler(stateSupport, newObjectEnsurers(stateSupport)) + handler := NewDeploymentReconciler(stateSupport, NewObjectEnsurers(stateSupport)) - result, objects, err := handler.reconcile(context.TODO(), workflow) + result, objects, err := handler.Reconcile(context.TODO(), workflow) assert.NoError(t, err) assert.NotEmpty(t, objects) assert.True(t, result.Requeue) @@ -167,7 +167,7 @@ func Test_CheckDeploymentUnchangedAfterCMChangeOtherKeys(t *testing.T) { userPropsCM.Data["other.key"] = "useless.key = value" utilruntime.Must(client.Update(context.TODO(), userPropsCM)) - result, objects, err = handler.reconcile(context.TODO(), workflow) + result, objects, err = handler.Reconcile(context.TODO(), workflow) assert.NoError(t, err) assert.NotEmpty(t, objects) assert.True(t, result.Requeue) diff --git a/controllers/profiles/prod/object_creators_prod.go b/controllers/profiles/preview/object_creators_preview.go similarity index 97% rename from controllers/profiles/prod/object_creators_prod.go rename to controllers/profiles/preview/object_creators_preview.go index 02328e9b4..903cd7418 100644 --- a/controllers/profiles/prod/object_creators_prod.go +++ b/controllers/profiles/preview/object_creators_preview.go @@ -17,7 +17,7 @@ * under the License. */ -package prod +package preview import ( "fmt" @@ -85,8 +85,7 @@ func mountProdConfigMapsMutateVisitor(workflow *operatorapi.SonataFlow, userProp kubeutil.AddOrReplaceVolumeMount(idx, &deployment.Spec.Template.Spec, kubeutil.VolumeMount(constants.ConfigMapWorkflowPropsVolumeName, true, quarkusProdConfigMountPath)) - kubeutil.AnnotateDeploymentConfigChecksum(workflow, deployment, userPropsCM, managedPropsCM) - return nil + return kubeutil.AnnotateDeploymentConfigChecksum(workflow, deployment, userPropsCM, managedPropsCM) } } } diff --git a/controllers/profiles/prod/profile_prod.go b/controllers/profiles/preview/profile_preview.go similarity index 69% rename from controllers/profiles/prod/profile_prod.go rename to controllers/profiles/preview/profile_preview.go index b33532685..a4afea9b1 100644 --- a/controllers/profiles/prod/profile_prod.go +++ b/controllers/profiles/preview/profile_preview.go @@ -17,7 +17,7 @@ * under the License. */ -package prod +package preview import ( "time" @@ -34,9 +34,9 @@ import ( "github.com/apache/incubator-kie-kogito-serverless-operator/controllers/profiles/common" ) -var _ profiles.ProfileReconciler = &prodProfile{} +var _ profiles.ProfileReconciler = &previewProfile{} -type prodProfile struct { +type previewProfile struct { common.Reconciler } @@ -48,18 +48,19 @@ const ( quarkusProdConfigMountPath = "/deployments/config" ) -// objectEnsurers is a struct for the objects that ReconciliationState needs to create in the platform for the Production profile. +// ObjectEnsurers is a struct for the objects that ReconciliationState needs to create in the platform for the Production profile. // ReconciliationState that needs access to it must include this struct as an attribute and initialize it in the profile builder. -// Use newObjectEnsurers to facilitate building this struct -type objectEnsurers struct { +// Use NewObjectEnsurers to facilitate building this struct +type ObjectEnsurers struct { deployment common.ObjectEnsurerWithPlatform service common.ObjectEnsurer userPropsConfigMap common.ObjectEnsurer managedPropsConfigMap common.ObjectEnsurerWithPlatform } -func newObjectEnsurers(support *common.StateSupport) *objectEnsurers { - return &objectEnsurers{ +// NewObjectEnsurers common.ObjectEnsurer(s) for the preview profile. +func NewObjectEnsurers(support *common.StateSupport) *ObjectEnsurers { + return &ObjectEnsurers{ deployment: common.NewObjectEnsurerWithPlatform(support.C, common.DeploymentCreator), service: common.NewObjectEnsurer(support.C, common.ServiceCreator), userPropsConfigMap: common.NewObjectEnsurer(support.C, common.UserPropsConfigMapCreator), @@ -80,36 +81,15 @@ func NewProfileReconciler(client client.Client, cfg *rest.Config, recorder recor stateMachine := common.NewReconciliationStateMachine( &newBuilderState{StateSupport: support}, &followBuildStatusState{StateSupport: support}, - &deployWithBuildWorkflowState{StateSupport: support, ensurers: newObjectEnsurers(support)}, + &deployWithBuildWorkflowState{StateSupport: support, ensurers: NewObjectEnsurers(support)}, ) - reconciler := &prodProfile{ + reconciler := &previewProfile{ Reconciler: common.NewReconciler(support, stateMachine), } return reconciler } -// NewProfileForOpsReconciler creates an alternative prod profile that won't require to build the workflow image in order to deploy -// the workflow application. It assumes that the image has been built somewhere else. -func NewProfileForOpsReconciler(client client.Client, cfg *rest.Config, recorder record.EventRecorder) profiles.ProfileReconciler { - support := &common.StateSupport{ - C: client, - Cfg: cfg, - Catalog: discovery.NewServiceCatalogForConfig(client, cfg), - Recorder: recorder, - } - // the reconciliation state machine - stateMachine := common.NewReconciliationStateMachine( - &ensureBuildSkipped{StateSupport: support}, - &followDeployWorkflowState{StateSupport: support, ensurers: newObjectEnsurers(support)}, - ) - reconciler := &prodProfile{ - Reconciler: common.NewReconciler(support, stateMachine), - } - - return reconciler -} - -func (p prodProfile) GetProfile() metadata.ProfileType { - return metadata.ProdProfile +func (p previewProfile) GetProfile() metadata.ProfileType { + return metadata.PreviewProfile } diff --git a/controllers/profiles/prod/profile_prod_test.go b/controllers/profiles/preview/profile_preview_test.go similarity index 79% rename from controllers/profiles/prod/profile_prod_test.go rename to controllers/profiles/preview/profile_preview_test.go index 5ca93a97f..cc518db03 100644 --- a/controllers/profiles/prod/profile_prod_test.go +++ b/controllers/profiles/preview/profile_preview_test.go @@ -17,7 +17,7 @@ * under the License. */ -package prod +package preview import ( "context" @@ -35,45 +35,6 @@ import ( clientruntime "sigs.k8s.io/controller-runtime/pkg/client" ) -var ( - emptyPlatform = &operatorapi.SonataFlowPlatform{} -) - -func Test_Reconciler_ProdOps(t *testing.T) { - workflow := test.GetBaseSonataFlowWithProdOpsProfile(t.Name()) - workflow.Spec.PodTemplate.PodSpec.InitContainers = append(workflow.Spec.PodTemplate.PodSpec.InitContainers, corev1.Container{ - Name: "check-postgres", - Image: "registry.access.redhat.com/ubi9/ubi-micro:latest", - Command: []string{"sh", "-c", "until (echo 1 > /dev/tcp/postgres.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local/5432) >/dev/null 2>&1; do echo \"Waiting for postgres server\"; sleep 3; done;"}, - }) - client := test.NewSonataFlowClientBuilder(). - WithRuntimeObjects(workflow). - WithStatusSubresource(workflow, &operatorapi.SonataFlowBuild{}).Build() - result, err := NewProfileForOpsReconciler(client, &rest.Config{}, test.NewFakeRecorder()).Reconcile(context.TODO(), workflow) - assert.NoError(t, err) - - assert.NotNil(t, result.RequeueAfter) - assert.True(t, workflow.Status.GetCondition(api.BuiltConditionType).IsFalse()) - assert.Equal(t, api.BuildSkippedReason, workflow.Status.GetCondition(api.BuiltConditionType).Reason) - // We need the deployment controller to tell us that the workflow is ready - // Since we don't have it in a mocked env, the result must be ready == false - assert.False(t, workflow.Status.IsReady()) - - // Reconcile again to run the deployment handler - result, err = NewProfileForOpsReconciler(client, &rest.Config{}, test.NewFakeRecorder()).Reconcile(context.TODO(), workflow) - assert.NoError(t, err) - - // Let's check for the right creation of the workflow (one CM volume, one container with a custom image) - deployment := &appsv1.Deployment{} - err = client.Get(context.TODO(), clientruntime.ObjectKeyFromObject(workflow), deployment) - assert.NoError(t, err) - - assert.Len(t, deployment.Spec.Template.Spec.Volumes, 1) - assert.Len(t, deployment.Spec.Template.Spec.Containers, 1) - assert.Len(t, deployment.Spec.Template.Spec.InitContainers, 1) - assert.Len(t, deployment.Spec.Template.Spec.Containers[0].VolumeMounts, 1) -} - func Test_Reconciler_ProdCustomPod(t *testing.T) { workflow := test.GetBaseSonataFlowWithProdProfile(t.Name()) workflow.Spec.PodTemplate.PodSpec.InitContainers = append(workflow.Spec.PodTemplate.PodSpec.InitContainers, corev1.Container{ @@ -100,6 +61,9 @@ func Test_Reconciler_ProdCustomPod(t *testing.T) { assert.Len(t, deployment.Spec.Template.Spec.Containers, 1) assert.Len(t, deployment.Spec.Template.Spec.InitContainers, 1) assert.Len(t, deployment.Spec.Template.Spec.Containers[0].VolumeMounts, 1) + assert.NotNil(t, deployment.ObjectMeta) + assert.NotNil(t, deployment.ObjectMeta.Labels) + assert.Equal(t, deployment.ObjectMeta.Labels, map[string]string{"test": "test", "app": "greeting", "sonataflow.org/workflow-app": "greeting"}) } func Test_reconcilerProdBuildConditions(t *testing.T) { @@ -172,7 +136,7 @@ func Test_deployWorkflowReconciliationHandler_handleObjects(t *testing.T) { Build() handler := &deployWithBuildWorkflowState{ StateSupport: fakeReconcilerSupport(client), - ensurers: newObjectEnsurers(&common.StateSupport{C: client}), + ensurers: NewObjectEnsurers(&common.StateSupport{C: client}), } result, objects, err := handler.Do(context.TODO(), workflow) assert.Greater(t, result.RequeueAfter, int64(0)) @@ -201,7 +165,7 @@ func Test_GenerationAnnotationCheck(t *testing.T) { handler := &deployWithBuildWorkflowState{ StateSupport: fakeReconcilerSupport(client), - ensurers: newObjectEnsurers(&common.StateSupport{C: client}), + ensurers: NewObjectEnsurers(&common.StateSupport{C: client}), } result, objects, err := handler.Do(context.TODO(), workflow) assert.Greater(t, result.RequeueAfter, int64(time.Second)) @@ -220,7 +184,7 @@ func Test_GenerationAnnotationCheck(t *testing.T) { // reconcile handler = &deployWithBuildWorkflowState{ StateSupport: fakeReconcilerSupport(client), - ensurers: newObjectEnsurers(&common.StateSupport{C: client}), + ensurers: NewObjectEnsurers(&common.StateSupport{C: client}), } result, objects, err = handler.Do(context.TODO(), workflowChanged) assert.NoError(t, err) diff --git a/controllers/profiles/prod/states_prod.go b/controllers/profiles/preview/states_preview.go similarity index 98% rename from controllers/profiles/prod/states_prod.go rename to controllers/profiles/preview/states_preview.go index feb30dca6..933820e8d 100644 --- a/controllers/profiles/prod/states_prod.go +++ b/controllers/profiles/preview/states_preview.go @@ -17,7 +17,7 @@ * under the License. */ -package prod +package preview import ( "context" @@ -151,7 +151,7 @@ func (h *followBuildStatusState) PostReconcile(ctx context.Context, workflow *op type deployWithBuildWorkflowState struct { *common.StateSupport - ensurers *objectEnsurers + ensurers *ObjectEnsurers deploymentVisitors []common.MutateVisitor } @@ -189,7 +189,7 @@ func (h *deployWithBuildWorkflowState) Do(ctx context.Context, workflow *operato } // didn't change, business as usual - return newDeploymentReconciler(h.StateSupport, h.ensurers).reconcileWithBuiltImage(ctx, workflow, build.Status.ImageTag) + return NewDeploymentReconciler(h.StateSupport, h.ensurers).reconcileWithBuiltImage(ctx, workflow, build.Status.ImageTag) } func (h *deployWithBuildWorkflowState) PostReconcile(ctx context.Context, workflow *operatorapi.SonataFlow) error { diff --git a/controllers/sonataflowplatform_controller.go b/controllers/sonataflowplatform_controller.go index a26db2fbe..ff36a8aeb 100644 --- a/controllers/sonataflowplatform_controller.go +++ b/controllers/sonataflowplatform_controller.go @@ -205,10 +205,10 @@ func (r *SonataFlowPlatformReconciler) SonataFlowPlatformUpdateStatus(ctx contex if sfcPlatform.Spec.Capabilities != nil && contains(sfcPlatform.Spec.Capabilities.Workflows, clusterplatform.PlatformServices) { tpsDI := services.NewDataIndexHandler(target) - tpsDI.SetServiceUrlInStatus(sfPlatform) + tpsDI.SetServiceUrlInPlatformStatus(sfPlatform) tpsJS := services.NewJobServiceHandler(target) - tpsJS.SetServiceUrlInStatus(sfPlatform) + tpsJS.SetServiceUrlInPlatformStatus(sfPlatform) } } else { target.Status.ClusterPlatformRef = nil diff --git a/controllers/workflowdef/configmap.go b/controllers/workflowdef/configmap.go index af9140635..698398321 100644 --- a/controllers/workflowdef/configmap.go +++ b/controllers/workflowdef/configmap.go @@ -23,6 +23,8 @@ import ( "context" "path" + "github.com/apache/incubator-kie-kogito-serverless-operator/workflowproj" + corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" @@ -47,6 +49,7 @@ func CreateNewConfigMap(workflow *operatorapi.SonataFlow) (*corev1.ConfigMap, er ObjectMeta: metav1.ObjectMeta{ Name: workflow.Name, Namespace: workflow.Namespace, + Labels: workflowproj.GetMergedLabels(workflow), }, Data: map[string]string{GetWorkflowDefFileName(workflow): string(workflowDef)}, }, nil diff --git a/go.mod b/go.mod index 0dba2eeea..4f650cf7b 100644 --- a/go.mod +++ b/go.mod @@ -122,7 +122,7 @@ require ( google.golang.org/genproto/googleapis/api v0.0.0-20231002182017-d307bd883b97 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20231009173412-8bfb1ae86b6c // indirect google.golang.org/grpc v1.58.3 // indirect - google.golang.org/protobuf v1.31.0 // indirect + google.golang.org/protobuf v1.33.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 422a7db53..86d6dfce3 100644 --- a/go.sum +++ b/go.sum @@ -1115,8 +1115,8 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= -google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= +google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= 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= diff --git a/go.work.sum b/go.work.sum index ac93bf1bb..378d3f740 100644 --- a/go.work.sum +++ b/go.work.sum @@ -704,8 +704,6 @@ github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI= github.com/cloudevents/conformance v0.2.0 h1:NvSXOKlagcsOWMEbi8U7Ex/0oQ4JZE1HQ45bnxYf2zk= github.com/cloudevents/sdk-go/observability/opencensus/v2 v2.4.1 h1:UHjY9+DJyjELyFA8vU/KHHXix1F1z7QLFskzdJZkP+0= -github.com/cloudevents/sdk-go/v2 v2.15.2 h1:54+I5xQEnI73RBhWHxbI1XJcqOFOVJN85vb41+8mHUc= -github.com/cloudevents/sdk-go/v2 v2.15.2/go.mod h1:lL7kSWAE/V8VI4Wh0jbL2v/jvqsm6tjmaQBSvxcv4uE= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4 h1:hzAQntlaYRkVSFEfj9OTWlVV1H155FMD8BTKktLv0QI= github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= @@ -1806,6 +1804,8 @@ google.golang.org/grpc v1.58.2/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSs google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0 h1:M1YKkFIboKNieVO5DLUEVzQfGwJD30Nv2jfUgzb5UcE= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v1.29.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/airbrake/gobrake.v2 v2.0.9 h1:7z2uVWwn7oVeeugY1DtlPAy5H+KYgB1KeKTnqjNatLo= gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= gopkg.in/cheggaaa/pb.v1 v1.0.25 h1:Ev7yu1/f6+d+b3pi5vPdRPc6nNtP1umSfcWiEfRqv6I= diff --git a/hack/local/run-e2e.sh b/hack/local/run-e2e.sh index 0e5261b62..a048fad7d 100755 --- a/hack/local/run-e2e.sh +++ b/hack/local/run-e2e.sh @@ -20,11 +20,12 @@ # You must have minikube installed MINIKUBE_PROFILE=${1:-minikube} echo "Using minikube profile ${MINIKUBE_PROFILE}" +export OPERATOR_IMAGE_NAME=localhost/kogito-serverless-operator:0.0.1 # clean up previous runs make undeploy ignore-not-found=true +make deploy IMG="${OPERATOR_IMAGE_NAME}" -export OPERATOR_IMAGE_NAME=localhost/kogito-serverless-operator:0.0.1 eval "$(minikube -p "${MINIKUBE_PROFILE}" docker-env)" if ! make docker-build IMG="${OPERATOR_IMAGE_NAME}"; then echo "Failure: Failed to build image, exiting " >&2 diff --git a/operator.yaml b/operator.yaml index fb73c1011..939c060a5 100644 --- a/operator.yaml +++ b/operator.yaml @@ -16762,8 +16762,7 @@ spec: Data Index service properties: url: - description: Url displays the base url of a cluster-wide - service + description: Url displays the base url of the service type: string type: object jobServiceRef: @@ -16771,8 +16770,7 @@ spec: Job Service properties: url: - description: Url displays the base url of a cluster-wide - service + description: Url displays the base url of the service type: string type: object type: object @@ -26283,6 +26281,27 @@ spec: description: keeps track of how many failure recovers a given workflow had so far type: integer + services: + description: Services displays which platform services are being used + by this workflow + properties: + dataIndexRef: + description: DataIndexRef displays information on the cluster-wide + Data Index service + properties: + url: + description: Url displays the base url of the service + type: string + type: object + jobServiceRef: + description: JobServiceRef displays information on the cluster-wide + Job Service + properties: + url: + description: Url displays the base url of the service + type: string + type: object + type: object type: object type: object served: true diff --git a/test/e2e/clusterplatform_test.go b/test/e2e/clusterplatform_test.go index d0b545f69..a2e316eb4 100644 --- a/test/e2e/clusterplatform_test.go +++ b/test/e2e/clusterplatform_test.go @@ -25,6 +25,7 @@ import ( "path/filepath" "time" + "github.com/apache/incubator-kie-kogito-serverless-operator/api/metadata" "github.com/apache/incubator-kie-kogito-serverless-operator/controllers/platform/services" "github.com/apache/incubator-kie-kogito-serverless-operator/controllers/profiles/common/constants" "github.com/apache/incubator-kie-kogito-serverless-operator/test" @@ -74,7 +75,6 @@ var _ = Describe("Validate a clusterplatform", Ordered, func() { } }) var _ = Context("with supporting services enabled", func() { - DescribeTable("against a platform in a separate namespace", func(testcaseDir string, profile string, persistenceType string, withServices bool) { By("Deploy the SonataFlowPlatform CR") var manifests []byte @@ -147,6 +147,19 @@ var _ = Describe("Validate a clusterplatform", Ordered, func() { returnedValue, _ := utils.Run(cmd) return returnedValue }, 20*time.Minute, 5).Should(Equal([]byte("''"))) + + dataIndexServiceUrl := services.GenerateServiceURL(constants.KogitoServiceURLProtocol, targetNamespace2, "sonataflow-platform-"+constants.DataIndexServiceName) + jobServiceUrl := services.GenerateServiceURL(constants.KogitoServiceURLProtocol, targetNamespace2, "sonataflow-platform-"+constants.JobServiceName) + EventuallyWithOffset(1, func() []byte { + cmd = exec.Command("kubectl", "get", "sf", "-n", targetNamespace2, "callbackstatetimeouts", "-o", "jsonpath='{.status.services.dataIndexRef.url}'") + returnedValue, _ := utils.Run(cmd) + return returnedValue + }, 20*time.Minute, 5).Should(Equal([]byte("'" + dataIndexServiceUrl + "'"))) + EventuallyWithOffset(1, func() []byte { + cmd = exec.Command("kubectl", "get", "sf", "-n", targetNamespace2, "callbackstatetimeouts", "-o", "jsonpath='{.status.services.jobServiceRef.url}'") + returnedValue, _ := utils.Run(cmd) + return returnedValue + }, 20*time.Minute, 5).Should(Equal([]byte("'" + jobServiceUrl + "'"))) } else { EventuallyWithOffset(1, func() error { var err error @@ -180,13 +193,23 @@ var _ = Describe("Validate a clusterplatform", Ordered, func() { returnedValue, _ := utils.Run(cmd) return returnedValue }, 20*time.Minute, 5).Should(Equal([]byte("'" + jobServiceUrl + "'"))) + EventuallyWithOffset(1, func() []byte { + cmd = exec.Command("kubectl", "get", "sf", "-n", targetNamespace2, "callbackstatetimeouts", "-o", "jsonpath='{.status.services.dataIndexRef.url}'") + returnedValue, _ := utils.Run(cmd) + return returnedValue + }, 20*time.Minute, 5).Should(Equal([]byte("'" + dataIndexServiceUrl + "'"))) + EventuallyWithOffset(1, func() []byte { + cmd = exec.Command("kubectl", "get", "sf", "-n", targetNamespace2, "callbackstatetimeouts", "-o", "jsonpath='{.status.services.jobServiceRef.url}'") + returnedValue, _ := utils.Run(cmd) + return returnedValue + }, 20*time.Minute, 5).Should(Equal([]byte("'" + jobServiceUrl + "'"))) } cmd = exec.Command("kubectl", "delete", "SonataFlowClusterPlatform", "cluster", "--wait") _, err = utils.Run(cmd) Expect(err).NotTo(HaveOccurred()) }, - Entry("without services configured", test.GetSonataFlowE2EPlatformNoServicesDirectory(), dev, ephemeral, false), - Entry("with services configured", test.GetSonataFlowE2EPlatformServicesDirectory(), dev, ephemeral, true), + Entry("without services configured", test.GetSonataFlowE2EPlatformNoServicesDirectory(), metadata.PreviewProfile.String(), ephemeral, false), + Entry("with services configured", test.GetSonataFlowE2EPlatformServicesDirectory(), metadata.PreviewProfile.String(), "ephemeral-with-workflow", true), ) DescribeTable("against a platform in a separate namespace", func(testcaseDir string, profile string, persistenceType string) { @@ -264,8 +287,8 @@ var _ = Describe("Validate a clusterplatform", Ordered, func() { _, err = utils.Run(cmd) Expect(err).NotTo(HaveOccurred()) }, - Entry("with only Data Index configured", test.GetSonataFlowE2EPlatformServicesDirectory(), dev, ephemeralDataIndex), - Entry("with only Job Service configured", test.GetSonataFlowE2EPlatformServicesDirectory(), dev, ephemeralJobService), + Entry("with only Data Index configured", test.GetSonataFlowE2EPlatformServicesDirectory(), metadata.PreviewProfile.String(), ephemeralDataIndex), + Entry("with only Job Service configured", test.GetSonataFlowE2EPlatformServicesDirectory(), metadata.PreviewProfile.String(), ephemeralJobService), ) }) }) diff --git a/test/e2e/helpers.go b/test/e2e/helpers.go index d2dd8e83b..104afa315 100644 --- a/test/e2e/helpers.go +++ b/test/e2e/helpers.go @@ -18,12 +18,10 @@ import ( "encoding/json" "fmt" "net/url" - "os" "os/exec" "strconv" "strings" - "github.com/apache/incubator-kie-kogito-serverless-operator/test" "github.com/apache/incubator-kie-kogito-serverless-operator/test/utils" //nolint:golint @@ -35,9 +33,6 @@ import ( . "github.com/onsi/gomega" ) -// sonataflow_operator_namespace store the ns where the Operator and Operand will be executed -const sonataflow_operator_namespace = "sonataflow-operator-system" - type health struct { Status string `json:"status"` Checks []check `json:"checks"` @@ -162,22 +157,3 @@ func verifyWorkflowIsAddressable(workflowName string, targetNamespace string) bo return false } } - -const ( - minikubePlatform = "minikube" - openshiftPlatform = "openshift" -) - -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/platform_test.go b/test/e2e/platform_test.go index 00f51039c..c2c86d082 100644 --- a/test/e2e/platform_test.go +++ b/test/e2e/platform_test.go @@ -23,6 +23,7 @@ import ( "strings" "time" + "github.com/apache/incubator-kie-kogito-serverless-operator/api/metadata" "github.com/apache/incubator-kie-kogito-serverless-operator/test" "github.com/apache/incubator-kie-kogito-serverless-operator/test/utils" @@ -38,8 +39,6 @@ import ( const ( ephemeral = "ephemeral" postgreSQL = "postgreSQL" - dev = "dev" - production = "prod" clusterWideEphemeral = "cluster-wide-ephemeral" ephemeralDataIndex = "ephemeral-data-index" ephemeralJobService = "ephemeral-job-service" @@ -82,7 +81,7 @@ var _ = Describe("Validate the persistence", Ordered, func() { cmd.Stdin = bytes.NewBuffer(manifests) _, err := utils.Run(cmd) Expect(err).NotTo(HaveOccurred()) - By("Wait for SonatatFlowPlatform CR to complete deployment") + By("Wait for SonataFlowPlatform CR to complete deployment") // wait for service deployments to be ready EventuallyWithOffset(1, func() error { cmd = exec.Command("kubectl", "wait", "pod", "-n", targetNamespace, "-l", "app=sonataflow-platform", "--for", "condition=Ready", "--timeout=5s") @@ -117,10 +116,10 @@ var _ = Describe("Validate the persistence", Ordered, func() { }, 10*time.Minute, 5).Should(BeTrue()) } }, - Entry("with both Job Service and Data Index and ephemeral persistence and the workflow in a dev profile", test.GetSonataFlowE2EPlatformServicesDirectory(), dev, ephemeral), - Entry("with both Job Service and Data Index and ephemeral persistence and the workflow in a production profile", test.GetSonataFlowE2EPlatformServicesDirectory(), production, ephemeral), - Entry("with both Job Service and Data Index and postgreSQL persistence and the workflow in a dev profile", test.GetSonataFlowE2EPlatformServicesDirectory(), dev, postgreSQL), - Entry("with both Job Service and Data Index and postgreSQL persistence and the workflow in a production profile", test.GetSonataFlowE2EPlatformServicesDirectory(), production, postgreSQL), + Entry("with both Job Service and Data Index and ephemeral persistence and the workflow in a dev profile", test.GetSonataFlowE2EPlatformServicesDirectory(), metadata.DevProfile.String(), ephemeral), + Entry("with both Job Service and Data Index and ephemeral persistence and the workflow in a preview profile", test.GetSonataFlowE2EPlatformServicesDirectory(), metadata.PreviewProfile.String(), ephemeral), + Entry("with both Job Service and Data Index and postgreSQL persistence and the workflow in a dev profile", test.GetSonataFlowE2EPlatformServicesDirectory(), metadata.DevProfile.String(), postgreSQL), + Entry("with both Job Service and Data Index and postgreSQL persistence and the workflow in a preview profile", test.GetSonataFlowE2EPlatformServicesDirectory(), metadata.PreviewProfile.String(), postgreSQL), ) }) diff --git a/test/e2e/workflow_test.go b/test/e2e/workflow_test.go index 30a0ae2fd..0750cd996 100644 --- a/test/e2e/workflow_test.go +++ b/test/e2e/workflow_test.go @@ -51,7 +51,7 @@ var _ = Describe("SonataFlow Operator", Ordered, func() { }) AfterEach(func() { // Remove resources in test namespace - if !CurrentGinkgoTestDescription().Failed && len(targetNamespace) > 0 { + if !CurrentSpecReport().Failed() && len(targetNamespace) > 0 { cmd := exec.Command("kubectl", "delete", "namespace", targetNamespace, "--wait") _, err := utils.Run(cmd) Expect(err).NotTo(HaveOccurred()) @@ -61,7 +61,7 @@ var _ = Describe("SonataFlow Operator", Ordered, func() { Describe("ensure that Operator and Operand(s) can run in restricted namespaces", func() { projectDir, _ := utils.GetProjectDir() - It("should successfully deploy the Simple Workflow in prod ops mode and verify if it's running", func() { + It("should successfully deploy the Simple Workflow in GitOps mode and verify if it's running", func() { By("creating an instance of the SonataFlow Operand(CR)") EventuallyWithOffset(1, func() error { cmd := exec.Command("kubectl", "apply", "-f", filepath.Join(projectDir, @@ -81,7 +81,7 @@ var _ = Describe("SonataFlow Operator", Ordered, func() { }, 3*time.Minute, time.Second).Should(Succeed()) }) - It("should successfully deploy the Greeting Workflow in prod mode and verify if it's running", func() { + It("should successfully deploy the Greeting Workflow in preview mode and verify if it's running", func() { By("creating external resources DataInputSchema configMap") EventuallyWithOffset(1, func() error { cmd := exec.Command("kubectl", "apply", "-f", filepath.Join(projectDir, diff --git a/test/testdata/platform/noservices/dev/ephemeral/02-sonataflow_platform.yaml b/test/testdata/platform/noservices/preview/ephemeral/02-sonataflow_platform.yaml similarity index 100% rename from test/testdata/platform/noservices/dev/ephemeral/02-sonataflow_platform.yaml rename to test/testdata/platform/noservices/preview/ephemeral/02-sonataflow_platform.yaml diff --git a/test/testdata/platform/services/dev/ephemeral-data-index/kustomization.yaml b/test/testdata/platform/noservices/preview/ephemeral/kustomization.yaml similarity index 92% rename from test/testdata/platform/services/dev/ephemeral-data-index/kustomization.yaml rename to test/testdata/platform/noservices/preview/ephemeral/kustomization.yaml index 5441bfce8..20286ada0 100644 --- a/test/testdata/platform/services/dev/ephemeral-data-index/kustomization.yaml +++ b/test/testdata/platform/noservices/preview/ephemeral/kustomization.yaml @@ -14,6 +14,7 @@ resources: - 02-sonataflow_platform.yaml +- sonataflow/03-sonataflow_callbackstatetimeouts.sw.yaml sortOptions: order: fifo diff --git a/test/testdata/platform/services/prod/ephemeral/sonataflow/03-sonataflow_callbackstatetimeouts.sw.yaml b/test/testdata/platform/noservices/preview/ephemeral/sonataflow/03-sonataflow_callbackstatetimeouts.sw.yaml similarity index 100% rename from test/testdata/platform/services/prod/ephemeral/sonataflow/03-sonataflow_callbackstatetimeouts.sw.yaml rename to test/testdata/platform/noservices/preview/ephemeral/sonataflow/03-sonataflow_callbackstatetimeouts.sw.yaml diff --git a/test/testdata/platform/services/dev/cluster-wide-ephemeral/01-sonataflow_clusterplatform.yaml b/test/testdata/platform/services/preview/cluster-wide-ephemeral/01-sonataflow_clusterplatform.yaml similarity index 100% rename from test/testdata/platform/services/dev/cluster-wide-ephemeral/01-sonataflow_clusterplatform.yaml rename to test/testdata/platform/services/preview/cluster-wide-ephemeral/01-sonataflow_clusterplatform.yaml diff --git a/test/testdata/platform/services/dev/cluster-wide-ephemeral/02-sonataflow_platform.yaml b/test/testdata/platform/services/preview/cluster-wide-ephemeral/02-sonataflow_platform.yaml similarity index 100% rename from test/testdata/platform/services/dev/cluster-wide-ephemeral/02-sonataflow_platform.yaml rename to test/testdata/platform/services/preview/cluster-wide-ephemeral/02-sonataflow_platform.yaml diff --git a/test/testdata/platform/services/dev/cluster-wide-ephemeral/kustomization.yaml b/test/testdata/platform/services/preview/cluster-wide-ephemeral/kustomization.yaml similarity index 100% rename from test/testdata/platform/services/dev/cluster-wide-ephemeral/kustomization.yaml rename to test/testdata/platform/services/preview/cluster-wide-ephemeral/kustomization.yaml diff --git a/test/testdata/platform/services/dev/ephemeral-data-index/02-sonataflow_platform.yaml b/test/testdata/platform/services/preview/ephemeral-data-index/02-sonataflow_platform.yaml similarity index 100% rename from test/testdata/platform/services/dev/ephemeral-data-index/02-sonataflow_platform.yaml rename to test/testdata/platform/services/preview/ephemeral-data-index/02-sonataflow_platform.yaml diff --git a/test/testdata/platform/services/preview/ephemeral-data-index/kustomization.yaml b/test/testdata/platform/services/preview/ephemeral-data-index/kustomization.yaml new file mode 100644 index 000000000..a6807fcf5 --- /dev/null +++ b/test/testdata/platform/services/preview/ephemeral-data-index/kustomization.yaml @@ -0,0 +1,20 @@ +# Copyright 2024 Apache Software Foundation (ASF) +# +# 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. + +resources: +- 02-sonataflow_platform.yaml +- sonataflow/03-sonataflow_callbackstatetimeouts.sw.yaml + +sortOptions: + order: fifo diff --git a/test/testdata/platform/services/prod/postgreSQL/sonataflow/04-sonataflow_callbackstatetimeouts.sw.yaml b/test/testdata/platform/services/preview/ephemeral-data-index/sonataflow/03-sonataflow_callbackstatetimeouts.sw.yaml similarity index 100% rename from test/testdata/platform/services/prod/postgreSQL/sonataflow/04-sonataflow_callbackstatetimeouts.sw.yaml rename to test/testdata/platform/services/preview/ephemeral-data-index/sonataflow/03-sonataflow_callbackstatetimeouts.sw.yaml diff --git a/test/testdata/platform/services/dev/ephemeral-job-service/02-sonataflow_platform.yaml b/test/testdata/platform/services/preview/ephemeral-job-service/02-sonataflow_platform.yaml similarity index 100% rename from test/testdata/platform/services/dev/ephemeral-job-service/02-sonataflow_platform.yaml rename to test/testdata/platform/services/preview/ephemeral-job-service/02-sonataflow_platform.yaml diff --git a/test/testdata/platform/services/dev/ephemeral-job-service/kustomization.yaml b/test/testdata/platform/services/preview/ephemeral-job-service/kustomization.yaml similarity index 92% rename from test/testdata/platform/services/dev/ephemeral-job-service/kustomization.yaml rename to test/testdata/platform/services/preview/ephemeral-job-service/kustomization.yaml index 5441bfce8..20286ada0 100644 --- a/test/testdata/platform/services/dev/ephemeral-job-service/kustomization.yaml +++ b/test/testdata/platform/services/preview/ephemeral-job-service/kustomization.yaml @@ -14,6 +14,7 @@ resources: - 02-sonataflow_platform.yaml +- sonataflow/03-sonataflow_callbackstatetimeouts.sw.yaml sortOptions: order: fifo diff --git a/test/testdata/platform/services/dev/ephemeral-data-index/sonataflow/03-sonataflow_callbackstatetimeouts.sw.yaml b/test/testdata/platform/services/preview/ephemeral-job-service/sonataflow/03-sonataflow_callbackstatetimeouts.sw.yaml similarity index 98% rename from test/testdata/platform/services/dev/ephemeral-data-index/sonataflow/03-sonataflow_callbackstatetimeouts.sw.yaml rename to test/testdata/platform/services/preview/ephemeral-job-service/sonataflow/03-sonataflow_callbackstatetimeouts.sw.yaml index 8bc8a77de..249ee2c12 100644 --- a/test/testdata/platform/services/dev/ephemeral-data-index/sonataflow/03-sonataflow_callbackstatetimeouts.sw.yaml +++ b/test/testdata/platform/services/preview/ephemeral-job-service/sonataflow/03-sonataflow_callbackstatetimeouts.sw.yaml @@ -19,7 +19,7 @@ metadata: annotations: sonataflow.org/description: Callback State Timeouts Example k8s sonataflow.org/version: 0.0.1 - sonataflow.org/profile: dev + sonataflow.org/profile: prod spec: flow: start: PrintStartMessage diff --git a/test/testdata/platform/services/prod/ephemeral/02-sonataflow_platform.yaml b/test/testdata/platform/services/preview/ephemeral-with-workflow/02-sonataflow_platform.yaml similarity index 100% rename from test/testdata/platform/services/prod/ephemeral/02-sonataflow_platform.yaml rename to test/testdata/platform/services/preview/ephemeral-with-workflow/02-sonataflow_platform.yaml diff --git a/test/testdata/platform/services/prod/ephemeral/kustomization.yaml b/test/testdata/platform/services/preview/ephemeral-with-workflow/kustomization.yaml similarity index 92% rename from test/testdata/platform/services/prod/ephemeral/kustomization.yaml rename to test/testdata/platform/services/preview/ephemeral-with-workflow/kustomization.yaml index 5441bfce8..20286ada0 100644 --- a/test/testdata/platform/services/prod/ephemeral/kustomization.yaml +++ b/test/testdata/platform/services/preview/ephemeral-with-workflow/kustomization.yaml @@ -14,6 +14,7 @@ resources: - 02-sonataflow_platform.yaml +- sonataflow/03-sonataflow_callbackstatetimeouts.sw.yaml sortOptions: order: fifo diff --git a/test/testdata/platform/services/dev/ephemeral-job-service/sonataflow/03-sonataflow_callbackstatetimeouts.sw.yaml b/test/testdata/platform/services/preview/ephemeral-with-workflow/sonataflow/03-sonataflow_callbackstatetimeouts.sw.yaml similarity index 98% rename from test/testdata/platform/services/dev/ephemeral-job-service/sonataflow/03-sonataflow_callbackstatetimeouts.sw.yaml rename to test/testdata/platform/services/preview/ephemeral-with-workflow/sonataflow/03-sonataflow_callbackstatetimeouts.sw.yaml index 8bc8a77de..249ee2c12 100644 --- a/test/testdata/platform/services/dev/ephemeral-job-service/sonataflow/03-sonataflow_callbackstatetimeouts.sw.yaml +++ b/test/testdata/platform/services/preview/ephemeral-with-workflow/sonataflow/03-sonataflow_callbackstatetimeouts.sw.yaml @@ -19,7 +19,7 @@ metadata: annotations: sonataflow.org/description: Callback State Timeouts Example k8s sonataflow.org/version: 0.0.1 - sonataflow.org/profile: dev + sonataflow.org/profile: prod spec: flow: start: PrintStartMessage diff --git a/test/testdata/platform/services/preview/ephemeral/02-sonataflow_platform.yaml b/test/testdata/platform/services/preview/ephemeral/02-sonataflow_platform.yaml new file mode 100644 index 000000000..52b7d11f7 --- /dev/null +++ b/test/testdata/platform/services/preview/ephemeral/02-sonataflow_platform.yaml @@ -0,0 +1,28 @@ +# Copyright 2024 Apache Software Foundation (ASF) +# +# 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. + +apiVersion: sonataflow.org/v1alpha08 +kind: SonataFlowPlatform +metadata: + name: sonataflow-platform +spec: + build: + config: + strategyOptions: + KanikoBuildCacheEnabled: "true" + services: + dataIndex: + enabled: true + jobService: + enabled: true diff --git a/test/testdata/platform/noservices/dev/ephemeral/kustomization.yaml b/test/testdata/platform/services/preview/ephemeral/kustomization.yaml similarity index 100% rename from test/testdata/platform/noservices/dev/ephemeral/kustomization.yaml rename to test/testdata/platform/services/preview/ephemeral/kustomization.yaml diff --git a/test/testdata/platform/noservices/dev/ephemeral/sonataflow/03-sonataflow_callbackstatetimeouts.sw.yaml b/test/testdata/platform/services/preview/ephemeral/sonataflow/03-sonataflow_callbackstatetimeouts.sw.yaml similarity index 98% rename from test/testdata/platform/noservices/dev/ephemeral/sonataflow/03-sonataflow_callbackstatetimeouts.sw.yaml rename to test/testdata/platform/services/preview/ephemeral/sonataflow/03-sonataflow_callbackstatetimeouts.sw.yaml index 8bc8a77de..a76ac23fb 100644 --- a/test/testdata/platform/noservices/dev/ephemeral/sonataflow/03-sonataflow_callbackstatetimeouts.sw.yaml +++ b/test/testdata/platform/services/preview/ephemeral/sonataflow/03-sonataflow_callbackstatetimeouts.sw.yaml @@ -19,7 +19,7 @@ metadata: annotations: sonataflow.org/description: Callback State Timeouts Example k8s sonataflow.org/version: 0.0.1 - sonataflow.org/profile: dev + sonataflow.org/profile: preview spec: flow: start: PrintStartMessage diff --git a/test/testdata/platform/services/prod/postgreSQL/01-postgres.yaml b/test/testdata/platform/services/preview/postgreSQL/01-postgres.yaml similarity index 100% rename from test/testdata/platform/services/prod/postgreSQL/01-postgres.yaml rename to test/testdata/platform/services/preview/postgreSQL/01-postgres.yaml diff --git a/test/testdata/platform/services/prod/postgreSQL/02-sonataflow_platform.yaml b/test/testdata/platform/services/preview/postgreSQL/02-sonataflow_platform.yaml similarity index 100% rename from test/testdata/platform/services/prod/postgreSQL/02-sonataflow_platform.yaml rename to test/testdata/platform/services/preview/postgreSQL/02-sonataflow_platform.yaml diff --git a/test/testdata/platform/services/prod/postgreSQL/kustomization.yaml b/test/testdata/platform/services/preview/postgreSQL/kustomization.yaml similarity index 100% rename from test/testdata/platform/services/prod/postgreSQL/kustomization.yaml rename to test/testdata/platform/services/preview/postgreSQL/kustomization.yaml diff --git a/test/testdata/platform/services/preview/postgreSQL/sonataflow/04-sonataflow_callbackstatetimeouts.sw.yaml b/test/testdata/platform/services/preview/postgreSQL/sonataflow/04-sonataflow_callbackstatetimeouts.sw.yaml new file mode 100644 index 000000000..a76ac23fb --- /dev/null +++ b/test/testdata/platform/services/preview/postgreSQL/sonataflow/04-sonataflow_callbackstatetimeouts.sw.yaml @@ -0,0 +1,81 @@ +# Copyright 2024 Apache Software Foundation (ASF) +# +# 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. + +apiVersion: sonataflow.org/v1alpha08 +kind: SonataFlow +metadata: + name: callbackstatetimeouts + annotations: + sonataflow.org/description: Callback State Timeouts Example k8s + sonataflow.org/version: 0.0.1 + sonataflow.org/profile: preview +spec: + flow: + start: PrintStartMessage + events: + - name: callbackEvent + source: '' + type: callback_event_type + functions: + - name: systemOut + type: custom + operation: sysout + states: + - name: PrintStartMessage + type: operation + actions: + - name: printSystemOut + functionRef: + refName: systemOut + arguments: + message: "${\"callback-state-timeouts: \" + $WORKFLOW.instanceId + \" has started.\"}" + transition: CallbackState + - name: CallbackState + type: callback + action: + name: callbackAction + functionRef: + refName: systemOut + arguments: + message: "${\"callback-state-timeouts: \" + $WORKFLOW.instanceId + \" has executed the callbackFunction.\"}" + eventRef: callbackEvent + transition: CheckEventArrival + timeouts: + eventTimeout: PT30S + - name: CheckEventArrival + type: switch + dataConditions: + - condition: "${ .eventData != null }" + transition: EventArrived + defaultCondition: + transition: EventNotArrived + - name: EventArrived + type: inject + data: + exitMessage: "The callback event has arrived." + transition: PrintExitMessage + - name: EventNotArrived + type: inject + data: + exitMessage: "The callback event has not arrived, and the timeout has overdue." + transition: PrintExitMessage + - name: PrintExitMessage + type: operation + actions: + - name: printSystemOut + functionRef: + refName: systemOut + arguments: + message: "${\"callback-state-timeouts: \" + $WORKFLOW.instanceId + \" has finalized. \" + .exitMessage + \" eventData: \" + .eventData}" + end: true diff --git a/test/testdata/sonataflow.org_v1alpha08_sonataflow-simpleops.yaml b/test/testdata/sonataflow.org_v1alpha08_sonataflow-simpleops.yaml index c9b4a9868..d55f427f1 100644 --- a/test/testdata/sonataflow.org_v1alpha08_sonataflow-simpleops.yaml +++ b/test/testdata/sonataflow.org_v1alpha08_sonataflow-simpleops.yaml @@ -19,6 +19,9 @@ metadata: annotations: sonataflow.org/description: Simple example on k8s! sonataflow.org/version: 0.0.1 + labels: + test: test + app: not-simple spec: podTemplate: container: diff --git a/test/testdata/sonataflow.org_v1alpha08_sonataflow.yaml b/test/testdata/sonataflow.org_v1alpha08_sonataflow.yaml index 4aa82104c..0616efd16 100644 --- a/test/testdata/sonataflow.org_v1alpha08_sonataflow.yaml +++ b/test/testdata/sonataflow.org_v1alpha08_sonataflow.yaml @@ -22,6 +22,8 @@ metadata: annotations: sonataflow.org/description: Greeting example on k8s! sonataflow.org/version: 0.0.1 + labels: + test: test spec: flow: start: ChooseOnLanguage diff --git a/test/yaml.go b/test/yaml.go index 8c3692a6f..84ac1b7d8 100644 --- a/test/yaml.go +++ b/test/yaml.go @@ -195,11 +195,11 @@ func SetDevProfile(workflow *operatorapi.SonataFlow) { workflow.Annotations["sonataflow.org/profile"] = "dev" } -func SetProdProfile(workflow *operatorapi.SonataFlow) { - workflow.Annotations["sonataflow.org/profile"] = "prod" +func SetPreviewProfile(workflow *operatorapi.SonataFlow) { + workflow.Annotations["sonataflow.org/profile"] = "preview" } -func GetBaseSonataFlow(namespace string, options ...*func(*operatorapi.SonataFlow)) *operatorapi.SonataFlow { +func GetBaseSonataFlow(namespace string) *operatorapi.SonataFlow { return NewSonataFlow(sonataFlowSampleYamlCR, namespace) } @@ -212,7 +212,7 @@ func GetBaseSonataFlowWithDevProfile(namespace string) *operatorapi.SonataFlow { } func GetBaseSonataFlowWithProdProfile(namespace string) *operatorapi.SonataFlow { - return NewSonataFlow(sonataFlowSampleYamlCR, namespace, SetProdProfile) + return NewSonataFlow(sonataFlowSampleYamlCR, namespace, SetPreviewProfile) } // GetBaseSonataFlowWithProdOpsProfile gets a base workflow that has a pre-built image set in podTemplate. @@ -244,10 +244,6 @@ func GetBasePlatformWithDevBaseImageInReadyPhase(namespace string) *operatorapi. return platform } -func GetBaseClusterPlatform() *operatorapi.SonataFlowClusterPlatform { - return getSonataFlowClusterPlatform(sonataFlowClusterPlatformYamlCR) -} - func GetBasePlatform() *operatorapi.SonataFlowPlatform { return getSonataFlowPlatform(sonataFlowPlatformYamlCR) } @@ -307,5 +303,9 @@ func getProjectDir() string { wd = filepath.Dir(wd) } projectDir = wd + if _, err := os.Lstat(projectDir); err != nil { + panic("Failed to read project directory to run tests: " + err.Error()) + } + return projectDir } diff --git a/testbdd/go.mod b/testbdd/go.mod index ad885f54f..aaae41fd0 100644 --- a/testbdd/go.mod +++ b/testbdd/go.mod @@ -126,7 +126,7 @@ require ( google.golang.org/genproto/googleapis/api v0.0.0-20231002182017-d307bd883b97 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20231009173412-8bfb1ae86b6c // indirect google.golang.org/grpc v1.58.3 // indirect - google.golang.org/protobuf v1.31.0 // indirect + google.golang.org/protobuf v1.33.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/src-d/go-billy.v4 v4.3.2 // indirect gopkg.in/src-d/go-git.v4 v4.13.1 // indirect diff --git a/testbdd/go.sum b/testbdd/go.sum index 09f220a4f..43572f7c8 100644 --- a/testbdd/go.sum +++ b/testbdd/go.sum @@ -1416,7 +1416,7 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba 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.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/utils/openshift/route.go b/utils/openshift/route.go index 0ad87a5e7..d678d371b 100644 --- a/utils/openshift/route.go +++ b/utils/openshift/route.go @@ -33,6 +33,7 @@ func RouteForWorkflow(workflow *operatorapi.SonataFlow) (*v1.Route, error) { ObjectMeta: metav1.ObjectMeta{ Name: workflow.Name, Namespace: workflow.Namespace, + Labels: workflowproj.GetMergedLabels(workflow), }, Spec: v1.RouteSpec{ To: v1.RouteTargetReference{ @@ -44,6 +45,5 @@ func RouteForWorkflow(workflow *operatorapi.SonataFlow) (*v1.Route, error) { }, }, } - workflowproj.SetDefaultLabels(workflow, route) return route, nil } diff --git a/workflowproj/go.mod b/workflowproj/go.mod index b85dbb1cb..79e952d32 100644 --- a/workflowproj/go.mod +++ b/workflowproj/go.mod @@ -70,7 +70,7 @@ require ( golang.org/x/time v0.3.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/protobuf v1.31.0 // indirect + google.golang.org/protobuf v1.33.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/workflowproj/go.sum b/workflowproj/go.sum index 81c0176ad..76febac12 100644 --- a/workflowproj/go.sum +++ b/workflowproj/go.sum @@ -313,7 +313,7 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba 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.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= 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= diff --git a/workflowproj/operator.go b/workflowproj/operator.go index de6615d53..2a5c3e3f0 100644 --- a/workflowproj/operator.go +++ b/workflowproj/operator.go @@ -75,21 +75,14 @@ func GetWorkflowManagedPropertiesConfigMapName(workflow *operatorapi.SonataFlow) // GetManagedPropertiesFileName gets the default ConfigMap name that holds the managed application property for the given workflow func GetManagedPropertiesFileName(workflow *operatorapi.SonataFlow) string { - profile := metadata.ProdProfile + profile := metadata.QuarkusProdProfile if IsDevProfile(workflow) { - profile = metadata.DevProfile + profile = metadata.QuarkusDevProfile } return fmt.Sprintf("application-%s.properties", profile) } -// SetDefaultLabels adds the default workflow application labels to the given object. -// Overrides the defined labels. -func SetDefaultLabels(workflow *operatorapi.SonataFlow, object metav1.Object) { - object.SetLabels(GetDefaultLabels(workflow)) -} - // GetDefaultLabels gets the default labels based on the given workflow. -// You can use SetDefaultLabels that essentially does the same thing, if you don't need the labels explicitly. func GetDefaultLabels(workflow *operatorapi.SonataFlow) map[string]string { return map[string]string{ LabelApp: workflow.Name, @@ -97,13 +90,32 @@ func GetDefaultLabels(workflow *operatorapi.SonataFlow) map[string]string { } } +// SetMergedLabels adds the merged labels to the given object. +func SetMergedLabels(workflow *operatorapi.SonataFlow, object metav1.Object) { + object.SetLabels(GetMergedLabels(workflow)) +} + +// GetMergedLabels gets labels based on the given workflow, includes their own labels, merged with the default ones. +func GetMergedLabels(workflow *operatorapi.SonataFlow) map[string]string { + mergedLabels := make(map[string]string) + if labels := workflow.GetLabels(); labels != nil { + for k, v := range labels { + mergedLabels[k] = v + } + } + for k, v := range GetDefaultLabels(workflow) { + mergedLabels[k] = v + } + return mergedLabels +} + // CreateNewUserPropsConfigMap creates a new empty ConfigMap object to hold the user application properties of the workflow. func CreateNewUserPropsConfigMap(workflow *operatorapi.SonataFlow) *corev1.ConfigMap { return &corev1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: GetWorkflowUserPropertiesConfigMapName(workflow), Namespace: workflow.Namespace, - Labels: GetDefaultLabels(workflow), + Labels: GetMergedLabels(workflow), }, Data: map[string]string{ApplicationPropertiesFileName: ""}, } @@ -115,7 +127,7 @@ func CreateNewManagedPropsConfigMap(workflow *operatorapi.SonataFlow, properties ObjectMeta: metav1.ObjectMeta{ Name: GetWorkflowManagedPropertiesConfigMapName(workflow), Namespace: workflow.Namespace, - Labels: GetDefaultLabels(workflow), + Labels: GetMergedLabels(workflow), }, Data: map[string]string{GetManagedPropertiesFileName(workflow): properties}, } diff --git a/workflowproj/workflowproj.go b/workflowproj/workflowproj.go index 79359e4b2..bd8653d2b 100644 --- a/workflowproj/workflowproj.go +++ b/workflowproj/workflowproj.go @@ -234,7 +234,7 @@ func (w *workflowProjectHandler) parseRawWorkflow() error { profile = w.profile } SetWorkflowProfile(w.project.Workflow, profile) - SetDefaultLabels(w.project.Workflow, w.project.Workflow) + SetMergedLabels(w.project.Workflow, w.project.Workflow) if err = SetTypeToObject(w.project.Workflow, w.scheme); err != nil { return err } diff --git a/workflowproj/workflowproj_test.go b/workflowproj/workflowproj_test.go index 1c04c602a..9d3cab678 100644 --- a/workflowproj/workflowproj_test.go +++ b/workflowproj/workflowproj_test.go @@ -55,7 +55,7 @@ func Test_Handler_WorkflowMinimalInvalid(t *testing.T) { func Test_Handler_WorkflowMinimalAndProps(t *testing.T) { proj, err := New("default"). Named("minimal"). - Profile(metadata.ProdProfile). + Profile(metadata.PreviewProfile). WithWorkflow(getWorkflowMinimal()). WithAppProperties(getWorkflowProperties()). AsObjects() @@ -65,7 +65,7 @@ func Test_Handler_WorkflowMinimalAndProps(t *testing.T) { assert.Equal(t, "minimal", proj.Workflow.Name) assert.Equal(t, "minimal-props", proj.Properties.Name) assert.NotEmpty(t, proj.Properties.Data["application.properties"]) - assert.Equal(t, string(metadata.ProdProfile), proj.Workflow.Annotations[metadata.Profile]) + assert.Equal(t, string(metadata.PreviewProfile), proj.Workflow.Annotations[metadata.Profile]) assert.NotEmpty(t, proj.Properties.Data) } @@ -77,6 +77,8 @@ func Test_Handler_WorkflowMinimalAndPropsAndSpec(t *testing.T) { AsObjects() assert.NoError(t, err) assert.NotNil(t, proj.Workflow) + assert.NotNil(t, proj.Workflow.ObjectMeta) + assert.Equal(t, proj.Workflow.ObjectMeta.Labels, map[string]string{"app": "hello", "sonataflow.org/workflow-app": "hello"}) assert.NotNil(t, proj.Properties) assert.NotEmpty(t, proj.Resources) assert.Equal(t, "hello", proj.Workflow.Name)