blob: 678e2167c084e3d22b65e24f4ab4025371f277df [file] [log] [blame]
// Copyright 2022 Red Hat, Inc. and/or its affiliates
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package v1alpha08
import (
cncfmodel "github.com/serverlessworkflow/sdk-go/v2/model"
v1 "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/kiegroup/kogito-serverless-operator/api"
)
// 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 v1.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
type SonataFlowSpec struct {
// +kubebuilder:validation:Required
Flow Flow `json:"flow"`
// Resources workflow resources that are linked to this workflow definition.
// For example, a collection of OpenAPI specification files.
Resources WorkflowResources `json:"resources,omitempty"`
}
// SonataFlowStatus defines the observed state of SonataFlow
type SonataFlowStatus struct {
api.Status `json:",inline"`
// Address is used as a part of Addressable interface (status.address.url) for knative
// +optional
Address duckv1.Addressable `json:"address,omitempty"`
// keeps track of how many failure recovers a given workflow had so far
RecoverFailureAttempts int `json:"recoverFailureAttempts,omitempty"`
LastTimeRecoverAttempt metav1.Time `json:"lastTimeRecoverAttempt,omitempty"`
// Endpoint is an externally accessible URL of the workflow
Endpoint *apis.URL `json:"endpoint,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.RunningConditionType)
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) 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`
type SonataFlow struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec SonataFlowSpec `json:"spec,omitempty"`
Status SonataFlowStatus `json:"status,omitempty"`
}
// 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{})
}