This is an automated email from the ASF dual-hosted git repository.

ricardozanini pushed a commit to branch main
in repository 
https://gitbox.apache.org/repos/asf/incubator-kie-kogito-serverless-operator.git


The following commit(s) were added to refs/heads/main by this push:
     new 4f505a71 Fix #385 - Introduce Knative deployments for workflows  (#447)
4f505a71 is described below

commit 4f505a71bf2eb4844587a2e75489a8ad35fcae1e
Author: Ricardo Zanini <[email protected]>
AuthorDate: Wed May 8 10:59:02 2024 -0300

    Fix #385 - Introduce Knative deployments for workflows  (#447)
---
 api/metadata/annotations.go                        |  28 ++
 api/metadata/annotations_test.go                   |  43 ++
 .../{sonataflow_types.go => podtemplate_types.go}  | 264 +---------
 api/v1alpha08/sonataflow_types.go                  | 540 +--------------------
 api/v1alpha08/zz_generated.deepcopy.go             |  22 +
 .../sonataflow-operator.clusterserviceversion.yaml |  19 +
 bundle/manifests/sonataflow.org_sonataflows.yaml   |   9 +
 config/crd/bases/sonataflow.org_sonataflows.yaml   |   9 +
 .../sonataflow-operator.clusterserviceversion.yaml |   3 +
 config/rbac/builder_role.yaml                      |  30 --
 config/rbac/knative_role.yaml                      |  52 ++
 config/rbac/knative_role_binding.yaml              |  13 +
 config/rbac/kustomization.yaml                     |   2 +
 controllers/platform/k8s.go                        |   4 +-
 ...{deployment.go => deployment_status_manager.go} |  36 +-
 .../common/{knative.go => knative_eventing.go}     |   0
 controllers/profiles/common/mutate_visitors.go     |  50 ++
 controllers/profiles/common/object_creators.go     |  42 +-
 .../profiles/common/object_creators_test.go        |  20 +-
 .../profiles/common/persistence/postgresql.go      |  15 +-
 controllers/profiles/dev/object_creators_dev.go    |   3 +-
 controllers/profiles/factory/factory.go            |  23 +-
 controllers/profiles/gitops/profile_gitops_test.go |   2 +-
 controllers/profiles/preview/deployment_handler.go | 104 ++--
 .../profiles/preview/deployment_handler_test.go    |  42 +-
 .../profiles/preview/object_creators_preview.go    |  35 +-
 controllers/profiles/preview/profile_preview.go    |  27 +-
 .../profiles/preview/profile_preview_test.go       |   1 +
 controllers/profiles/preview/states_preview.go     |   2 +-
 controllers/sonataflow_controller.go               |  15 +
 hack/local/run-operator.sh                         |   3 +
 main.go                                            |   2 +
 operator.yaml                                      |  44 ++
 test/kubernetes_cli.go                             |   8 +
 test/yaml.go                                       |   4 +-
 testbdd/go.mod                                     |   4 +
 testbdd/go.sum                                     |   4 +
 utils/common.go                                    |   6 +-
 workflowproj/workflowproj.go                       |   6 +-
 39 files changed, 625 insertions(+), 911 deletions(-)

diff --git a/api/metadata/annotations.go b/api/metadata/annotations.go
index a0980ab9..a8f56091 100644
--- a/api/metadata/annotations.go
+++ b/api/metadata/annotations.go
@@ -73,3 +73,31 @@ const (
        // Ideally used in production use cases
        GitOpsProfile ProfileType = "gitops"
 )
+
+const (
+       DefaultProfile = PreviewProfile
+)
+
+// deprecated prod profile is deprecate and not supported, use preview profile
+var supportedProfiles = map[ProfileType]ProfileType{DevProfile: DevProfile, 
PreviewProfile: PreviewProfile, GitOpsProfile: GitOpsProfile}
+
+func GetProfileOrDefault(annotation map[string]string) ProfileType {
+       if annotation == nil {
+               return DefaultProfile
+       }
+       if profile, ok := supportedProfiles[ProfileType(annotation[Profile])]; 
!ok {
+               return DefaultProfile
+       } else {
+               return profile
+       }
+}
+
+func IsDevProfile(annotation map[string]string) bool {
+       if annotation == nil {
+               return false
+       }
+       if len(annotation[Profile]) == 0 {
+               return false
+       }
+       return ProfileType(annotation[Profile]) == DevProfile
+}
diff --git a/api/metadata/annotations_test.go b/api/metadata/annotations_test.go
new file mode 100644
index 00000000..b0437bb3
--- /dev/null
+++ b/api/metadata/annotations_test.go
@@ -0,0 +1,43 @@
+// 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 metadata
+
+import (
+       "testing"
+)
+
+func TestGetProfile(t *testing.T) {
+       type args struct {
+               annotation map[string]string
+       }
+       tests := []struct {
+               name string
+               args args
+               want ProfileType
+       }{
+               {"Empty Annotations", args{annotation: nil}, DefaultProfile},
+               {"Non-existent Profile", args{annotation: 
map[string]string{Profile: "IDontExist"}}, DefaultProfile},
+               {"Regular Annotation", args{annotation: 
map[string]string{Profile: GitOpsProfile.String()}}, GitOpsProfile},
+               {"Deprecated Annotation", args{annotation: 
map[string]string{Profile: ProdProfile.String()}}, DefaultProfile},
+               {"Dev Annotation", args{annotation: map[string]string{Profile: 
DevProfile.String()}}, DevProfile},
+       }
+       for _, tt := range tests {
+               t.Run(tt.name, func(t *testing.T) {
+                       if got := GetProfileOrDefault(tt.args.annotation); got 
!= tt.want {
+                               t.Errorf("GetProfileOrDefault() = %v, want %v", 
got, tt.want)
+                       }
+               })
+       }
+}
diff --git a/api/v1alpha08/sonataflow_types.go 
b/api/v1alpha08/podtemplate_types.go
similarity index 72%
copy from api/v1alpha08/sonataflow_types.go
copy to api/v1alpha08/podtemplate_types.go
index 3237fc1f..3811a1bb 100644
--- a/api/v1alpha08/sonataflow_types.go
+++ b/api/v1alpha08/podtemplate_types.go
@@ -1,35 +1,20 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.
- */
+// 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 v1alpha08
 
-import (
-       cncfmodel "github.com/serverlessworkflow/sdk-go/v2/model"
-       corev1 "k8s.io/api/core/v1"
-       metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-       "knative.dev/pkg/apis"
-       duckv1 "knative.dev/pkg/apis/duck/v1"
-
-       "github.com/apache/incubator-kie-kogito-serverless-operator/api"
-)
-
-const DefaultContainerName = "workflow"
+import corev1 "k8s.io/api/core/v1"
 
 // ContainerSpec is the container for the internal deployments based on the 
default Kubernetes Container API
 type ContainerSpec struct {
@@ -558,224 +543,3 @@ type PodTemplateSpec struct {
        // +optional
        Replicas *int32 `json:"replicas,omitempty"`
 }
-
-// Flow describes the contents of the Workflow definition following the CNCF 
Serverless Workflow Specification.
-// The attributes not part of the flow are defined by the Custom Resource 
metadata information, as follows:
-//
-// - Id, name, and key are replaced by the Custom Resource's name. Must follow 
the Kubernetes naming patterns (RFC1123).
-//
-// - Description can be added in the CR's annotation field 
sonataflow.org/description
-//
-// - Version is also defined in the CR's annotation, field 
sonataflow.org/version
-//
-// - SpecVersion is in the CR's apiVersion, for example v1alpha08 means that 
it follows the specification version 0.8.
-type Flow struct {
-       // Workflow start definition.
-       // +kubebuilder:validation:Schemaless
-       // +kubebuilder:pruning:PreserveUnknownFields
-       // +optional
-       Start *cncfmodel.Start `json:"start,omitempty"`
-       // Annotations List of helpful terms describing the workflows intended 
purpose, subject areas, or other important
-       // qualities.
-       // +optional
-       Annotations []string `json:"annotations,omitempty"`
-       // DataInputSchema URI of the JSON Schema used to validate the workflow 
data input
-       // +optional
-       DataInputSchema *cncfmodel.DataInputSchema 
`json:"dataInputSchema,omitempty"`
-       // Secrets allow you to access sensitive information, such as 
passwords, OAuth tokens, ssh keys, etc,
-       // inside your Workflow Expressions.
-       // +optional
-       Secrets cncfmodel.Secrets `json:"secrets,omitempty"`
-       // Constants Workflow constants are used to define static, and 
immutable, data which is available to
-       // Workflow Expressions.
-       // +optional
-       Constants *cncfmodel.Constants `json:"constants,omitempty"`
-       // Defines the workflow default timeout settings.
-       // +optional
-       Timeouts *cncfmodel.Timeouts `json:"timeouts,omitempty"`
-       // Defines checked errors that can be explicitly handled during 
workflow execution.
-       // +optional
-       Errors cncfmodel.Errors `json:"errors,omitempty"`
-       // If "true", workflow instances is not terminated when there are no 
active execution paths.
-       // Instance can be terminated with "terminate end definition" or 
reaching defined "workflowExecTimeout"
-       // +optional
-       KeepActive bool `json:"keepActive,omitempty"`
-       // Metadata custom information shared with the runtime.
-       // +kubebuilder:validation:Schemaless
-       // +kubebuilder:pruning:PreserveUnknownFields
-       // +optional
-       Metadata cncfmodel.Metadata `json:"metadata,omitempty"`
-       // AutoRetries If set to true, actions should automatically be retried 
on unchecked errors. Default is false
-       // +optional
-       AutoRetries bool `json:"autoRetries,omitempty"`
-       // Auth definitions can be used to define authentication information 
that should be applied to resources defined
-       // in the operation property of function definitions. It is not used as 
authentication information for the
-       // function invocation, but just to access the resource containing the 
function invocation information.
-       // +kubebuilder:validation:Schemaless
-       // +kubebuilder:pruning:PreserveUnknownFields
-       // +optional
-       Auth cncfmodel.Auths `json:"auth,omitempty" validate:"omitempty"`
-       // +kubebuilder:validation:MinItems=1
-       // +kubebuilder:pruning:PreserveUnknownFields
-       States []cncfmodel.State `json:"states" validate:"required,min=1,dive"`
-       // +optional
-       Events cncfmodel.Events `json:"events,omitempty"`
-       // +optional
-       Functions cncfmodel.Functions `json:"functions,omitempty"`
-       // +optional
-       Retries cncfmodel.Retries `json:"retries,omitempty" validate:"dive"`
-}
-
-// WorkflowResources collection of local objects holding workflow resources, 
such as OpenAPI files
-// that will be mounted in the workflow application.
-type WorkflowResources struct {
-       ConfigMaps []ConfigMapWorkflowResource `json:"configMaps,omitempty"`
-}
-
-// ConfigMapWorkflowResource ConfigMap local reference holding one or more 
workflow resources, such as OpenAPI files
-// that will be mounted in the workflow application.
-type ConfigMapWorkflowResource struct {
-       // ConfigMap the given configMap name in the same workflow context to 
find the resource
-       // +kubebuilder:validation:Required
-       ConfigMap corev1.LocalObjectReference `json:"configMap"`
-       // WorkflowPath path relative to the workflow application root file 
system within the pod (/<application path>/src/main/resources).
-       // Starting trailing slashes will be removed.
-       WorkflowPath string `json:"workflowPath,omitempty"`
-}
-
-// SonataFlowSpec defines the desired state of SonataFlow
-// +k8s:openapi-gen=true
-type SonataFlowSpec struct {
-       // Flow the workflow definition.
-       // +kubebuilder:validation:Required
-       
//+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="flow"
-       Flow Flow `json:"flow"`
-       // Resources workflow resources that are linked to this workflow 
definition.
-       // For example, a collection of OpenAPI specification files.
-       
//+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="resources"
-       Resources WorkflowResources `json:"resources,omitempty"`
-       // PodTemplate describes the deployment details of this SonataFlow 
instance.
-       
//+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="podTemplate"
-       PodTemplate PodTemplateSpec `json:"podTemplate,omitempty"`
-       // Persistence defines the database persistence configuration for the 
workflow
-       Persistence *PersistenceOptionsSpec `json:"persistence,omitempty"`
-       // Sink describes the sinkBinding details of this SonataFlow instance.
-       
//+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="sink"
-       Sink *duckv1.Destination `json:"sink,omitempty"`
-}
-
-// SonataFlowStatus defines the observed state of SonataFlow
-// +k8s:openapi-gen=true
-type SonataFlowStatus struct {
-       api.Status `json:",inline"`
-       // Address is used as a part of Addressable interface 
(status.address.url) for knative
-       // +optional
-       
//+operator-sdk:csv:customresourcedefinitions:type=status,displayName="address"
-       Address duckv1.Addressable `json:"address,omitempty"`
-       // keeps track of how many failure recovers a given workflow had so far
-       
//+operator-sdk:csv:customresourcedefinitions:type=status,displayName="recoverFailureAttempts"
-       RecoverFailureAttempts int `json:"recoverFailureAttempts,omitempty"`
-       
//+operator-sdk:csv:customresourcedefinitions:type=status,displayName="lastTimeRecoverAttempt"
-       LastTimeRecoverAttempt metav1.Time 
`json:"lastTimeRecoverAttempt,omitempty"`
-       // 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 {
-       return api.RunningConditionType
-}
-
-func (s *SonataFlowStatus) IsReady() bool {
-       return s.GetTopLevelCondition().IsTrue()
-}
-
-func (s *SonataFlowStatus) GetTopLevelCondition() *api.Condition {
-       return s.GetCondition(s.GetTopLevelConditionType())
-}
-
-func (s *SonataFlowStatus) Manager() api.ConditionsManager {
-       return api.NewConditionManager(s, api.RunningConditionType, 
api.BuiltConditionType)
-}
-
-func (s *SonataFlowStatus) IsWaitingForPlatform() bool {
-       cond := s.GetCondition(api.BuiltConditionType)
-       return cond.IsFalse() && cond.Reason == api.WaitingForPlatformReason
-}
-
-func (s *SonataFlowStatus) IsWaitingForDeployment() bool {
-       cond := s.GetCondition(api.RunningConditionType)
-       return cond.IsFalse() && cond.Reason == api.WaitingForDeploymentReason
-}
-
-// IsChildObjectsProblem indicates a problem during objects creation during 
reconciliation
-// For example, a deployment that couldn't be created or a referenced object 
not found.
-func (s *SonataFlowStatus) IsChildObjectsProblem() bool {
-       cond := s.GetCondition(api.RunningConditionType)
-       // You can add more conditions that meet this conditional here
-       return cond.IsFalse() && (cond.Reason == 
api.ExternalResourcesNotFoundReason)
-}
-
-func (s *SonataFlowStatus) IsWaitingForBuild() bool {
-       cond := s.GetCondition(api.RunningConditionType)
-       return cond.IsFalse() && cond.Reason == api.WaitingForBuildReason
-}
-
-func (s *SonataFlowStatus) IsBuildRunningOrUnknown() bool {
-       cond := s.GetCondition(api.BuiltConditionType)
-       return cond.IsUnknown() || (cond.IsFalse() && cond.Reason == 
api.BuildIsRunningReason)
-}
-
-func (s *SonataFlowStatus) IsBuildRunning() bool {
-       cond := s.GetCondition(api.BuiltConditionType)
-       return cond.IsFalse() && cond.Reason == api.BuildIsRunningReason
-}
-
-func (s *SonataFlowStatus) IsBuildFailed() bool {
-       cond := s.GetCondition(api.BuiltConditionType)
-       return cond.IsFalse() && cond.Reason == api.BuildFailedReason
-}
-
-// SonataFlow is the descriptor representation for a workflow application 
based on the CNCF Serverless Workflow specification.
-// +kubebuilder:object:root=true
-// +kubebuilder:object:generate=true
-// +kubebuilder:subresource:status
-// +kubebuilder:resource:shortName={"sf", "workflow", "workflows"}
-// +k8s:openapi-gen=true
-// 
+kubebuilder:printcolumn:name="Profile",type=string,JSONPath=`.metadata.annotations.sonataflow\.org\/profile`
-// 
+kubebuilder:printcolumn:name="Version",type=string,JSONPath=`.metadata.annotations.sonataflow\.org\/version`
-// +kubebuilder:printcolumn:name="URL",type=string,JSONPath=`.status.endpoint`
-// 
+kubebuilder:printcolumn:name="Ready",type=string,JSONPath=`.status.conditions[?(@.type=='Running')].status`
-// 
+kubebuilder:printcolumn:name="Reason",type=string,JSONPath=`.status.conditions[?(@.type=='Running')].reason`
-// 
+operator-sdk:csv:customresourcedefinitions:resources={{SonataFlowBuild,sonataflow.org/v1alpha08,"A
 SonataFlow Build"}}
-// 
+operator-sdk:csv:customresourcedefinitions:resources={{Deployment,apps/v1,"A 
Deployment for the Flow"}}
-// +operator-sdk:csv:customresourcedefinitions:resources={{Service,v1,"A 
Service for the Flow"}}
-// 
+operator-sdk:csv:customresourcedefinitions:resources={{Route,route.openshift.io/v1,"An
 OpenShift Route for the Flow"}}
-// +operator-sdk:csv:customresourcedefinitions:resources={{ConfigMap,v1,"The 
ConfigMaps with Flow definition and additional configuration files"}}
-type SonataFlow struct {
-       metav1.TypeMeta   `json:",inline"`
-       metav1.ObjectMeta `json:"metadata,omitempty"`
-
-       Spec   SonataFlowSpec   `json:"spec,omitempty"`
-       Status SonataFlowStatus `json:"status,omitempty"`
-}
-
-func (s *SonataFlow) HasContainerSpecImage() bool {
-       return len(s.Spec.PodTemplate.Container.Image) > 0
-}
-
-// SonataFlowList contains a list of SonataFlow
-// +kubebuilder:object:root=true
-// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
-type SonataFlowList struct {
-       metav1.TypeMeta `json:",inline"`
-       metav1.ListMeta `json:"metadata,omitempty"`
-       Items           []SonataFlow `json:"items"`
-}
-
-func init() {
-       SchemeBuilder.Register(&SonataFlow{}, &SonataFlowList{})
-}
diff --git a/api/v1alpha08/sonataflow_types.go 
b/api/v1alpha08/sonataflow_types.go
index 3237fc1f..7763dc23 100644
--- a/api/v1alpha08/sonataflow_types.go
+++ b/api/v1alpha08/sonataflow_types.go
@@ -31,524 +31,19 @@ import (
 
 const DefaultContainerName = "workflow"
 
-// ContainerSpec is the container for the internal deployments based on the 
default Kubernetes Container API
-type ContainerSpec struct {
-       // Container image name.
-       // More info: https://kubernetes.io/docs/concepts/containers/images
-       // This field is optional to allow higher level config management to 
default or override
-       // container images in workload controllers like Deployments and 
StatefulSets.
-       // +optional
-       Image string `json:"image,omitempty" protobuf:"bytes,2,opt,name=image"`
-       // Entrypoint array. Not executed within a shell.
-       // The container image's ENTRYPOINT is used if this is not provided.
-       // Variable references $(VAR_NAME) are expanded using the container's 
environment. If a variable
-       // cannot be resolved, the reference in the input string will be 
unchanged. Double $$ are reduced
-       // to a single $, which allows for escaping the $(VAR_NAME) syntax: 
i.e. "$$(VAR_NAME)" will
-       // produce the string literal "$(VAR_NAME)". Escaped references will 
never be expanded, regardless
-       // of whether the variable exists or not. Cannot be updated.
-       // More info: 
https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell
-       // +optional
-       Command []string `json:"command,omitempty" 
protobuf:"bytes,3,rep,name=command"`
-       // Arguments to the entrypoint.
-       // The container image's CMD is used if this is not provided.
-       // Variable references $(VAR_NAME) are expanded using the container's 
environment. If a variable
-       // cannot be resolved, the reference in the input string will be 
unchanged. Double $$ are reduced
-       // to a single $, which allows for escaping the $(VAR_NAME) syntax: 
i.e. "$$(VAR_NAME)" will
-       // produce the string literal "$(VAR_NAME)". Escaped references will 
never be expanded, regardless
-       // of whether the variable exists or not. Cannot be updated.
-       // More info: 
https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell
-       // +optional
-       Args []string `json:"args,omitempty" protobuf:"bytes,4,rep,name=args"`
-       // List of ports to expose from the container. Not specifying a port 
here
-       // DOES NOT prevent that port from being exposed. Any port which is
-       // listening on the default "0.0.0.0" address inside a container will be
-       // accessible from the network.
-       // Modifying this array with strategic merge patch may corrupt the data.
-       // For more information See 
https://github.com/kubernetes/kubernetes/issues/108255.
-       // Cannot be updated.
-       // +optional
-       // +patchMergeKey=containerPort
-       // +patchStrategy=merge
-       // +listType=map
-       // +listMapKey=containerPort
-       // +listMapKey=protocol
-       Ports []corev1.ContainerPort `json:"ports,omitempty" 
patchStrategy:"merge" patchMergeKey:"containerPort" 
protobuf:"bytes,6,rep,name=ports"`
-       // List of sources to populate environment variables in the container.
-       // The keys defined within a source must be a C_IDENTIFIER. All invalid 
keys
-       // will be reported as an event when the container is starting. When a 
key exists in multiple
-       // sources, the value associated with the last source will take 
precedence.
-       // Values defined by an Env with a duplicate key will take precedence.
-       // Cannot be updated.
-       // +optional
-       EnvFrom []corev1.EnvFromSource `json:"envFrom,omitempty" 
protobuf:"bytes,19,rep,name=envFrom"`
-       // List of environment variables to set in the container.
-       // Cannot be updated.
-       // +optional
-       // +patchMergeKey=name
-       // +patchStrategy=merge
-       Env []corev1.EnvVar `json:"env,omitempty" patchStrategy:"merge" 
patchMergeKey:"name" protobuf:"bytes,7,rep,name=env"`
-       // Compute Resources required by this container.
-       // Cannot be updated.
-       // More info: 
https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
-       // +optional
-       Resources corev1.ResourceRequirements `json:"resources,omitempty" 
protobuf:"bytes,8,opt,name=resources"`
-       // Resources resize policy for the container.
-       // +featureGate=InPlacePodVerticalScaling
-       // +optional
-       // +listType=atomic
-       ResizePolicy []corev1.ContainerResizePolicy 
`json:"resizePolicy,omitempty" protobuf:"bytes,23,rep,name=resizePolicy"`
-       // Pod volumes to mount into the container's filesystem.
-       // Cannot be updated.
-       // +optional
-       // +patchMergeKey=mountPath
-       // +patchStrategy=merge
-       VolumeMounts []corev1.VolumeMount `json:"volumeMounts,omitempty" 
patchStrategy:"merge" patchMergeKey:"mountPath" 
protobuf:"bytes,9,rep,name=volumeMounts"`
-       // volumeDevices is the list of block devices to be used by the 
container.
-       // +patchMergeKey=devicePath
-       // +patchStrategy=merge
-       // +optional
-       VolumeDevices []corev1.VolumeDevice `json:"volumeDevices,omitempty" 
patchStrategy:"merge" patchMergeKey:"devicePath" 
protobuf:"bytes,21,rep,name=volumeDevices"`
-       // Periodic probe of container liveness.
-       // Container will be restarted if the probe fails.
-       // Cannot be updated.
-       // More info: 
https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
-       // +optional
-       LivenessProbe *corev1.Probe `json:"livenessProbe,omitempty" 
protobuf:"bytes,10,opt,name=livenessProbe"`
-       // Periodic probe of container service readiness.
-       // Container will be removed from service endpoints if the probe fails.
-       // Cannot be updated.
-       // More info: 
https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
-       // +optional
-       ReadinessProbe *corev1.Probe `json:"readinessProbe,omitempty" 
protobuf:"bytes,11,opt,name=readinessProbe"`
-       // StartupProbe indicates that the Pod has successfully initialized.
-       // If specified, no other probes are executed until this completes 
successfully.
-       // If this probe fails, the Pod will be restarted, just as if the 
livenessProbe failed.
-       // This can be used to provide different probe parameters at the 
beginning of a Pod's lifecycle,
-       // when it might take a long time to load data or warm a cache, than 
during steady-state operation.
-       // This cannot be updated.
-       // More info: 
https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
-       // +optional
-       StartupProbe *corev1.Probe `json:"startupProbe,omitempty" 
protobuf:"bytes,22,opt,name=startupProbe"`
-       // Actions that the management system should take in response to 
container lifecycle events.
-       // Cannot be updated.
-       // +optional
-       Lifecycle *corev1.Lifecycle `json:"lifecycle,omitempty" 
protobuf:"bytes,12,opt,name=lifecycle"`
-       // Optional: Path at which the file to which the container's 
termination message
-       // will be written is mounted into the container's filesystem.
-       // Message written is intended to be brief final status, such as an 
assertion failure message.
-       // Will be truncated by the node if greater than 4096 bytes. The total 
message length across
-       // all containers will be limited to 12kb.
-       // Defaults to /dev/termination-log.
-       // Cannot be updated.
-       // +optional
-       TerminationMessagePath string `json:"terminationMessagePath,omitempty" 
protobuf:"bytes,13,opt,name=terminationMessagePath"`
-       // Indicate how the termination message should be populated. File will 
use the contents of
-       // terminationMessagePath to populate the container status message on 
both success and failure.
-       // FallbackToLogsOnError will use the last chunk of container log 
output if the termination
-       // message file is empty and the container exited with an error.
-       // The log output is limited to 2048 bytes or 80 lines, whichever is 
smaller.
-       // Defaults to File.
-       // Cannot be updated.
-       // +optional
-       TerminationMessagePolicy corev1.TerminationMessagePolicy 
`json:"terminationMessagePolicy,omitempty" 
protobuf:"bytes,20,opt,name=terminationMessagePolicy,casttype=TerminationMessagePolicy"`
-       // Image pull policy.
-       // One of Always, Never, IfNotPresent.
-       // Defaults to Always if :latest tag is specified, or IfNotPresent 
otherwise.
-       // Cannot be updated.
-       // More info: 
https://kubernetes.io/docs/concepts/containers/images#updating-images
-       // +optional
-       ImagePullPolicy corev1.PullPolicy `json:"imagePullPolicy,omitempty" 
protobuf:"bytes,14,opt,name=imagePullPolicy,casttype=PullPolicy"`
-       // SecurityContext defines the security options the container should be 
run with.
-       // If set, the fields of SecurityContext override the equivalent fields 
of PodSecurityContext.
-       // More info: 
https://kubernetes.io/docs/tasks/configure-pod-container/security-context/
-       // +optional
-       SecurityContext *corev1.SecurityContext 
`json:"securityContext,omitempty" protobuf:"bytes,15,opt,name=securityContext"`
-
-       // Variables for interactive containers, these have very specialized 
use-cases (e.g. debugging)
-       // and shouldn't be used for general purpose containers.
-
-       // Whether this container should allocate a buffer for stdin in the 
container runtime. If this
-       // is not set, reads from stdin in the container will always result in 
EOF.
-       // Default is false.
-       // +optional
-       Stdin bool `json:"stdin,omitempty" protobuf:"varint,16,opt,name=stdin"`
-       // Whether the container runtime should close the stdin channel after 
it has been opened by
-       // a single attach. When stdin is true the stdin stream will remain 
open across multiple attach
-       // sessions. If stdinOnce is set to true, stdin is opened on container 
start, is empty until the
-       // first client attaches to stdin, and then remains open and accepts 
data until the client disconnects,
-       // at which time stdin is closed and remains closed until the container 
is restarted. If this
-       // flag is false, a container processes that reads from stdin will 
never receive an EOF.
-       // Default is false
-       // +optional
-       StdinOnce bool `json:"stdinOnce,omitempty" 
protobuf:"varint,17,opt,name=stdinOnce"`
-       // Whether this container should allocate a TTY for itself, also 
requires 'stdin' to be true.
-       // Default is false.
-       // +optional
-       TTY bool `json:"tty,omitempty" protobuf:"varint,18,opt,name=tty"`
-}
-
-// ToContainer converts to Kubernetes Container API.
-func (f *ContainerSpec) ToContainer() corev1.Container {
-       return corev1.Container{
-               Name:                     DefaultContainerName,
-               Image:                    f.Image,
-               Command:                  f.Command,
-               Args:                     f.Args,
-               Ports:                    f.Ports,
-               EnvFrom:                  f.EnvFrom,
-               Env:                      f.Env,
-               Resources:                f.Resources,
-               ResizePolicy:             f.ResizePolicy,
-               VolumeMounts:             f.VolumeMounts,
-               VolumeDevices:            f.VolumeDevices,
-               LivenessProbe:            f.LivenessProbe,
-               ReadinessProbe:           f.ReadinessProbe,
-               StartupProbe:             f.StartupProbe,
-               Lifecycle:                f.Lifecycle,
-               TerminationMessagePath:   f.TerminationMessagePath,
-               TerminationMessagePolicy: f.TerminationMessagePolicy,
-               ImagePullPolicy:          f.ImagePullPolicy,
-               SecurityContext:          f.SecurityContext,
-               Stdin:                    f.Stdin,
-               StdinOnce:                f.StdinOnce,
-               TTY:                      f.TTY,
-       }
-}
-
-// PodSpec describes the PodSpec for the internal deployments based on the 
default Kubernetes PodSpec API
-type PodSpec struct {
-       // List of volumes that can be mounted by containers belonging to the 
pod.
-       // More info: https://kubernetes.io/docs/concepts/storage/volumes
-       // +optional
-       // +patchMergeKey=name
-       // +patchStrategy=merge,retainKeys
-       Volumes []corev1.Volume `json:"volumes,omitempty" 
patchStrategy:"merge,retainKeys" patchMergeKey:"name" 
protobuf:"bytes,1,rep,name=volumes"`
-       // List of initialization containers belonging to the pod.
-       // Init containers are executed in order prior to containers being 
started. If any
-       // init container fails, the pod is considered to have failed and is 
handled according
-       // to its restartPolicy. The name for an init container or normal 
container must be
-       // unique among all containers.
-       // Init containers may not have Lifecycle actions, Readiness probes, 
Liveness probes, or Startup probes.
-       // The resourceRequirements of an init container are taken into account 
during scheduling
-       // by finding the highest request/limit for each resource type, and 
then using the max of
-       // of that value or the sum of the normal containers. Limits are 
applied to init containers
-       // in a similar fashion.
-       // Init containers cannot currently be added or removed.
-       // Cannot be updated.
-       // More info: 
https://kubernetes.io/docs/concepts/workloads/pods/init-containers/
-       // +patchMergeKey=name
-       // +patchStrategy=merge
-       InitContainers []corev1.Container `json:"initContainers,omitempty" 
patchStrategy:"merge" patchMergeKey:"name" 
protobuf:"bytes,20,rep,name=initContainers"`
-       // List of containers belonging to the pod.
-       // Containers cannot currently be added or removed.
-       // There must be at least one container in a Pod.
-       // Cannot be updated.
-       // +optional
-       // +patchMergeKey=name
-       // +patchStrategy=merge
-       Containers []corev1.Container `json:"containers,omitempty" 
patchStrategy:"merge" patchMergeKey:"name" 
protobuf:"bytes,2,rep,name=containers"`
-       // Restart policy for all containers within the pod.
-       // One of Always, OnFailure, Never. In some contexts, only a subset of 
those values may be permitted.
-       // Default to Always.
-       // More info: 
https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy
-       // +optional
-       RestartPolicy corev1.RestartPolicy `json:"restartPolicy,omitempty" 
protobuf:"bytes,3,opt,name=restartPolicy,casttype=RestartPolicy"`
-       // Optional duration in seconds the pod needs to terminate gracefully. 
May be decreased in delete request.
-       // Value must be non-negative integer. The value zero indicates stop 
immediately via
-       // the kill signal (no opportunity to shut down).
-       // If this value is nil, the default grace period will be used instead.
-       // The grace period is the duration in seconds after the processes 
running in the pod are sent
-       // a termination signal and the time when the processes are forcibly 
halted with a kill signal.
-       // Set this value longer than the expected cleanup time for your 
process.
-       // Defaults to 30 seconds.
-       // +optional
-       TerminationGracePeriodSeconds *int64 
`json:"terminationGracePeriodSeconds,omitempty" 
protobuf:"varint,4,opt,name=terminationGracePeriodSeconds"`
-       // Optional duration in seconds the pod may be active on the node 
relative to
-       // StartTime before the system will actively try to mark it failed and 
kill associated containers.
-       // Value must be a positive integer.
-       // +optional
-       ActiveDeadlineSeconds *int64 `json:"activeDeadlineSeconds,omitempty" 
protobuf:"varint,5,opt,name=activeDeadlineSeconds"`
-       // Set DNS policy for the pod.
-       // Defaults to "ClusterFirst".
-       // Valid values are 'ClusterFirstWithHostNet', 'ClusterFirst', 
'Default' or 'None'.
-       // DNS parameters given in DNSConfig will be merged with the policy 
selected with DNSPolicy.
-       // To have DNS options set along with hostNetwork, you have to specify 
DNS policy
-       // explicitly to 'ClusterFirstWithHostNet'.
-       // +optional
-       DNSPolicy corev1.DNSPolicy `json:"dnsPolicy,omitempty" 
protobuf:"bytes,6,opt,name=dnsPolicy,casttype=DNSPolicy"`
-       // NodeSelector is a selector which must be true for the pod to fit on 
a node.
-       // Selector which must match a node's labels for the pod to be 
scheduled on that node.
-       // More info: 
https://kubernetes.io/docs/concepts/configuration/assign-pod-node/
-       // +optional
-       // +mapType=atomic
-       NodeSelector map[string]string `json:"nodeSelector,omitempty" 
protobuf:"bytes,7,rep,name=nodeSelector"`
-
-       // ServiceAccountName is the name of the ServiceAccount to use to run 
this pod.
-       // More info: 
https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/
-       // +optional
-       ServiceAccountName string `json:"serviceAccountName,omitempty" 
protobuf:"bytes,8,opt,name=serviceAccountName"`
-       // AutomountServiceAccountToken indicates whether a service account 
token should be automatically mounted.
-       // +optional
-       AutomountServiceAccountToken *bool 
`json:"automountServiceAccountToken,omitempty" 
protobuf:"varint,21,opt,name=automountServiceAccountToken"`
-
-       // NodeName is a request to schedule this pod onto a specific node. If 
it is non-empty,
-       // the scheduler simply schedules this pod onto that node, assuming 
that it fits resource
-       // requirements.
-       // +optional
-       NodeName string `json:"nodeName,omitempty" 
protobuf:"bytes,10,opt,name=nodeName"`
-       // Host networking requested for this pod. Use the host's network 
namespace.
-       // If this option is set, the ports that will be used must be specified.
-       // Default to false.
-       // +k8s:conversion-gen=false
-       // +optional
-       HostNetwork bool `json:"hostNetwork,omitempty" 
protobuf:"varint,11,opt,name=hostNetwork"`
-       // Use the host's pid namespace.
-       // Optional: Default to false.
-       // +k8s:conversion-gen=false
-       // +optional
-       HostPID bool `json:"hostPID,omitempty" 
protobuf:"varint,12,opt,name=hostPID"`
-       // Use the host's ipc namespace.
-       // Optional: Default to false.
-       // +k8s:conversion-gen=false
-       // +optional
-       HostIPC bool `json:"hostIPC,omitempty" 
protobuf:"varint,13,opt,name=hostIPC"`
-       // Share a single process namespace between all of the containers in a 
pod.
-       // When this is set containers will be able to view and signal 
processes from other containers
-       // in the same pod, and the first process in each container will not be 
assigned PID 1.
-       // HostPID and ShareProcessNamespace cannot both be set.
-       // Optional: Default to false.
-       // +k8s:conversion-gen=false
-       // +optional
-       ShareProcessNamespace *bool `json:"shareProcessNamespace,omitempty" 
protobuf:"varint,27,opt,name=shareProcessNamespace"`
-       // SecurityContext holds pod-level security attributes and common 
container settings.
-       // Optional: Defaults to empty.  See type description for default 
values of each field.
-       // +optional
-       SecurityContext *corev1.PodSecurityContext 
`json:"securityContext,omitempty" protobuf:"bytes,14,opt,name=securityContext"`
-       // ImagePullSecrets is an optional list of references to secrets in the 
same namespace to use for pulling any of the images used by this PodSpec.
-       // If specified, these secrets will be passed to individual puller 
implementations for them to use.
-       // More info: 
https://kubernetes.io/docs/concepts/containers/images#specifying-imagepullsecrets-on-a-pod
-       // +optional
-       // +patchMergeKey=name
-       // +patchStrategy=merge
-       ImagePullSecrets []corev1.LocalObjectReference 
`json:"imagePullSecrets,omitempty" patchStrategy:"merge" patchMergeKey:"name" 
protobuf:"bytes,15,rep,name=imagePullSecrets"`
-       // Specifies the hostname of the Pod
-       // If not specified, the pod's hostname will be set to a system-defined 
value.
-       // +optional
-       Hostname string `json:"hostname,omitempty" 
protobuf:"bytes,16,opt,name=hostname"`
-       // If specified, the fully qualified Pod hostname will be 
"<hostname>.<subdomain>.<pod namespace>.svc.<cluster domain>".
-       // If not specified, the pod will not have a domainname at all.
-       // +optional
-       Subdomain string `json:"subdomain,omitempty" 
protobuf:"bytes,17,opt,name=subdomain"`
-       // If specified, the pod's scheduling constraints
-       // +optional
-       Affinity *corev1.Affinity `json:"affinity,omitempty" 
protobuf:"bytes,18,opt,name=affinity"`
-       // If specified, the pod will be dispatched by specified scheduler.
-       // If not specified, the pod will be dispatched by default scheduler.
-       // +optional
-       SchedulerName string `json:"schedulerName,omitempty" 
protobuf:"bytes,19,opt,name=schedulerName"`
-       // If specified, the pod's tolerations.
-       // +optional
-       Tolerations []corev1.Toleration `json:"tolerations,omitempty" 
protobuf:"bytes,22,opt,name=tolerations"`
-       // HostAliases is an optional list of hosts and IPs that will be 
injected into the pod's hosts
-       // file if specified. This is only valid for non-hostNetwork pods.
-       // +optional
-       // +patchMergeKey=ip
-       // +patchStrategy=merge
-       HostAliases []corev1.HostAlias `json:"hostAliases,omitempty" 
patchStrategy:"merge" patchMergeKey:"ip" 
protobuf:"bytes,23,rep,name=hostAliases"`
-       // If specified, indicates the pod's priority. "system-node-critical" 
and
-       // "system-cluster-critical" are two special keywords which indicate the
-       // highest priorities with the former being the highest priority. Any 
other
-       // name must be defined by creating a PriorityClass object with that 
name.
-       // If not specified, the pod priority will be default or zero if there 
is no
-       // default.
-       // +optional
-       PriorityClassName string `json:"priorityClassName,omitempty" 
protobuf:"bytes,24,opt,name=priorityClassName"`
-       // The priority value. Various system components use this field to find 
the
-       // priority of the pod. When Priority Admission Controller is enabled, 
it
-       // prevents users from setting this field. The admission controller 
populates
-       // this field from PriorityClassName.
-       // The higher the value, the higher the priority.
-       // +optional
-       Priority *int32 `json:"priority,omitempty" 
protobuf:"bytes,25,opt,name=priority"`
-       // Specifies the DNS parameters of a pod.
-       // Parameters specified here will be merged to the generated DNS
-       // configuration based on DNSPolicy.
-       // +optional
-       DNSConfig *corev1.PodDNSConfig `json:"dnsConfig,omitempty" 
protobuf:"bytes,26,opt,name=dnsConfig"`
-       // If specified, all readiness gates will be evaluated for pod 
readiness.
-       // A pod is ready when all its containers are ready AND
-       // all conditions specified in the readiness gates have status equal to 
"True"
-       // More info: 
https://git.k8s.io/enhancements/keps/sig-network/580-pod-readiness-gates
-       // +optional
-       ReadinessGates []corev1.PodReadinessGate 
`json:"readinessGates,omitempty" protobuf:"bytes,28,opt,name=readinessGates"`
-       // RuntimeClassName refers to a RuntimeClass object in the node.k8s.io 
group, which should be used
-       // to run this pod.  If no RuntimeClass resource matches the named 
class, the pod will not be run.
-       // If unset or empty, the "legacy" RuntimeClass will be used, which is 
an implicit class with an
-       // empty definition that uses the default runtime handler.
-       // More info: 
https://git.k8s.io/enhancements/keps/sig-node/585-runtime-class
-       // +optional
-       RuntimeClassName *string `json:"runtimeClassName,omitempty" 
protobuf:"bytes,29,opt,name=runtimeClassName"`
-       // EnableServiceLinks indicates whether information about services 
should be injected into pod's
-       // environment variables, matching the syntax of Docker links.
-       // Optional: Defaults to true.
-       // +optional
-       EnableServiceLinks *bool `json:"enableServiceLinks,omitempty" 
protobuf:"varint,30,opt,name=enableServiceLinks"`
-       // PreemptionPolicy is the Policy for preempting pods with lower 
priority.
-       // One of Never, PreemptLowerPriority.
-       // Defaults to PreemptLowerPriority if unset.
-       // +optional
-       PreemptionPolicy *corev1.PreemptionPolicy 
`json:"preemptionPolicy,omitempty" 
protobuf:"bytes,31,opt,name=preemptionPolicy"`
-       // Overhead represents the resource overhead associated with running a 
pod for a given RuntimeClass.
-       // This field will be autopopulated at admission time by the 
RuntimeClass admission controller. If
-       // the RuntimeClass admission controller is enabled, overhead must not 
be set in Pod create requests.
-       // The RuntimeClass admission controller will reject Pod create 
requests which have the overhead already
-       // set. If RuntimeClass is configured and selected in the PodSpec, 
Overhead will be set to the value
-       // defined in the corresponding RuntimeClass, otherwise it will remain 
unset and treated as zero.
-       // More info: 
https://git.k8s.io/enhancements/keps/sig-node/688-pod-overhead/README.md
-       // +optional
-       Overhead corev1.ResourceList `json:"overhead,omitempty" 
protobuf:"bytes,32,opt,name=overhead"`
-       // TopologySpreadConstraints describes how a group of pods ought to 
spread across topology
-       // domains. Scheduler will schedule pods in a way which abides by the 
constraints.
-       // All topologySpreadConstraints are ANDed.
-       // +optional
-       // +patchMergeKey=topologyKey
-       // +patchStrategy=merge
-       // +listType=map
-       // +listMapKey=topologyKey
-       // +listMapKey=whenUnsatisfiable
-       TopologySpreadConstraints []corev1.TopologySpreadConstraint 
`json:"topologySpreadConstraints,omitempty" patchStrategy:"merge" 
patchMergeKey:"topologyKey" 
protobuf:"bytes,33,opt,name=topologySpreadConstraints"`
-       // If true the pod's hostname will be configured as the pod's FQDN, 
rather than the leaf name (the default).
-       // In Linux containers, this means setting the FQDN in the hostname 
field of the kernel (the nodename field of struct utsname).
-       // In Windows containers, this means setting the registry value of 
hostname for the registry key 
HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters to 
FQDN.
-       // If a pod does not have FQDN, this has no effect.
-       // Default to false.
-       // +optional
-       SetHostnameAsFQDN *bool `json:"setHostnameAsFQDN,omitempty" 
protobuf:"varint,35,opt,name=setHostnameAsFQDN"`
-       // Specifies the OS of the containers in the pod.
-       // Some pod and container fields are restricted if this is set.
-       //
-       // If the OS field is set to linux, the following fields must be unset:
-       // -securityContext.windowsOptions
-       //
-       // If the OS field is set to windows, following fields must be unset:
-       // - spec.hostPID
-       // - spec.hostIPC
-       // - spec.hostUsers
-       // - spec.securityContext.seLinuxOptions
-       // - spec.securityContext.seccompProfile
-       // - spec.securityContext.fsGroup
-       // - spec.securityContext.fsGroupChangePolicy
-       // - spec.securityContext.sysctls
-       // - spec.shareProcessNamespace
-       // - spec.securityContext.runAsUser
-       // - spec.securityContext.runAsGroup
-       // - spec.securityContext.supplementalGroups
-       // - spec.containers[*].securityContext.seLinuxOptions
-       // - spec.containers[*].securityContext.seccompProfile
-       // - spec.containers[*].securityContext.capabilities
-       // - spec.containers[*].securityContext.readOnlyRootFilesystem
-       // - spec.containers[*].securityContext.privileged
-       // - spec.containers[*].securityContext.allowPrivilegeEscalation
-       // - spec.containers[*].securityContext.procMount
-       // - spec.containers[*].securityContext.runAsUser
-       // - spec.containers[*].securityContext.runAsGroup
-       // +optional
-       OS *corev1.PodOS `json:"os,omitempty" protobuf:"bytes,36,opt,name=os"`
-
-       // Use the host's user namespace.
-       // Optional: Default to true.
-       // If set to true or not present, the pod will be run in the host user 
namespace, useful
-       // for when the pod needs a feature only available to the host user 
namespace, such as
-       // loading a kernel module with CAP_SYS_MODULE.
-       // When set to false, a new userns is created for the pod. Setting 
false is useful for
-       // mitigating container breakout vulnerabilities even allowing users to 
run their
-       // containers as root without actually having root privileges on the 
host.
-       // This field is alpha-level and is only honored by servers that enable 
the UserNamespacesSupport feature.
-       // +k8s:conversion-gen=false
-       // +optional
-       HostUsers *bool `json:"hostUsers,omitempty" 
protobuf:"bytes,37,opt,name=hostUsers"`
-
-       // SchedulingGates is an opaque list of values that if specified will 
block scheduling the pod.
-       // If schedulingGates is not empty, the pod will stay in the 
SchedulingGated state and the
-       // scheduler will not attempt to schedule the pod.
-       //
-       // SchedulingGates can only be set at pod creation time, and be removed 
only afterwards.
-       //
-       // This is a beta feature enabled by the PodSchedulingReadiness feature 
gate.
-       //
-       // +patchMergeKey=name
-       // +patchStrategy=merge
-       // +listType=map
-       // +listMapKey=name
-       // +featureGate=PodSchedulingReadiness
-       // +optional
-       SchedulingGates []corev1.PodSchedulingGate 
`json:"schedulingGates,omitempty" patchStrategy:"merge" patchMergeKey:"name" 
protobuf:"bytes,38,opt,name=schedulingGates"`
-       // ResourceClaims defines which ResourceClaims must be allocated
-       // and reserved before the Pod is allowed to start. The resources
-       // will be made available to those containers which consume them
-       // by name.
-       //
-       // This is an alpha field and requires enabling the
-       // DynamicResourceAllocation feature gate.
-       //
-       // This field is immutable.
-       //
-       // +patchMergeKey=name
-       // +patchStrategy=merge,retainKeys
-       // +listType=map
-       // +listMapKey=name
-       // +featureGate=DynamicResourceAllocation
-       // +optional
-       ResourceClaims []corev1.PodResourceClaim 
`json:"resourceClaims,omitempty" patchStrategy:"merge,retainKeys" 
patchMergeKey:"name" protobuf:"bytes,39,rep,name=resourceClaims"`
-}
-
-func (f *PodSpec) ToPodSpec() corev1.PodSpec {
-       return corev1.PodSpec{
-               Volumes:                       f.Volumes,
-               InitContainers:                f.InitContainers,
-               Containers:                    f.Containers,
-               RestartPolicy:                 f.RestartPolicy,
-               TerminationGracePeriodSeconds: f.TerminationGracePeriodSeconds,
-               ActiveDeadlineSeconds:         f.ActiveDeadlineSeconds,
-               DNSPolicy:                     f.DNSPolicy,
-               NodeSelector:                  f.NodeSelector,
-               ServiceAccountName:            f.ServiceAccountName,
-               AutomountServiceAccountToken:  f.AutomountServiceAccountToken,
-               NodeName:                      f.NodeName,
-               HostNetwork:                   f.HostNetwork,
-               HostPID:                       f.HostPID,
-               HostIPC:                       f.HostIPC,
-               ShareProcessNamespace:         f.ShareProcessNamespace,
-               SecurityContext:               f.SecurityContext,
-               ImagePullSecrets:              f.ImagePullSecrets,
-               Hostname:                      f.Hostname,
-               Subdomain:                     f.Subdomain,
-               Affinity:                      f.Affinity,
-               SchedulerName:                 f.SchedulerName,
-               Tolerations:                   f.Tolerations,
-               HostAliases:                   f.HostAliases,
-               PriorityClassName:             f.PriorityClassName,
-               Priority:                      f.Priority,
-               DNSConfig:                     f.DNSConfig,
-               ReadinessGates:                f.ReadinessGates,
-               RuntimeClassName:              f.RuntimeClassName,
-               EnableServiceLinks:            f.EnableServiceLinks,
-               PreemptionPolicy:              f.PreemptionPolicy,
-               Overhead:                      f.Overhead,
-               TopologySpreadConstraints:     f.TopologySpreadConstraints,
-               SetHostnameAsFQDN:             f.SetHostnameAsFQDN,
-               OS:                            f.OS,
-               HostUsers:                     f.HostUsers,
-               SchedulingGates:               f.SchedulingGates,
-               ResourceClaims:                f.ResourceClaims,
-       }
-}
+// DeploymentModel defines how a given pod will be deployed
+// +kubebuilder:validation:Enum=kubernetes;knative
+type DeploymentModel string
+
+const (
+       // KubernetesDeploymentModel defines a PodSpec to be deployed as a 
regular Kubernetes Deployment
+       KubernetesDeploymentModel DeploymentModel = "kubernetes"
+       // KnativeDeploymentModel defines a PodSpec to be deployed as a Knative 
Serving Service
+       KnativeDeploymentModel DeploymentModel = "knative"
+)
 
-// PodTemplateSpec describes the desired custom Kubernetes PodTemplate 
definition for the deployed flow or service.
-//
-// The ContainerSpec describes the container where the actual flow or service 
is running. It will override any default definitions.
-// For example, to override the image one can use 
`.spec.podTemplate.container.image = my/image:tag`.
-type PodTemplateSpec struct {
+// FlowPodTemplateSpec is a special PodTemplateSpec designed for SonataFlow 
deployments
+type FlowPodTemplateSpec struct {
        // Container is the Kubernetes container where the application should 
run.
        // One can change this attribute in order to override the defaults 
provided by the operator.
        // +optional
@@ -556,7 +51,11 @@ type PodTemplateSpec struct {
        // +optional
        PodSpec `json:",inline"`
        // +optional
+       // Replicas define the number of pods to start by default for this 
deployment model. Ignored in "knative" deployment model.
        Replicas *int32 `json:"replicas,omitempty"`
+       // Defines the kind of deployment model for this pod spec. In dev 
profile, only "kubernetes" is valid.
+       // +optional
+       DeploymentModel DeploymentModel `json:"deploymentModel,omitempty"`
 }
 
 // Flow describes the contents of the Workflow definition following the CNCF 
Serverless Workflow Specification.
@@ -656,7 +155,7 @@ type SonataFlowSpec struct {
        Resources WorkflowResources `json:"resources,omitempty"`
        // PodTemplate describes the deployment details of this SonataFlow 
instance.
        
//+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="podTemplate"
-       PodTemplate PodTemplateSpec `json:"podTemplate,omitempty"`
+       PodTemplate FlowPodTemplateSpec `json:"podTemplate,omitempty"`
        // Persistence defines the database persistence configuration for the 
workflow
        Persistence *PersistenceOptionsSpec `json:"persistence,omitempty"`
        // Sink describes the sinkBinding details of this SonataFlow instance.
@@ -752,6 +251,7 @@ func (s *SonataFlowStatus) IsBuildFailed() bool {
 // 
+kubebuilder:printcolumn:name="Reason",type=string,JSONPath=`.status.conditions[?(@.type=='Running')].reason`
 // 
+operator-sdk:csv:customresourcedefinitions:resources={{SonataFlowBuild,sonataflow.org/v1alpha08,"A
 SonataFlow Build"}}
 // 
+operator-sdk:csv:customresourcedefinitions:resources={{Deployment,apps/v1,"A 
Deployment for the Flow"}}
+// 
+operator-sdk:csv:customresourcedefinitions:resources={{Service,serving.knative.dev/v1,"A
 Knative Serving Service for the Flow"}}
 // +operator-sdk:csv:customresourcedefinitions:resources={{Service,v1,"A 
Service for the Flow"}}
 // 
+operator-sdk:csv:customresourcedefinitions:resources={{Route,route.openshift.io/v1,"An
 OpenShift Route for the Flow"}}
 // +operator-sdk:csv:customresourcedefinitions:resources={{ConfigMap,v1,"The 
ConfigMaps with Flow definition and additional configuration files"}}
@@ -763,6 +263,10 @@ type SonataFlow struct {
        Status SonataFlowStatus `json:"status,omitempty"`
 }
 
+func (s *SonataFlow) IsKnativeDeployment() bool {
+       return s.Spec.PodTemplate.DeploymentModel == KnativeDeploymentModel
+}
+
 func (s *SonataFlow) HasContainerSpecImage() bool {
        return len(s.Spec.PodTemplate.Container.Image) > 0
 }
diff --git a/api/v1alpha08/zz_generated.deepcopy.go 
b/api/v1alpha08/zz_generated.deepcopy.go
index c970b108..645d2b60 100644
--- a/api/v1alpha08/zz_generated.deepcopy.go
+++ b/api/v1alpha08/zz_generated.deepcopy.go
@@ -320,6 +320,28 @@ func (in *Flow) DeepCopy() *Flow {
        return out
 }
 
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, 
writing into out. in must be non-nil.
+func (in *FlowPodTemplateSpec) DeepCopyInto(out *FlowPodTemplateSpec) {
+       *out = *in
+       in.Container.DeepCopyInto(&out.Container)
+       in.PodSpec.DeepCopyInto(&out.PodSpec)
+       if in.Replicas != nil {
+               in, out := &in.Replicas, &out.Replicas
+               *out = new(int32)
+               **out = **in
+       }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, 
creating a new FlowPodTemplateSpec.
+func (in *FlowPodTemplateSpec) DeepCopy() *FlowPodTemplateSpec {
+       if in == nil {
+               return nil
+       }
+       out := new(FlowPodTemplateSpec)
+       in.DeepCopyInto(out)
+       return out
+}
+
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, 
writing into out. in must be non-nil.
 func (in *PersistenceOptionsSpec) DeepCopyInto(out *PersistenceOptionsSpec) {
        *out = *in
diff --git a/bundle/manifests/sonataflow-operator.clusterserviceversion.yaml 
b/bundle/manifests/sonataflow-operator.clusterserviceversion.yaml
index b71c508b..7e78264f 100644
--- a/bundle/manifests/sonataflow-operator.clusterserviceversion.yaml
+++ b/bundle/manifests/sonataflow-operator.clusterserviceversion.yaml
@@ -288,6 +288,9 @@ spec:
       - kind: Deployment
         name: A Deployment for the Flow
         version: apps/v1
+      - kind: Service
+        name: A Knative Serving Service for the Flow
+        version: serving.knative.dev/v1
       - kind: Service
         name: A Service for the Flow
         version: v1
@@ -437,6 +440,22 @@ spec:
           - patch
           - update
           - watch
+        - apiGroups:
+          - serving.knative.dev
+          resources:
+          - service
+          - services
+          - services/status
+          - services/finalizers
+          verbs:
+          - create
+          - delete
+          - deletecollection
+          - get
+          - list
+          - patch
+          - update
+          - watch
         - apiGroups:
           - coordination.k8s.io
           resources:
diff --git a/bundle/manifests/sonataflow.org_sonataflows.yaml 
b/bundle/manifests/sonataflow.org_sonataflows.yaml
index eaf80c91..6f2cb2e7 100644
--- a/bundle/manifests/sonataflow.org_sonataflows.yaml
+++ b/bundle/manifests/sonataflow.org_sonataflows.yaml
@@ -5626,6 +5626,13 @@ spec:
                       - name
                       type: object
                     type: array
+                  deploymentModel:
+                    description: Defines the kind of deployment model for this 
pod
+                      spec. In dev profile, only "kubernetes" is valid.
+                    enum:
+                    - kubernetes
+                    - knative
+                    type: string
                   dnsConfig:
                     description: Specifies the DNS parameters of a pod. 
Parameters
                       specified here will be merged to the generated DNS 
configuration
@@ -7153,6 +7160,8 @@ spec:
                       type: object
                     type: array
                   replicas:
+                    description: Replicas define the number of pods to start 
by default
+                      for this deployment model. Ignored in "knative" 
deployment model.
                     format: int32
                     type: integer
                   resourceClaims:
diff --git a/config/crd/bases/sonataflow.org_sonataflows.yaml 
b/config/crd/bases/sonataflow.org_sonataflows.yaml
index 1557c3b8..61002c32 100644
--- a/config/crd/bases/sonataflow.org_sonataflows.yaml
+++ b/config/crd/bases/sonataflow.org_sonataflows.yaml
@@ -5627,6 +5627,13 @@ spec:
                       - name
                       type: object
                     type: array
+                  deploymentModel:
+                    description: Defines the kind of deployment model for this 
pod
+                      spec. In dev profile, only "kubernetes" is valid.
+                    enum:
+                    - kubernetes
+                    - knative
+                    type: string
                   dnsConfig:
                     description: Specifies the DNS parameters of a pod. 
Parameters
                       specified here will be merged to the generated DNS 
configuration
@@ -7154,6 +7161,8 @@ spec:
                       type: object
                     type: array
                   replicas:
+                    description: Replicas define the number of pods to start 
by default
+                      for this deployment model. Ignored in "knative" 
deployment model.
                     format: int32
                     type: integer
                   resourceClaims:
diff --git 
a/config/manifests/bases/sonataflow-operator.clusterserviceversion.yaml 
b/config/manifests/bases/sonataflow-operator.clusterserviceversion.yaml
index c61183d8..c6fdf4e6 100644
--- a/config/manifests/bases/sonataflow-operator.clusterserviceversion.yaml
+++ b/config/manifests/bases/sonataflow-operator.clusterserviceversion.yaml
@@ -172,6 +172,9 @@ spec:
       - kind: Deployment
         name: A Deployment for the Flow
         version: apps/v1
+      - kind: Service
+        name: A Knative Serving Service for the Flow
+        version: serving.knative.dev/v1
       - kind: Service
         name: A Service for the Flow
         version: v1
diff --git a/config/rbac/builder_role.yaml b/config/rbac/builder_role.yaml
index 70b2ab54..ffced490 100644
--- a/config/rbac/builder_role.yaml
+++ b/config/rbac/builder_role.yaml
@@ -66,33 +66,3 @@ rules:
     - patch
     - update
     - watch
-- apiGroups:
-    - eventing.knative.dev
-  resources:
-    - triggers
-    - triggers/status
-    - triggers/finalizers
-  verbs:
-    - create
-    - delete
-    - deletecollection
-    - get
-    - list
-    - patch
-    - update
-    - watch
-- apiGroups:
-    - sources.knative.dev
-  resources:
-    - sinkbindings
-    - sinkbindings/status
-    - sinkbindings/finalizers
-  verbs:
-    - create
-    - delete
-    - deletecollection
-    - get
-    - list
-    - patch
-    - update
-    - watch
\ No newline at end of file
diff --git a/config/rbac/knative_role.yaml b/config/rbac/knative_role.yaml
new file mode 100644
index 00000000..8dad9419
--- /dev/null
+++ b/config/rbac/knative_role.yaml
@@ -0,0 +1,52 @@
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: knative-manager-role
+rules:
+  - apiGroups:
+      - eventing.knative.dev
+    resources:
+      - triggers
+      - triggers/status
+      - triggers/finalizers
+    verbs:
+      - create
+      - delete
+      - deletecollection
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - sources.knative.dev
+    resources:
+      - sinkbindings
+      - sinkbindings/status
+      - sinkbindings/finalizers
+    verbs:
+      - create
+      - delete
+      - deletecollection
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - serving.knative.dev
+    resources:
+      - service
+      - services
+      - services/status
+      - services/finalizers
+    verbs:
+      - create
+      - delete
+      - deletecollection
+      - get
+      - list
+      - patch
+      - update
+      - watch
diff --git a/config/rbac/knative_role_binding.yaml 
b/config/rbac/knative_role_binding.yaml
new file mode 100644
index 00000000..cbab613c
--- /dev/null
+++ b/config/rbac/knative_role_binding.yaml
@@ -0,0 +1,13 @@
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: knative-manager-rolebinding
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: knative-manager-role
+subjects:
+  - kind: ServiceAccount
+    name: controller-manager
+    namespace: system
diff --git a/config/rbac/kustomization.yaml b/config/rbac/kustomization.yaml
index 2ffd5efa..9a097cc2 100644
--- a/config/rbac/kustomization.yaml
+++ b/config/rbac/kustomization.yaml
@@ -17,6 +17,8 @@ resources:
 - operator_role_binding_leases.yaml
 - service_discovery_role.yaml
 - service_discovery_role_binding.yaml
+- knative_role.yaml
+- knative_role_binding.yaml
 # Comment the following 4 lines if you want to disable
 # the auth proxy (https://github.com/brancz/kube-rbac-proxy)
 # which protects your /metrics endpoint.
diff --git a/controllers/platform/k8s.go b/controllers/platform/k8s.go
index e4310de8..62d8b369 100644
--- a/controllers/platform/k8s.go
+++ b/controllers/platform/k8s.go
@@ -115,7 +115,7 @@ func createOrUpdateDeployment(ctx context.Context, client 
client.Client, platfor
                LivenessProbe:   liveProbe,
                Ports: []corev1.ContainerPort{
                        {
-                               Name:          utils.HttpScheme,
+                               Name:          utils.DefaultServicePortName,
                                ContainerPort: 
int32(constants.DefaultHTTPWorkflowPortInt),
                                Protocol:      corev1.ProtocolTCP,
                        },
@@ -199,7 +199,7 @@ func createOrUpdateService(ctx context.Context, client 
client.Client, platform *
        dataSvcSpec := corev1.ServiceSpec{
                Ports: []corev1.ServicePort{
                        {
-                               Name:       utils.HttpScheme,
+                               Name:       utils.DefaultServicePortName,
                                Protocol:   corev1.ProtocolTCP,
                                Port:       80,
                                TargetPort: 
variables.DefaultHTTPWorkflowPortIntStr,
diff --git a/controllers/profiles/common/deployment.go 
b/controllers/profiles/common/deployment_status_manager.go
similarity index 83%
rename from controllers/profiles/common/deployment.go
rename to controllers/profiles/common/deployment_status_manager.go
index 64b67767..6272d3f3 100644
--- a/controllers/profiles/common/deployment.go
+++ b/controllers/profiles/common/deployment_status_manager.go
@@ -26,7 +26,9 @@ import (
        appsv1 "k8s.io/api/apps/v1"
        "k8s.io/apimachinery/pkg/api/errors"
        metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+       "k8s.io/apimachinery/pkg/types"
        "k8s.io/klog/v2"
+       servingv1 "knative.dev/serving/pkg/apis/serving/v1"
        ctrl "sigs.k8s.io/controller-runtime"
        "sigs.k8s.io/controller-runtime/pkg/client"
 
@@ -39,6 +41,8 @@ import (
 
 var _ WorkflowDeploymentManager = &deploymentHandler{}
 
+const knativeDeploymentSuffix = "-deployment"
+
 // WorkflowDeploymentManager interface to handle workflow deployment features.
 type WorkflowDeploymentManager interface {
        // SyncDeploymentStatus updates the workflow status aligned with the 
deployment counterpart.
@@ -58,24 +62,42 @@ type deploymentHandler struct {
        c client.Client
 }
 
-func (d *deploymentHandler) RolloutDeployment(ctx context.Context, workflow 
*operatorapi.SonataFlow) error {
+func (d *deploymentHandler) getDeployment(ctx context.Context, workflow 
*operatorapi.SonataFlow) (*appsv1.Deployment, error) {
+       deploymentName := workflow.Name
+       if workflow.IsKnativeDeployment() {
+               ksvc := &servingv1.Service{}
+               if err := d.c.Get(ctx, client.ObjectKeyFromObject(workflow), 
ksvc); err != nil {
+                       if errors.IsNotFound(err) {
+                               return nil, nil
+                       }
+                       return nil, err
+               }
+               deploymentName = ksvc.Status.LatestCreatedRevisionName + 
knativeDeploymentSuffix
+       }
        deployment := &appsv1.Deployment{}
-       if err := d.c.Get(ctx, client.ObjectKeyFromObject(workflow), 
deployment); err != nil {
-               // Deployment not found, nothing to do.
+       if err := d.c.Get(ctx, types.NamespacedName{Namespace: 
workflow.Namespace, Name: deploymentName}, deployment); err != nil {
                if errors.IsNotFound(err) {
-                       return nil
+                       return nil, nil
                }
+               return nil, err
+       }
+       return deployment, nil
+}
+
+func (d *deploymentHandler) RolloutDeployment(ctx context.Context, workflow 
*operatorapi.SonataFlow) error {
+       deployment, err := d.getDeployment(ctx, workflow)
+       if err != nil || deployment == nil {
                return err
        }
-       if err := kubeutil.MarkDeploymentToRollout(deployment); err != nil {
+       if err = kubeutil.MarkDeploymentToRollout(deployment); err != nil {
                return err
        }
        return d.c.Update(ctx, deployment)
 }
 
 func (d *deploymentHandler) SyncDeploymentStatus(ctx context.Context, workflow 
*operatorapi.SonataFlow) (ctrl.Result, error) {
-       deployment := &appsv1.Deployment{}
-       if err := d.c.Get(ctx, client.ObjectKeyFromObject(workflow), 
deployment); err != nil {
+       deployment, err := d.getDeployment(ctx, workflow)
+       if err != nil || deployment == nil {
                // we should have the deployment by this time, so even if the 
error above is not found, we should halt.
                workflow.Status.Manager().MarkFalse(api.RunningConditionType, 
api.DeploymentUnavailableReason, "Couldn't find the workflow deployment")
                return ctrl.Result{RequeueAfter: 
constants.RequeueAfterFailure}, err
diff --git a/controllers/profiles/common/knative.go 
b/controllers/profiles/common/knative_eventing.go
similarity index 100%
rename from controllers/profiles/common/knative.go
rename to controllers/profiles/common/knative_eventing.go
diff --git a/controllers/profiles/common/mutate_visitors.go 
b/controllers/profiles/common/mutate_visitors.go
index eab1944b..426154ee 100644
--- a/controllers/profiles/common/mutate_visitors.go
+++ b/controllers/profiles/common/mutate_visitors.go
@@ -27,6 +27,7 @@ import (
        "github.com/imdario/mergo"
        appsv1 "k8s.io/api/apps/v1"
        corev1 "k8s.io/api/core/v1"
+       servingv1 "knative.dev/serving/pkg/apis/serving/v1"
        "sigs.k8s.io/controller-runtime/pkg/client"
        "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
 
@@ -55,6 +56,25 @@ func ImageDeploymentMutateVisitor(workflow 
*operatorapi.SonataFlow, image string
        }
 }
 
+// ImageKServiceMutateVisitor same as ImageDeploymentMutateVisitor for Knative 
Serving
+func ImageKServiceMutateVisitor(workflow *operatorapi.SonataFlow, image 
string) MutateVisitor {
+       return func(object client.Object) controllerutil.MutateFn {
+               // noop since we already have an image in the flow container 
defined by the user.
+               if workflow.HasContainerSpecImage() {
+                       return func() error {
+                               return nil
+                       }
+               }
+               return func() error {
+                       ksvc := object.(*servingv1.Service)
+                       _, idx := 
kubeutil.GetContainerByName(operatorapi.DefaultContainerName, 
&ksvc.Spec.Template.Spec.PodSpec)
+                       ksvc.Spec.Template.Spec.Containers[idx].Image = image
+                       ksvc.Spec.Template.Spec.Containers[idx].ImagePullPolicy 
= kubeutil.GetImagePullPolicy(image)
+                       return nil
+               }
+       }
+}
+
 // DeploymentMutateVisitor guarantees the state of the default Deployment 
object
 func DeploymentMutateVisitor(workflow *operatorapi.SonataFlow, plf 
*operatorapi.SonataFlowPlatform) MutateVisitor {
        return func(object client.Object) controllerutil.MutateFn {
@@ -87,6 +107,36 @@ func EnsureDeployment(original *appsv1.Deployment, object 
*appsv1.Deployment) er
        return mergo.Merge(&object.Spec.Template.Spec, 
original.Spec.Template.Spec, mergo.WithOverride)
 }
 
+// KServiceMutateVisitor guarantees the state of the default Knative Service 
object
+func KServiceMutateVisitor(workflow *operatorapi.SonataFlow, plf 
*operatorapi.SonataFlowPlatform) MutateVisitor {
+       return func(object client.Object) controllerutil.MutateFn {
+               return func() error {
+                       if kubeutil.IsObjectNew(object) {
+                               return nil
+                       }
+                       original, err := KServiceCreator(workflow, plf)
+                       if err != nil {
+                               return err
+                       }
+                       return EnsureKService(original.(*servingv1.Service), 
object.(*servingv1.Service))
+               }
+       }
+}
+
+// EnsureKService Ensure that the original Knative Service fields are 
immutable.
+func EnsureKService(original *servingv1.Service, object *servingv1.Service) 
error {
+       object.Labels = original.GetLabels()
+
+       // Clean up the volumes, they are inherited from original, additional 
are added by other visitors
+       object.Spec.Template.Spec.Volumes = nil
+       for i := range object.Spec.Template.Spec.Containers {
+               object.Spec.Template.Spec.Containers[i].VolumeMounts = nil
+       }
+
+       // we do a merge to not keep changing the spec since k8s will set 
default values to the podSpec
+       return mergo.Merge(&object.Spec.Template.Spec.PodSpec, 
original.Spec.Template.Spec.PodSpec, mergo.WithOverride)
+}
+
 func ServiceMutateVisitor(workflow *operatorapi.SonataFlow) MutateVisitor {
        return func(object client.Object) controllerutil.MutateFn {
                return func() error {
diff --git a/controllers/profiles/common/object_creators.go 
b/controllers/profiles/common/object_creators.go
index 8da5956d..c1ac6703 100644
--- a/controllers/profiles/common/object_creators.go
+++ b/controllers/profiles/common/object_creators.go
@@ -24,6 +24,7 @@ import (
        "strings"
 
        
"github.com/apache/incubator-kie-kogito-serverless-operator/controllers/workflowdef"
+       servingv1 "knative.dev/serving/pkg/apis/serving/v1"
 
        cncfmodel "github.com/serverlessworkflow/sdk-go/v2/model"
 
@@ -108,6 +109,41 @@ func DeploymentCreator(workflow *operatorapi.SonataFlow, 
plf *operatorapi.Sonata
        return deployment, nil
 }
 
+// KServiceCreator creates the default Knative Service object for SonataFlow 
instances. It's based on the default DeploymentCreator.
+func KServiceCreator(workflow *operatorapi.SonataFlow, plf 
*operatorapi.SonataFlowPlatform) (client.Object, error) {
+       lbl := workflowproj.GetMergedLabels(workflow)
+       ksvc := &servingv1.Service{
+               ObjectMeta: metav1.ObjectMeta{
+                       Name:      workflow.Name,
+                       Namespace: workflow.Namespace,
+                       Labels:    lbl,
+               },
+               Spec: servingv1.ServiceSpec{
+                       ConfigurationSpec: servingv1.ConfigurationSpec{
+                               Template: servingv1.RevisionTemplateSpec{
+                                       ObjectMeta: metav1.ObjectMeta{
+                                               Labels: lbl,
+                                       },
+                                       Spec: servingv1.RevisionSpec{
+                                               PodSpec: corev1.PodSpec{},
+                                       },
+                               },
+                       },
+               },
+       }
+
+       if err := mergo.Merge(&ksvc.Spec.Template.Spec.PodSpec, 
workflow.Spec.PodTemplate.PodSpec.ToPodSpec(), mergo.WithOverride); err != nil {
+               return nil, err
+       }
+       flowContainer, err := defaultContainer(workflow, plf)
+       if err != nil {
+               return nil, err
+       }
+       kubeutil.AddOrReplaceContainer(operatorapi.DefaultContainerName, 
*flowContainer, &ksvc.Spec.Template.Spec.PodSpec)
+
+       return ksvc, nil
+}
+
 func getReplicasOrDefault(workflow *operatorapi.SonataFlow) *int32 {
        var dReplicas int32 = 1
        if workflow.Spec.PodTemplate.Replicas == nil {
@@ -119,7 +155,7 @@ func getReplicasOrDefault(workflow *operatorapi.SonataFlow) 
*int32 {
 func defaultContainer(workflow *operatorapi.SonataFlow, plf 
*operatorapi.SonataFlowPlatform) (*corev1.Container, error) {
        defaultContainerPort := corev1.ContainerPort{
                ContainerPort: variables.DefaultHTTPWorkflowPortIntStr.IntVal,
-               Name:          utils.HttpScheme,
+               Name:          utils.DefaultServicePortName,
                Protocol:      corev1.ProtocolTCP,
        }
        defaultFlowContainer := &corev1.Container{
@@ -134,6 +170,7 @@ func defaultContainer(workflow *operatorapi.SonataFlow, plf 
*operatorapi.SonataF
                                },
                        },
                        TimeoutSeconds: healthTimeoutSeconds,
+                       PeriodSeconds:  healthStartedPeriodSeconds,
                },
                ReadinessProbe: &corev1.Probe{
                        ProbeHandler: corev1.ProbeHandler{
@@ -143,6 +180,7 @@ func defaultContainer(workflow *operatorapi.SonataFlow, plf 
*operatorapi.SonataF
                                },
                        },
                        TimeoutSeconds: healthTimeoutSeconds,
+                       PeriodSeconds:  healthStartedPeriodSeconds,
                },
                StartupProbe: &corev1.Probe{
                        ProbeHandler: corev1.ProbeHandler{
@@ -173,7 +211,7 @@ func defaultContainer(workflow *operatorapi.SonataFlow, plf 
*operatorapi.SonataF
        defaultFlowContainer.Name = operatorapi.DefaultContainerName
        portIdx := -1
        for i := range defaultFlowContainer.Ports {
-               if defaultFlowContainer.Ports[i].Name == utils.HttpScheme ||
+               if defaultFlowContainer.Ports[i].Name == 
utils.DefaultServicePortName ||
                        defaultFlowContainer.Ports[i].ContainerPort == 
variables.DefaultHTTPWorkflowPortIntStr.IntVal {
                        portIdx = i
                        break
diff --git a/controllers/profiles/common/object_creators_test.go 
b/controllers/profiles/common/object_creators_test.go
index 26b54999..8b42e5fc 100644
--- a/controllers/profiles/common/object_creators_test.go
+++ b/controllers/profiles/common/object_creators_test.go
@@ -94,13 +94,13 @@ func 
Test_ensureWorkflowPropertiesConfigMapMutator_DollarReplacement(t *testing.
 
 func TestMergePodSpec(t *testing.T) {
        workflow := test.GetBaseSonataFlow(t.Name())
-       workflow.Spec.PodTemplate = v1alpha08.PodTemplateSpec{
+       workflow.Spec.PodTemplate = v1alpha08.FlowPodTemplateSpec{
                Container: v1alpha08.ContainerSpec{
                        // this one we can override
                        Image: "quay.io/example/my-workflow:1.0.0",
                        Ports: []corev1.ContainerPort{
                                // let's override a immutable attribute
-                               {Name: utils.HttpScheme, ContainerPort: 9090},
+                               {Name: utils.DefaultServicePortName, 
ContainerPort: 9090},
                        },
                        Env: []corev1.EnvVar{
                                // We should be able to override this too
@@ -147,7 +147,7 @@ func TestMergePodSpec(t *testing.T) {
 
 func TestMergePodSpec_OverrideContainers(t *testing.T) {
        workflow := test.GetBaseSonataFlow(t.Name())
-       workflow.Spec.PodTemplate = v1alpha08.PodTemplateSpec{
+       workflow.Spec.PodTemplate = v1alpha08.FlowPodTemplateSpec{
                PodSpec: v1alpha08.PodSpec{
                        // Try to override the workflow container via the 
podspec
                        Containers: []corev1.Container{
@@ -155,7 +155,7 @@ func TestMergePodSpec_OverrideContainers(t *testing.T) {
                                        Name:  v1alpha08.DefaultContainerName,
                                        Image: 
"quay.io/example/my-workflow:1.0.0",
                                        Ports: []corev1.ContainerPort{
-                                               {Name: utils.HttpScheme, 
ContainerPort: 9090},
+                                               {Name: 
utils.DefaultServicePortName, ContainerPort: 9090},
                                        },
                                        Env: []corev1.EnvVar{
                                                {Name: "ENV1", Value: 
"VALUE_CUSTOM"},
@@ -213,13 +213,13 @@ func Test_ensureWorkflowTriggersAreCreated(t *testing.T) {
 func TestMergePodSpec_WithPostgreSQL_and_JDBC_URL_field(t *testing.T) {
        workflow := test.GetBaseSonataFlow(t.Name())
        workflow.Spec = v1alpha08.SonataFlowSpec{
-               PodTemplate: v1alpha08.PodTemplateSpec{
+               PodTemplate: v1alpha08.FlowPodTemplateSpec{
                        Container: v1alpha08.ContainerSpec{
                                // this one we can override
                                Image: "quay.io/example/my-workflow:1.0.0",
                                Ports: []corev1.ContainerPort{
                                        // let's override a immutable attribute
-                                       {Name: utils.HttpScheme, ContainerPort: 
9090},
+                                       {Name: utils.DefaultServicePortName, 
ContainerPort: 9090},
                                },
                                Env: []corev1.EnvVar{
                                        // We should be able to override this 
too
@@ -321,7 +321,7 @@ var (
 func TestMergePodSpec_OverrideContainers_WithPostgreSQL_In_Workflow_CR(t 
*testing.T) {
        workflow := test.GetBaseSonataFlow(t.Name())
        workflow.Spec = v1alpha08.SonataFlowSpec{
-               PodTemplate: v1alpha08.PodTemplateSpec{
+               PodTemplate: v1alpha08.FlowPodTemplateSpec{
                        PodSpec: v1alpha08.PodSpec{
                                // Try to override the workflow container via 
the podspec
                                Containers: []corev1.Container{
@@ -329,7 +329,7 @@ func 
TestMergePodSpec_OverrideContainers_WithPostgreSQL_In_Workflow_CR(t *testin
                                                Name:  
v1alpha08.DefaultContainerName,
                                                Image: 
"quay.io/example/my-workflow:1.0.0",
                                                Ports: []corev1.ContainerPort{
-                                                       {Name: 
utils.HttpScheme, ContainerPort: 9090},
+                                                       {Name: 
utils.DefaultServicePortName, ContainerPort: 9090},
                                                },
                                                Env: []corev1.EnvVar{
                                                        {Name: "ENV1", Value: 
"VALUE_CUSTOM"},
@@ -510,7 +510,7 @@ func 
TestMergePodSpec_WithServicedPostgreSQL_In_Platform_And_In_Workflow_CR(t *t
        }
        workflow := test.GetBaseSonataFlow(t.Name())
        workflow.Spec = v1alpha08.SonataFlowSpec{
-               PodTemplate: v1alpha08.PodTemplateSpec{
+               PodTemplate: v1alpha08.FlowPodTemplateSpec{
                        PodSpec: v1alpha08.PodSpec{
                                // Try to override the workflow container via 
the podspec
                                Containers: []corev1.Container{
@@ -518,7 +518,7 @@ func 
TestMergePodSpec_WithServicedPostgreSQL_In_Platform_And_In_Workflow_CR(t *t
                                                Name:  
v1alpha08.DefaultContainerName,
                                                Image: 
"quay.io/example/my-workflow:1.0.0",
                                                Ports: []corev1.ContainerPort{
-                                                       {Name: 
utils.HttpScheme, ContainerPort: 9090},
+                                                       {Name: 
utils.DefaultServicePortName, ContainerPort: 9090},
                                                },
                                                Env: []corev1.EnvVar{
                                                        {Name: "ENV1", Value: 
"VALUE_CUSTOM"},
diff --git a/controllers/profiles/common/persistence/postgresql.go 
b/controllers/profiles/common/persistence/postgresql.go
index 4bb5f38d..e88a3425 100644
--- a/controllers/profiles/common/persistence/postgresql.go
+++ b/controllers/profiles/common/persistence/postgresql.go
@@ -25,20 +25,7 @@ import (
 )
 
 const (
-       defaultDatabaseName  = "sonataflow"
-       timeoutSeconds       = 3
-       failureThreshold     = 5
-       initialPeriodSeconds = 15
-       initialDelaySeconds  = 10
-       successThreshold     = 1
-
-       postgreSQLCPULimit      = "500m"
-       postgreSQLMemoryLimit   = "256Mi"
-       postgreSQLMemoryRequest = "256Mi"
-       postgreSQLCPURequest    = "100m"
-
-       defaultPostgreSQLUsername  = "sonataflow"
-       defaultPostgresSQLPassword = "sonataflow"
+       defaultDatabaseName = "sonataflow"
 )
 
 func ConfigurePostgreSQLEnv(postgresql *operatorapi.PersistencePostgreSQL, 
databaseSchema, databaseNamespace string) []corev1.EnvVar {
diff --git a/controllers/profiles/dev/object_creators_dev.go 
b/controllers/profiles/dev/object_creators_dev.go
index 45f6926c..0f6069f1 100644
--- a/controllers/profiles/dev/object_creators_dev.go
+++ b/controllers/profiles/dev/object_creators_dev.go
@@ -90,8 +90,7 @@ func deploymentMutateVisitor(workflow 
*operatorapi.SonataFlow, plf *operatorapi.
                        if err != nil {
                                return err
                        }
-                       common.EnsureDeployment(original.(*appsv1.Deployment), 
object.(*appsv1.Deployment))
-                       return nil
+                       return 
common.EnsureDeployment(original.(*appsv1.Deployment), 
object.(*appsv1.Deployment))
                }
        }
 }
diff --git a/controllers/profiles/factory/factory.go 
b/controllers/profiles/factory/factory.go
index d54b0df3..511c6ca3 100644
--- a/controllers/profiles/factory/factory.go
+++ b/controllers/profiles/factory/factory.go
@@ -34,10 +34,6 @@ import (
        
"github.com/apache/incubator-kie-kogito-serverless-operator/controllers/profiles/dev"
 )
 
-const (
-       defaultProfile = metadata.PreviewProfile
-)
-
 type reconcilerBuilder func(client client.Client, cfg *rest.Config, recorder 
record.EventRecorder) profiles.ProfileReconciler
 
 var profileBuilders = map[metadata.ProfileType]reconcilerBuilder{
@@ -47,25 +43,22 @@ var profileBuilders = 
map[metadata.ProfileType]reconcilerBuilder{
 }
 
 func profileBuilder(workflow *operatorapi.SonataFlow) reconcilerBuilder {
-       profile := workflow.Annotations[metadata.Profile]
-       if len(profile) == 0 {
-               profile = defaultProfile.String()
-       }
+       profile := metadata.GetProfileOrDefault(workflow.Annotations)
        // keep backward compatibility
-       if profile == metadata.ProdProfile.String() {
+       if profile == metadata.ProdProfile {
                klog.V(log.W).Infof("Profile %s is deprecated, please use '%s' 
instead.", metadata.ProdProfile, metadata.PreviewProfile)
-               profile = metadata.PreviewProfile.String()
+               profile = metadata.PreviewProfile
        }
        // 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() {
+       if (profile == metadata.PreviewProfile || profile == 
metadata.ProdProfile) && 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]
+       if _, ok := profileBuilders[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, metadata.DefaultProfile)
+               return profileBuilders[metadata.DefaultProfile]
        }
-       return profileBuilders[metadata.ProfileType(profile)]
+       return profileBuilders[profile]
 }
 
 // NewReconciler creates a new ProfileReconciler based on the given workflow 
and context.
diff --git a/controllers/profiles/gitops/profile_gitops_test.go 
b/controllers/profiles/gitops/profile_gitops_test.go
index 9287cbc2..051ea577 100644
--- a/controllers/profiles/gitops/profile_gitops_test.go
+++ b/controllers/profiles/gitops/profile_gitops_test.go
@@ -29,7 +29,7 @@ import (
 )
 
 func Test_Reconciler_ProdOps(t *testing.T) {
-       workflow := test.GetBaseSonataFlowWithProdOpsProfile(t.Name())
+       workflow := test.GetBaseSonataFlowWithPreviewProfile(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",
diff --git a/controllers/profiles/preview/deployment_handler.go 
b/controllers/profiles/preview/deployment_handler.go
index 5fce2688..dfbac253 100644
--- a/controllers/profiles/preview/deployment_handler.go
+++ b/controllers/profiles/preview/deployment_handler.go
@@ -17,8 +17,8 @@ package preview
 import (
        "context"
 
+       
"github.com/apache/incubator-kie-kogito-serverless-operator/controllers/knative"
        v1 "k8s.io/api/core/v1"
-       ctrl "sigs.k8s.io/controller-runtime"
        "sigs.k8s.io/controller-runtime/pkg/client"
        "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
        "sigs.k8s.io/controller-runtime/pkg/reconcile"
@@ -44,81 +44,117 @@ func NewDeploymentReconciler(stateSupport 
*common.StateSupport, ensurer *ObjectE
 }
 
 func (d *DeploymentReconciler) Reconcile(ctx context.Context, workflow 
*operatorapi.SonataFlow) (reconcile.Result, []client.Object, error) {
-       return d.reconcileWithBuiltImage(ctx, workflow, "")
+       return d.reconcileWithImage(ctx, workflow, "")
 }
 
-func (d *DeploymentReconciler) reconcileWithBuiltImage(ctx context.Context, 
workflow *operatorapi.SonataFlow, image string) (reconcile.Result, 
[]client.Object, error) {
+func (d *DeploymentReconciler) reconcileWithImage(ctx context.Context, 
workflow *operatorapi.SonataFlow, image string) (reconcile.Result, 
[]client.Object, error) {
+       // Checks if we need Knative installed and is not present.
+       if requires, err := d.ensureKnativeServingRequired(workflow); requires 
|| err != nil {
+               return reconcile.Result{Requeue: false}, nil, err
+       }
+
+       // Ensure objects
+       result, objs, err := d.ensureObjects(ctx, workflow, image)
+       if err != nil || result.Requeue {
+               return result, objs, err
+       }
+
+       // Follow deployment status
+       result, err = common.DeploymentManager(d.C).SyncDeploymentStatus(ctx, 
workflow)
+       if err != nil {
+               return reconcile.Result{Requeue: false}, nil, err
+       }
+
+       if _, err := d.PerformStatusUpdate(ctx, workflow); err != nil {
+               return reconcile.Result{Requeue: false}, nil, err
+       }
+       return result, objs, nil
+}
+
+// ensureKnativeServingRequired returns true if the SonataFlow instance 
requires Knative deployment and Knative Serving is not available.
+func (d *DeploymentReconciler) ensureKnativeServingRequired(workflow 
*operatorapi.SonataFlow) (bool, error) {
+       if workflow.IsKnativeDeployment() {
+               avail, err := knative.GetKnativeAvailability(d.Cfg)
+               if err != nil {
+                       return true, err
+               }
+               if !avail.Serving {
+                       d.Recorder.Eventf(workflow, v1.EventTypeWarning,
+                               "KnativeServingNotAvailable",
+                               "Knative Serving is not available in this 
cluster, can't deploy workflow. Please update the deployment model to %s",
+                               operatorapi.KubernetesDeploymentModel)
+                       return true, nil
+               }
+       }
+       return false, nil
+}
+
+func (d *DeploymentReconciler) ensureObjects(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 {
                workflow.Status.Manager().MarkFalse(api.RunningConditionType, 
api.ExternalResourcesNotFoundReason, "Unable to retrieve the user properties 
config map")
-               _, err = d.PerformStatusUpdate(ctx, workflow)
-               return ctrl.Result{}, nil, err
+               _, _ = d.PerformStatusUpdate(ctx, workflow)
+               return reconcile.Result{}, nil, err
        }
        managedPropsCM, _, err := d.ensurers.managedPropsConfigMap.Ensure(ctx, 
workflow, pl,
                common.ManagedPropertiesMutateVisitor(ctx, 
d.StateSupport.Catalog, workflow, pl, userPropsCM.(*v1.ConfigMap)))
        if err != nil {
                workflow.Status.Manager().MarkFalse(api.RunningConditionType, 
api.ExternalResourcesNotFoundReason, "Unable to retrieve the managed properties 
config map")
-               _, err = d.PerformStatusUpdate(ctx, workflow)
-               return ctrl.Result{}, nil, err
+               _, _ = d.PerformStatusUpdate(ctx, workflow)
+               return reconcile.Result{}, nil, err
        }
 
        deployment, deploymentOp, err :=
-               d.ensurers.deployment.Ensure(
-                       ctx,
-                       workflow,
-                       pl,
-                       d.getDeploymentMutateVisitors(workflow, pl, image, 
userPropsCM.(*v1.ConfigMap), managedPropsCM.(*v1.ConfigMap))...,
-               )
+               d.ensurers.DeploymentByDeploymentModel(workflow).Ensure(ctx, 
workflow, pl,
+                       d.deploymentModelMutateVisitors(workflow, pl, image, 
userPropsCM.(*v1.ConfigMap), managedPropsCM.(*v1.ConfigMap))...)
        if err != nil {
                workflow.Status.Manager().MarkFalse(api.RunningConditionType, 
api.DeploymentUnavailableReason, "Unable to perform the deploy due to ", err)
-               _, err = d.PerformStatusUpdate(ctx, workflow)
+               _, _ = d.PerformStatusUpdate(ctx, workflow)
                return reconcile.Result{}, nil, err
        }
 
-       service, _, err := d.ensurers.service.Ensure(ctx, workflow, 
common.ServiceMutateVisitor(workflow))
+       service, _, err := 
d.ensurers.ServiceByDeploymentModel(workflow).Ensure(ctx, workflow, 
common.ServiceMutateVisitor(workflow))
        if err != nil {
                workflow.Status.Manager().MarkFalse(api.RunningConditionType, 
api.DeploymentUnavailableReason, "Unable to make the service available due to 
", err)
-               _, err = d.PerformStatusUpdate(ctx, workflow)
+               _, _ = d.PerformStatusUpdate(ctx, workflow)
                return reconcile.Result{}, nil, err
        }
 
-       knativeObjs, err := 
common.NewKnativeEventingHandler(d.StateSupport).Ensure(ctx, workflow)
+       eventingObjs, err := 
common.NewKnativeEventingHandler(d.StateSupport).Ensure(ctx, workflow)
        if err != nil {
-               return ctrl.Result{RequeueAfter: 
constants.RequeueAfterFailure}, nil, err
+               return reconcile.Result{}, nil, err
        }
-       objs := []client.Object{deployment, service, managedPropsCM}
-       objs = append(objs, knativeObjs...)
 
+       objs := []client.Object{deployment, managedPropsCM, service}
        if deploymentOp == controllerutil.OperationResultCreated {
                workflow.Status.Manager().MarkFalse(api.RunningConditionType, 
api.WaitingForDeploymentReason, "")
                if _, err := d.PerformStatusUpdate(ctx, workflow); err != nil {
-                       return reconcile.Result{Requeue: false}, nil, err
+                       return reconcile.Result{}, nil, err
                }
                return reconcile.Result{RequeueAfter: 
constants.RequeueAfterFollowDeployment, Requeue: true}, objs, nil
        }
+       objs = append(objs, eventingObjs...)
 
-       // Follow deployment status
-       result, err := common.DeploymentManager(d.C).SyncDeploymentStatus(ctx, 
workflow)
-       if err != nil {
-               return reconcile.Result{Requeue: false}, nil, err
-       }
-
-       if _, err := d.PerformStatusUpdate(ctx, workflow); err != nil {
-               return reconcile.Result{Requeue: false}, nil, err
-       }
-       return result, objs, nil
+       return reconcile.Result{}, objs, nil
 }
 
-func (d *DeploymentReconciler) getDeploymentMutateVisitors(
+func (d *DeploymentReconciler) deploymentModelMutateVisitors(
        workflow *operatorapi.SonataFlow,
        plf *operatorapi.SonataFlowPlatform,
        image string,
        userPropsCM *v1.ConfigMap,
        managedPropsCM *v1.ConfigMap) []common.MutateVisitor {
+
+       if workflow.IsKnativeDeployment() {
+               return 
[]common.MutateVisitor{common.KServiceMutateVisitor(workflow, plf),
+                       common.ImageKServiceMutateVisitor(workflow, image),
+                       mountConfigMapsMutateVisitor(workflow, userPropsCM, 
managedPropsCM)}
+       }
+
        if utils.IsOpenShift() {
                return 
[]common.MutateVisitor{common.DeploymentMutateVisitor(workflow, plf),
-                       mountProdConfigMapsMutateVisitor(workflow, userPropsCM, 
managedPropsCM),
+                       mountConfigMapsMutateVisitor(workflow, userPropsCM, 
managedPropsCM),
                        
addOpenShiftImageTriggerDeploymentMutateVisitor(workflow, image),
                        common.ImageDeploymentMutateVisitor(workflow, image),
                        
common.RolloutDeploymentIfCMChangedMutateVisitor(workflow, userPropsCM, 
managedPropsCM),
@@ -126,6 +162,6 @@ func (d *DeploymentReconciler) getDeploymentMutateVisitors(
        }
        return []common.MutateVisitor{common.DeploymentMutateVisitor(workflow, 
plf),
                common.ImageDeploymentMutateVisitor(workflow, image),
-               mountProdConfigMapsMutateVisitor(workflow, userPropsCM, 
managedPropsCM),
+               mountConfigMapsMutateVisitor(workflow, userPropsCM, 
managedPropsCM),
                common.RolloutDeploymentIfCMChangedMutateVisitor(workflow, 
userPropsCM, managedPropsCM)}
 }
diff --git a/controllers/profiles/preview/deployment_handler_test.go 
b/controllers/profiles/preview/deployment_handler_test.go
index d70436d7..5faf98bb 100644
--- a/controllers/profiles/preview/deployment_handler_test.go
+++ b/controllers/profiles/preview/deployment_handler_test.go
@@ -28,10 +28,42 @@ import (
        corev1 "k8s.io/api/core/v1"
        "k8s.io/apimachinery/pkg/types"
        utilruntime "k8s.io/apimachinery/pkg/util/runtime"
+       servingv1 "knative.dev/serving/pkg/apis/serving/v1"
 )
 
+type fakeDeploymentReconciler struct {
+       DeploymentReconciler
+}
+
+func Test_CheckDeploymentModelIsKnative(t *testing.T) {
+       workflow := test.GetBaseSonataFlowWithPreviewProfile(t.Name())
+       workflow.Spec.PodTemplate.DeploymentModel = 
v1alpha08.KnativeDeploymentModel
+
+       cli := test.NewSonataFlowClientBuilderWithKnative().
+               WithRuntimeObjects(workflow).
+               WithStatusSubresource(workflow).
+               Build()
+       stateSupport := fakeReconcilerSupport(cli)
+       handler := NewDeploymentReconciler(stateSupport, 
NewObjectEnsurers(stateSupport))
+
+       result, objects, err := handler.ensureObjects(context.TODO(), workflow, 
"")
+       assert.NoError(t, err)
+       assert.NotEmpty(t, objects)
+       assert.True(t, result.Requeue)
+
+       var ksvc *servingv1.Service
+       for _, o := range objects {
+               if _, ok := o.(*servingv1.Service); ok {
+                       ksvc = o.(*servingv1.Service)
+                       assert.Equal(t, v1alpha08.DefaultContainerName, 
ksvc.Spec.Template.Spec.Containers[0].Name)
+                       break
+               }
+       }
+       assert.NotNil(t, ksvc)
+}
+
 func Test_CheckPodTemplateChangesReflectDeployment(t *testing.T) {
-       workflow := test.GetBaseSonataFlowWithProdOpsProfile(t.Name())
+       workflow := test.GetBaseSonataFlowWithPreviewProfile(t.Name())
 
        client := test.NewSonataFlowClientBuilder().
                WithRuntimeObjects(workflow).
@@ -53,18 +85,20 @@ func Test_CheckPodTemplateChangesReflectDeployment(t 
*testing.T) {
        assert.NoError(t, err)
        assert.NotEmpty(t, objects)
        assert.True(t, result.Requeue)
+       var deployment *v1.Deployment
        for _, o := range objects {
                if _, ok := o.(*v1.Deployment); ok {
-                       deployment := o.(*v1.Deployment)
+                       deployment = o.(*v1.Deployment)
                        assert.Equal(t, expectedImg, 
deployment.Spec.Template.Spec.Containers[0].Image)
                        assert.Equal(t, v1alpha08.DefaultContainerName, 
deployment.Spec.Template.Spec.Containers[0].Name)
                        break
                }
        }
+       assert.NotNil(t, deployment)
 }
 
 func Test_CheckDeploymentRolloutAfterCMChange(t *testing.T) {
-       workflow := test.GetBaseSonataFlowWithProdOpsProfile(t.Name())
+       workflow := test.GetBaseSonataFlowWithPreviewProfile(t.Name())
 
        client := test.NewSonataFlowClientBuilder().
                WithRuntimeObjects(workflow).
@@ -126,7 +160,7 @@ func Test_CheckDeploymentRolloutAfterCMChange(t *testing.T) 
{
 }
 
 func Test_CheckDeploymentUnchangedAfterCMChangeOtherKeys(t *testing.T) {
-       workflow := test.GetBaseSonataFlowWithProdOpsProfile(t.Name())
+       workflow := test.GetBaseSonataFlowWithPreviewProfile(t.Name())
 
        client := test.NewSonataFlowClientBuilder().
                WithRuntimeObjects(workflow).
diff --git a/controllers/profiles/preview/object_creators_preview.go 
b/controllers/profiles/preview/object_creators_preview.go
index 903cd741..a48a4e5d 100644
--- a/controllers/profiles/preview/object_creators_preview.go
+++ b/controllers/profiles/preview/object_creators_preview.go
@@ -24,6 +24,7 @@ import (
 
        appsv1 "k8s.io/api/apps/v1"
        v1 "k8s.io/api/core/v1"
+       servingv1 "knative.dev/serving/pkg/apis/serving/v1"
        "sigs.k8s.io/controller-runtime/pkg/client"
        "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
 
@@ -64,28 +65,40 @@ func 
addOpenShiftImageTriggerDeploymentMutateVisitor(workflow *v1alpha08.SonataF
        }
 }
 
-// mountDevConfigMapsMutateVisitor mounts the required configMaps in the 
Workflow Dev Deployment
-func mountProdConfigMapsMutateVisitor(workflow *operatorapi.SonataFlow, 
userPropsCM *v1.ConfigMap, managedPropsCM *v1.ConfigMap) common.MutateVisitor {
+// mountConfigMapsMutateVisitor mounts the required configMaps in the 
SonataFlow instance
+func mountConfigMapsMutateVisitor(workflow *operatorapi.SonataFlow, 
userPropsCM *v1.ConfigMap, managedPropsCM *v1.ConfigMap) common.MutateVisitor {
        return func(object client.Object) controllerutil.MutateFn {
                return func() error {
-                       deployment := object.(*appsv1.Deployment)
-                       _, idx := 
kubeutil.GetContainerByName(v1alpha08.DefaultContainerName, 
&deployment.Spec.Template.Spec)
+                       var podTemplateSpec *v1.PodSpec
 
-                       if len(deployment.Spec.Template.Spec.Volumes) == 0 {
-                               deployment.Spec.Template.Spec.Volumes = 
make([]v1.Volume, 0, 1)
+                       if workflow.IsKnativeDeployment() {
+                               ksvc := object.(*servingv1.Service)
+                               podTemplateSpec = 
&ksvc.Spec.Template.Spec.PodSpec
+                       } else {
+                               deployment := object.(*appsv1.Deployment)
+                               podTemplateSpec = &deployment.Spec.Template.Spec
+                               if err := 
kubeutil.AnnotateDeploymentConfigChecksum(workflow, deployment, userPropsCM, 
managedPropsCM); err != nil {
+                                       return err
+                               }
                        }
-                       if 
len(deployment.Spec.Template.Spec.Containers[idx].VolumeMounts) == 0 {
-                               
deployment.Spec.Template.Spec.Containers[idx].VolumeMounts = 
make([]v1.VolumeMount, 0, 1)
+
+                       _, idx := 
kubeutil.GetContainerByName(v1alpha08.DefaultContainerName, podTemplateSpec)
+
+                       if len(podTemplateSpec.Volumes) == 0 {
+                               podTemplateSpec.Volumes = make([]v1.Volume, 0, 
1)
+                       }
+                       if len(podTemplateSpec.Containers[idx].VolumeMounts) == 
0 {
+                               podTemplateSpec.Containers[idx].VolumeMounts = 
make([]v1.VolumeMount, 0, 1)
                        }
 
                        defaultResourcesVolume := v1.Volume{Name: 
constants.ConfigMapWorkflowPropsVolumeName, VolumeSource: 
v1.VolumeSource{Projected: &v1.ProjectedVolumeSource{}}}
                        
kubeutil.VolumeProjectionAddConfigMap(defaultResourcesVolume.Projected, 
userPropsCM.Name, v1.KeyToPath{Key: workflowproj.ApplicationPropertiesFileName, 
Path: workflowproj.ApplicationPropertiesFileName})
                        
kubeutil.VolumeProjectionAddConfigMap(defaultResourcesVolume.Projected, 
managedPropsCM.Name, v1.KeyToPath{Key: 
workflowproj.GetManagedPropertiesFileName(workflow), Path: 
workflowproj.GetManagedPropertiesFileName(workflow)})
-                       
kubeutil.AddOrReplaceVolume(&deployment.Spec.Template.Spec, 
defaultResourcesVolume)
-                       kubeutil.AddOrReplaceVolumeMount(idx, 
&deployment.Spec.Template.Spec,
+                       kubeutil.AddOrReplaceVolume(podTemplateSpec, 
defaultResourcesVolume)
+                       kubeutil.AddOrReplaceVolumeMount(idx, podTemplateSpec,
                                
kubeutil.VolumeMount(constants.ConfigMapWorkflowPropsVolumeName, true, 
quarkusProdConfigMountPath))
 
-                       return 
kubeutil.AnnotateDeploymentConfigChecksum(workflow, deployment, userPropsCM, 
managedPropsCM)
+                       return nil
                }
        }
 }
diff --git a/controllers/profiles/preview/profile_preview.go 
b/controllers/profiles/preview/profile_preview.go
index a4afea9b..1a0dda49 100644
--- a/controllers/profiles/preview/profile_preview.go
+++ b/controllers/profiles/preview/profile_preview.go
@@ -23,6 +23,7 @@ import (
        "time"
 
        
"github.com/apache/incubator-kie-kogito-serverless-operator/api/metadata"
+       
"github.com/apache/incubator-kie-kogito-serverless-operator/api/v1alpha08"
        "k8s.io/client-go/rest"
 
        
"github.com/apache/incubator-kie-kogito-serverless-operator/controllers/discovery"
@@ -48,20 +49,42 @@ 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 preview 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 {
-       deployment            common.ObjectEnsurerWithPlatform
+       // deployment for this ensurer. Don't call it directly, use 
DeploymentByDeploymentModel instead
+       deployment common.ObjectEnsurerWithPlatform
+       // kservice Knative Serving deployment for this ensurer. Don't call it 
directly, use DeploymentByDeploymentModel instead
+       kservice common.ObjectEnsurerWithPlatform
+       // service for this ensurer. Don't call it directly, use 
ServiceByDeploymentModel instead
        service               common.ObjectEnsurer
        userPropsConfigMap    common.ObjectEnsurer
        managedPropsConfigMap common.ObjectEnsurerWithPlatform
 }
 
+// DeploymentByDeploymentModel gets the deployment ensurer based on the 
SonataFlow deployment model
+func (o *ObjectEnsurers) DeploymentByDeploymentModel(workflow 
*v1alpha08.SonataFlow) common.ObjectEnsurerWithPlatform {
+       if workflow.IsKnativeDeployment() {
+               return o.kservice
+       }
+       return o.deployment
+}
+
+// ServiceByDeploymentModel gets the service ensurer based on the SonataFlow 
deployment model
+func (o *ObjectEnsurers) ServiceByDeploymentModel(workflow 
*v1alpha08.SonataFlow) common.ObjectEnsurer {
+       if workflow.IsKnativeDeployment() {
+               // Knative Serving handles the service
+               return common.NewNoopObjectEnsurer()
+       }
+       return o.service
+}
+
 // NewObjectEnsurers common.ObjectEnsurer(s) for the preview profile.
 func NewObjectEnsurers(support *common.StateSupport) *ObjectEnsurers {
        return &ObjectEnsurers{
                deployment:            
common.NewObjectEnsurerWithPlatform(support.C, common.DeploymentCreator),
+               kservice:              
common.NewObjectEnsurerWithPlatform(support.C, common.KServiceCreator),
                service:               common.NewObjectEnsurer(support.C, 
common.ServiceCreator),
                userPropsConfigMap:    common.NewObjectEnsurer(support.C, 
common.UserPropsConfigMapCreator),
                managedPropsConfigMap: 
common.NewObjectEnsurerWithPlatform(support.C, 
common.ManagedPropsConfigMapCreator),
diff --git a/controllers/profiles/preview/profile_preview_test.go 
b/controllers/profiles/preview/profile_preview_test.go
index cc518db0..22146ccf 100644
--- a/controllers/profiles/preview/profile_preview_test.go
+++ b/controllers/profiles/preview/profile_preview_test.go
@@ -198,5 +198,6 @@ func fakeReconcilerSupport(client clientruntime.Client) 
*common.StateSupport {
        return &common.StateSupport{
                C:        client,
                Recorder: test.NewFakeRecorder(),
+               Cfg:      &rest.Config{},
        }
 }
diff --git a/controllers/profiles/preview/states_preview.go 
b/controllers/profiles/preview/states_preview.go
index 933820e8..4612c84d 100644
--- a/controllers/profiles/preview/states_preview.go
+++ b/controllers/profiles/preview/states_preview.go
@@ -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).reconcileWithImage(ctx, workflow, build.Status.ImageTag)
 }
 
 func (h *deployWithBuildWorkflowState) PostReconcile(ctx context.Context, 
workflow *operatorapi.SonataFlow) error {
diff --git a/controllers/sonataflow_controller.go 
b/controllers/sonataflow_controller.go
index 447e386f..7c1d28ab 100644
--- a/controllers/sonataflow_controller.go
+++ b/controllers/sonataflow_controller.go
@@ -23,6 +23,7 @@ import (
        "context"
        "fmt"
 
+       
"github.com/apache/incubator-kie-kogito-serverless-operator/api/metadata"
        "k8s.io/klog/v2"
 
        profiles 
"github.com/apache/incubator-kie-kogito-serverless-operator/controllers/profiles/factory"
@@ -89,6 +90,8 @@ func (r *SonataFlowReconciler) Reconcile(ctx context.Context, 
req ctrl.Request)
                return ctrl.Result{}, err
        }
 
+       r.setDefaults(workflow)
+
        // Only process resources assigned to the operator
        if !platform.IsOperatorHandlerConsideringLock(ctx, r.Client, 
req.Namespace, workflow) {
                klog.V(log.I).InfoS("Ignoring request because resource is not 
assigned to current operator")
@@ -97,6 +100,18 @@ func (r *SonataFlowReconciler) Reconcile(ctx 
context.Context, req ctrl.Request)
        return profiles.NewReconciler(r.Client, r.Config, r.Recorder, 
workflow).Reconcile(ctx, workflow)
 }
 
+// TODO: move to webhook see 
https://github.com/apache/incubator-kie-kogito-serverless-operator/pull/239
+func (r *SonataFlowReconciler) setDefaults(workflow *operatorapi.SonataFlow) {
+       if workflow.Annotations == nil {
+               workflow.Annotations = map[string]string{}
+       }
+       profile := metadata.GetProfileOrDefault(workflow.Annotations)
+       workflow.Annotations[metadata.Profile] = string(profile)
+       if profile == metadata.DevProfile {
+               workflow.Spec.PodTemplate.DeploymentModel = 
operatorapi.KubernetesDeploymentModel
+       }
+}
+
 func platformEnqueueRequestsFromMapFunc(c client.Client, p 
*operatorapi.SonataFlowPlatform) []reconcile.Request {
        var requests []reconcile.Request
 
diff --git a/hack/local/run-operator.sh b/hack/local/run-operator.sh
index 5cb8a73c..8b57477c 100755
--- a/hack/local/run-operator.sh
+++ b/hack/local/run-operator.sh
@@ -17,6 +17,9 @@
 # under the License.
 
 # Runs the operator locally via go main
+POD_NAMESPACE=$(kubectl config view --minify | grep namespace | cut -d" " -f6)
+
+export POD_NAMESPACE
 
 kubectl delete --ignore-not-found=true -f 
./bundle/manifests/sonataflow.org_sonataflowclusterplatforms.yaml
 kubectl delete --ignore-not-found=true -f 
./bundle/manifests/sonataflow.org_sonataflowplatforms.yaml
diff --git a/main.go b/main.go
index 535a3ed0..e0265ed6 100644
--- a/main.go
+++ b/main.go
@@ -26,6 +26,7 @@ import (
        
"github.com/apache/incubator-kie-kogito-serverless-operator/controllers/cfg"
        eventingv1 "knative.dev/eventing/pkg/apis/eventing/v1"
        sourcesv1 "knative.dev/eventing/pkg/apis/sources/v1"
+       servingv1 "knative.dev/serving/pkg/apis/serving/v1"
 
        "k8s.io/klog/v2/klogr"
 
@@ -60,6 +61,7 @@ func init() {
        utilruntime.Must(operatorapi.AddToScheme(scheme))
        utilruntime.Must(sourcesv1.AddToScheme(scheme))
        utilruntime.Must(eventingv1.AddToScheme(scheme))
+       utilruntime.Must(servingv1.AddToScheme(scheme))
        //+kubebuilder:scaffold:scheme
 }
 
diff --git a/operator.yaml b/operator.yaml
index 14dfec14..f2ef7178 100644
--- a/operator.yaml
+++ b/operator.yaml
@@ -22523,6 +22523,13 @@ spec:
                       - name
                       type: object
                     type: array
+                  deploymentModel:
+                    description: Defines the kind of deployment model for this 
pod
+                      spec. In dev profile, only "kubernetes" is valid.
+                    enum:
+                    - kubernetes
+                    - knative
+                    type: string
                   dnsConfig:
                     description: Specifies the DNS parameters of a pod. 
Parameters
                       specified here will be merged to the generated DNS 
configuration
@@ -24050,6 +24057,8 @@ spec:
                       type: object
                     type: array
                   replicas:
+                    description: Replicas define the number of pods to start 
by default
+                      for this deployment model. Ignored in "knative" 
deployment model.
                     format: int32
                     type: integer
                   resourceClaims:
@@ -26492,6 +26501,12 @@ rules:
   - patch
   - update
   - watch
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: sonataflow-operator-knative-manager-role
+rules:
 - apiGroups:
   - eventing.knative.dev
   resources:
@@ -26522,6 +26537,22 @@ rules:
   - patch
   - update
   - watch
+- apiGroups:
+  - serving.knative.dev
+  resources:
+  - service
+  - services
+  - services/status
+  - services/finalizers
+  verbs:
+  - create
+  - delete
+  - deletecollection
+  - get
+  - list
+  - patch
+  - update
+  - watch
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: ClusterRole
@@ -26864,6 +26895,19 @@ subjects:
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: ClusterRoleBinding
+metadata:
+  name: sonataflow-operator-knative-manager-rolebinding
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: sonataflow-operator-knative-manager-role
+subjects:
+- kind: ServiceAccount
+  name: sonataflow-operator-controller-manager
+  namespace: sonataflow-operator-system
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
 metadata:
   name: sonataflow-operator-leases-binding
 roleRef:
diff --git a/test/kubernetes_cli.go b/test/kubernetes_cli.go
index c4d7021f..72029fd1 100644
--- a/test/kubernetes_cli.go
+++ b/test/kubernetes_cli.go
@@ -33,6 +33,7 @@ import (
        utilruntime "k8s.io/apimachinery/pkg/util/runtime"
        "k8s.io/client-go/kubernetes/scheme"
        "k8s.io/client-go/tools/record"
+       servingv1 "knative.dev/serving/pkg/apis/serving/v1"
        ctrl "sigs.k8s.io/controller-runtime/pkg/client"
        "sigs.k8s.io/controller-runtime/pkg/client/fake"
 
@@ -50,6 +51,13 @@ func NewSonataFlowClientBuilder() *fake.ClientBuilder {
        return fake.NewClientBuilder().WithScheme(s)
 }
 
+func NewSonataFlowClientBuilderWithKnative() *fake.ClientBuilder {
+       s := scheme.Scheme
+       utilruntime.Must(operatorapi.AddToScheme(s))
+       utilruntime.Must(servingv1.AddToScheme(s))
+       return fake.NewClientBuilder().WithScheme(s)
+}
+
 // NewKogitoClientBuilderWithOpenShift creates a new fake client with 
OpenShift schemas.
 // If your object is not present, just add in the list below.
 func NewKogitoClientBuilderWithOpenShift() *fake.ClientBuilder {
diff --git a/test/yaml.go b/test/yaml.go
index 84ac1b7d..fd96943b 100644
--- a/test/yaml.go
+++ b/test/yaml.go
@@ -215,8 +215,8 @@ func GetBaseSonataFlowWithProdProfile(namespace string) 
*operatorapi.SonataFlow
        return NewSonataFlow(sonataFlowSampleYamlCR, namespace, 
SetPreviewProfile)
 }
 
-// GetBaseSonataFlowWithProdOpsProfile gets a base workflow that has a 
pre-built image set in podTemplate.
-func GetBaseSonataFlowWithProdOpsProfile(namespace string) 
*operatorapi.SonataFlow {
+// GetBaseSonataFlowWithPreviewProfile gets a base workflow that has a 
pre-built image set in podTemplate.
+func GetBaseSonataFlowWithPreviewProfile(namespace string) 
*operatorapi.SonataFlow {
        return NewSonataFlow(SonataFlowSimpleOpsYamlCR, namespace)
 }
 
diff --git a/testbdd/go.mod b/testbdd/go.mod
index 5f0c0ed6..bea1546d 100644
--- a/testbdd/go.mod
+++ b/testbdd/go.mod
@@ -66,6 +66,7 @@ require (
        github.com/golang/protobuf v1.5.3 // indirect
        github.com/google/gnostic v0.6.9 // indirect
        github.com/google/go-cmp v0.6.0 // indirect
+       github.com/google/go-containerregistry v0.13.0 // indirect
        github.com/google/gofuzz v1.2.0 // indirect
        github.com/google/pprof v0.0.0-20230705174524-200ffdc848b8 // indirect
        github.com/google/uuid v1.3.1 // indirect
@@ -89,6 +90,7 @@ require (
        github.com/modern-go/reflect2 v1.0.2 // indirect
        github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // 
indirect
        github.com/onsi/ginkgo/v2 v2.13.0 // indirect
+       github.com/opencontainers/go-digest v1.0.0 // indirect
        github.com/openshift/client-go v0.0.0-20230503144108-75015d2347cb // 
indirect
        github.com/pkg/errors v0.9.1 // indirect
        github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // 
indirect
@@ -137,7 +139,9 @@ require (
        k8s.io/klog/v2 v2.100.1 // indirect
        k8s.io/kube-openapi v0.0.0-20230525220651-2546d827e515 // indirect
        k8s.io/utils v0.0.0-20230711102312-30195339c3c7 // indirect
+       knative.dev/networking v0.0.0-20231017124814-2a7676e912b7 // indirect
        knative.dev/pkg v0.0.0-20231023151236-29775d7c9e5c // indirect
+       knative.dev/serving v0.39.0 // indirect
        sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
        sigs.k8s.io/structured-merge-diff/v4 v4.3.0 // indirect
        sigs.k8s.io/yaml v1.3.0 // indirect
diff --git a/testbdd/go.sum b/testbdd/go.sum
index 2e0cf298..16617aed 100644
--- a/testbdd/go.sum
+++ b/testbdd/go.sum
@@ -460,6 +460,7 @@ github.com/google/go-cmp v0.5.4/go.mod 
h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
 github.com/google/go-cmp v0.5.5/go.mod 
h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.6/go.mod 
h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
+github.com/google/go-containerregistry v0.13.0 
h1:y1C7Z3e149OJbOPDBxLYR8ITPz8dTKqQwjErKVHJC8k=
 github.com/google/go-github v17.0.0+incompatible/go.mod 
h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
 github.com/google/go-github/v27 v27.0.6/go.mod 
h1:/0Gr8pJ55COkmv+S/yPKCczSkUPIM/LnFyubufRNIS0=
 github.com/google/go-querystring v1.0.0/go.mod 
h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
@@ -718,6 +719,7 @@ github.com/onsi/gomega v1.30.0 
h1:hvMK7xYz4D3HapigLTeGdId/NcfQx1VHMJc60ew99+8=
 github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod 
h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
 github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod 
h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
 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/image-spec v1.0.0/go.mod 
h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
 github.com/opencontainers/image-spec v1.0.1/go.mod 
h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
 github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod 
h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
@@ -1566,10 +1568,12 @@ knative.dev/eventing v0.26.0 
h1:osDUdav7S0FuChN0onfwL5cEcsdb54Kee2hjAPMpY7o=
 knative.dev/eventing v0.26.0/go.mod 
h1:6tTam0lsPtBSJHJ63/195obj2VAHlTZZB7TLiBSeqk0=
 knative.dev/hack v0.0.0-20210806075220-815cd312d65c/go.mod 
h1:PHt8x8yX5Z9pPquBEfIj0X66f8iWkWfR0S/sarACJrI=
 knative.dev/hack/schema v0.0.0-20210806075220-815cd312d65c/go.mod 
h1:ffjwmdcrH5vN3mPhO8RrF2KfNnbHeCE2C60A+2cv3U0=
+knative.dev/networking v0.0.0-20231017124814-2a7676e912b7 
h1:6+1icZuxiZO1paFZ4d/ysKWVG2M4WB7OxNJNyLG0P/E=
 knative.dev/pkg v0.0.0-20210914164111-4857ab6939e3/go.mod 
h1:jMSqkNMsrzuy+XR4Yr/BMy7SDVbUOl3KKB6+5MR+ZU8=
 knative.dev/pkg v0.0.0-20210919202233-5ae482141474/go.mod 
h1:jMSqkNMsrzuy+XR4Yr/BMy7SDVbUOl3KKB6+5MR+ZU8=
 knative.dev/pkg v0.0.0-20231023151236-29775d7c9e5c 
h1:xyPoEToTWeBdn6tinhLxXfnhJhTNQt5WzHiTNiFphRw=
 knative.dev/reconciler-test v0.0.0-20210915181908-49fac7555086/go.mod 
h1:6yDmb26SINSmgw6wVy9qQwgRMewiW8ddkkwGLR0ZvOY=
+knative.dev/serving v0.39.0 h1:NVt8WthHmFFMWZ3qpBblXt47del8qqrbCegqwGBVSwk=
 modernc.org/cc v1.0.0/go.mod h1:1Sk4//wdnYJiUIxnW8ddKpaOJCF37yAdqYnkxUpaYxw=
 modernc.org/golex v1.0.0/go.mod h1:b/QX9oBD/LhixY6NDh+IdGv17hgB+51fET1i2kPSmvk=
 modernc.org/mathutil v1.0.0/go.mod 
h1:wU0vUrJsVWBZ4P6e7xtFJEhFSNsfRLJ8H458uRjg03k=
diff --git a/utils/common.go b/utils/common.go
index e24e8691..073bb255 100644
--- a/utils/common.go
+++ b/utils/common.go
@@ -28,7 +28,11 @@ import (
 )
 
 const (
-       HttpScheme = "http"
+       // DefaultServicePortName default service name to increase 
compatibility with Knative
+       //
+       // see: 
https://github.com/knative/specs/blob/main/specs/serving/runtime-contract.md#protocols-and-ports
+       // By default we do support 
HTTP/2:https://quarkus.io/guides/http-reference#http2-support
+       DefaultServicePortName = "h2c"
 )
 
 // GetOperatorIDAnnotation to safely get the operator id annotation value.
diff --git a/workflowproj/workflowproj.go b/workflowproj/workflowproj.go
index bd8653d2..2bf1deba 100644
--- a/workflowproj/workflowproj.go
+++ b/workflowproj/workflowproj.go
@@ -304,9 +304,5 @@ func (w *workflowProjectHandler) 
addResourceConfigMapToProject(cm *corev1.Config
 
 // IsDevProfile detects if the workflow is using the Dev profile or not
 func IsDevProfile(workflow *operatorapi.SonataFlow) bool {
-       profile := workflow.Annotations[metadata.Profile]
-       if len(profile) == 0 {
-               return false
-       }
-       return metadata.ProfileType(profile) == metadata.DevProfile
+       return metadata.IsDevProfile(workflow.Annotations)
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to