diff --git a/docs/TektonConfig.md b/docs/TektonConfig.md index 8a83e5548b..4d6a7d1855 100644 --- a/docs/TektonConfig.md +++ b/docs/TektonConfig.md @@ -41,19 +41,37 @@ The TektonConfig CR provides the following features chain: disabled: false pipeline: + await-sidecar-readiness: true + coschedule: workspaces disable-affinity-assistant: false disable-creds-init: false disable-home-env-overwrite: true disable-working-directory-overwrite: true - enable-api-fields: stable - enable-custom-tasks: false + enable-api-fields: beta + enable-bundles-resolver: true + enable-cel-in-whenexpression: false + enable-cluster-resolver: true + enable-custom-tasks: true + enable-git-resolver: true + enable-hub-resolver: true + enable-param-enum: false + enable-provenance-in-status: true + enable-step-actions: false enable-tekton-oci-bundles: false + enforce-nonfalsifiability: none + keep-pod-on-cancel: false + max-result-size: 4096 + metrics.count.enable-reason: false metrics.pipelinerun.duration-type: histogram - metrics.pipelinerun.level: pipelinerun + metrics.pipelinerun.level: pipeline metrics.taskrun.duration-type: histogram - metrics.taskrun.level: taskrun + metrics.taskrun.level: task require-git-ssh-secret-known-hosts: false + results-from: termination-message running-in-environment-with-injected-sidecars: true + scope-when-expressions-to-task: false + send-cloudevents-for-runs: false + set-security-context: false trusted-resources-verification-no-match-policy: ignore performance: disable-ha: false @@ -75,7 +93,7 @@ The TektonConfig CR provides the following features keep: 3 # keep-since: 1440 # NOTE: you can use either "keep" or "keep-since", not both - prune-per-resource: true + prune-per-resource: true hub: params: - name: enable-devconsole-integration diff --git a/docs/TektonPipeline.md b/docs/TektonPipeline.md index 373ca59948..4bc185185a 100644 --- a/docs/TektonPipeline.md +++ b/docs/TektonPipeline.md @@ -18,20 +18,37 @@ metadata: name: pipeline spec: targetNamespace: tekton-pipelines + await-sidecar-readiness: true + coschedule: workspaces disable-affinity-assistant: false disable-creds-init: false disable-home-env-overwrite: true disable-working-directory-overwrite: true - enable-api-fields: stable - enable-custom-tasks: false + enable-api-fields: beta + enable-bundles-resolver: true + enable-cel-in-whenexpression: false + enable-cluster-resolver: true + enable-custom-tasks: true + enable-git-resolver: true + enable-hub-resolver: true + enable-param-enum: false + enable-provenance-in-status: true + enable-step-actions: false enable-tekton-oci-bundles: false + enforce-nonfalsifiability: none + keep-pod-on-cancel: false + max-result-size: 4096 + metrics.count.enable-reason: false metrics.pipelinerun.duration-type: histogram metrics.pipelinerun.level: pipeline metrics.taskrun.duration-type: histogram metrics.taskrun.level: task require-git-ssh-secret-known-hosts: false + results-from: termination-message running-in-environment-with-injected-sidecars: true scope-when-expressions-to-task: false + send-cloudevents-for-runs: false + set-security-context: false trusted-resources-verification-no-match-policy: ignore performance: disable-ha: false @@ -64,6 +81,17 @@ finds into your Steps. Note: setting this to "true" will prevent PipelineResources from working. See more info [here](https://github.com/tektoncd/pipeline/issues/2791). +- `await-sidecar-readiness` (Default: `true`) + + Setting this flag to "false" to allow the Tekton controller to start a TasksRun's first step immediately without + waiting for sidecar containers to be running first. + + Note: setting this flag to "false" will mean the running-in-environment-with-injected-sidecars flag has no effect. + +- `coschedule` (Default: `workspaces`) + + This flag determines how PipelineRun Pods are scheduled with Affinity Assistant. Acceptable values are + "workspaces" (default), "pipelineruns", "isolate-pipelinerun", or "disabled" - `running-in-environment-with-injected-sidecars` (Default: `true`) @@ -97,6 +125,47 @@ and thus should still be considered an alpha feature. Setting this flag will determine which gated features are enabled. Acceptable values are "stable" or "alpha". +- `results-from` (Default: `termination-message`) + + This feature is to use the container's termination message to fetch results from. Set it to "sidecar-logs" to + enable use of a results sidecar logs to extract results instead of termination message. + +- `max-result-size` (Default: `4096`) + + This feature is to configure the size of the task results if using `sidecar-logs`. The default value if `4096` and + maximum value can be `1572863`. + +- `enable-provenance-in-status` (Default: `true`) + + This feature is to enable populating the provenance field in TaskRun and PipelineRun status. The provenance field + contains metadata about resources used in the TaskRun/PipelineRun such as the source from where a remote + Task/Pipeline definition was fetched. To disable populating this field, set this flag to "false". + +- `set-security-context` (Default: `false`) + + Setting this flag to "true" to set a security context for containers injected by Tekton that will allow TaskRun pods + to run in namespaces with restricted pod security admission + +- `keep-pod-on-cancel` (Default: `false`) + + Setting this flag to "true" will not delete the pod associated with cancelled taskrun. + +- `enforce-nonfalsifiability` (Default: `none`) + + Setting this flag to "spire" to enable integration with `SPIRE`. + +- `enable-param-enum` (Default: `false`) + + Setting this flag to "true" will enable params of type `Enum` + +- `enable-step-actions` (Default: `false`) + + Setting this flag to "true" will enable specifying `StepAction` in a `Step`. A `StepAction` is the reusable and + scriptable unit of work that is performed by a `Step` + +- `enable-cel-in-whenexpression` (Default: `false`) + + Setting this flag to "true" will enable using CEL in when expressions. - `scope-when-expressions-to-task` (Default: `false`) @@ -126,6 +195,10 @@ configure in pipelines. Setting this flag will determine the level of taskrun metrics. +- `metrics.count.enable-reason` (Default: `false`) + + Setting this flag to "true" will include reason label on count metrics. + ### Optional Properties @@ -176,6 +249,11 @@ default is the only option available. If no sink is specified, no CloudEvent is default-task-run-workspace-binding contains the default workspace configuration provided for any Workspaces that a Task declares but that a TaskRun does not explicitly provide. + +- `default-resolver-type` + + default-resolver-type contains the resolver type to be used as default resolver. + [Pipeline]:https://github.com/tektoncd/pipeline ### Performance Properties diff --git a/pkg/apis/operator/v1alpha1/tektonpipeline_defaults.go b/pkg/apis/operator/v1alpha1/tektonpipeline_defaults.go index 081f0abc9a..25c50de177 100644 --- a/pkg/apis/operator/v1alpha1/tektonpipeline_defaults.go +++ b/pkg/apis/operator/v1alpha1/tektonpipeline_defaults.go @@ -77,6 +77,42 @@ func (p *Pipeline) setDefaults() { // Deprecated: set to nil, remove in further release p.ScopeWhenExpressionsToTask = nil + if p.EnforceNonfalsifiability == "" { + p.EnforceNonfalsifiability = config.DefaultEnforceNonfalsifiability + } + + if p.EnableKeepPodOnCancel == nil { + p.EnableKeepPodOnCancel = ptr.Bool(config.DefaultEnableKeepPodOnCancel) + } + + if p.ResultExtractionMethod == "" { + p.ResultExtractionMethod = config.DefaultResultExtractionMethod + } + + if p.MaxResultSize == nil { + p.MaxResultSize = ptr.Int32(config.DefaultMaxResultSize) + } + + if p.SetSecurityContext == nil { + p.SetSecurityContext = ptr.Bool(config.DefaultSetSecurityContext) + } + + if p.Coschedule == "" { + p.Coschedule = config.DefaultCoschedule + } + + if p.EnableCELInWhenExpression == nil { + p.EnableCELInWhenExpression = ptr.Bool(config.DefaultEnableCELInWhenExpression) + } + + if p.EnableStepActions == nil { + p.EnableStepActions = ptr.Bool(config.DefaultEnableStepActions) + } + + if p.EnableParamEnum == nil { + p.EnableParamEnum = ptr.Bool(config.DefaultEnableParamEnum) + } + if p.MetricsPipelinerunDurationType == "" { p.MetricsPipelinerunDurationType = config.DefaultDurationPipelinerunType } @@ -89,6 +125,9 @@ func (p *Pipeline) setDefaults() { if p.MetricsTaskrunLevel == "" { p.MetricsTaskrunLevel = config.DefaultTaskrunLevel } + if p.CountWithReason == nil { + p.CountWithReason = ptr.Bool(false) + } // Resolvers if p.EnableBundlesResolver == nil { diff --git a/pkg/apis/operator/v1alpha1/tektonpipeline_defaults_test.go b/pkg/apis/operator/v1alpha1/tektonpipeline_defaults_test.go index b58529990d..cc0f59cf62 100644 --- a/pkg/apis/operator/v1alpha1/tektonpipeline_defaults_test.go +++ b/pkg/apis/operator/v1alpha1/tektonpipeline_defaults_test.go @@ -53,11 +53,21 @@ func Test_SetDefaults_PipelineProperties(t *testing.T) { SendCloudEventsForRuns: ptr.Bool(false), VerificationNoMatchPolicy: config.DefaultNoMatchPolicyConfig, EnableProvenanceInStatus: ptr.Bool(true), + EnforceNonfalsifiability: config.DefaultEnforceNonfalsifiability, + EnableKeepPodOnCancel: ptr.Bool(config.DefaultEnableKeepPodOnCancel), + ResultExtractionMethod: config.DefaultResultExtractionMethod, + MaxResultSize: ptr.Int32(config.DefaultMaxResultSize), + SetSecurityContext: ptr.Bool(config.DefaultSetSecurityContext), + Coschedule: config.DefaultCoschedule, + EnableCELInWhenExpression: ptr.Bool(config.DefaultEnableCELInWhenExpression), + EnableStepActions: ptr.Bool(config.DefaultEnableStepActions), + EnableParamEnum: ptr.Bool(config.DefaultEnableParamEnum), PipelineMetricsProperties: PipelineMetricsProperties{ MetricsPipelinerunDurationType: "histogram", MetricsPipelinerunLevel: "pipeline", MetricsTaskrunDurationType: "histogram", MetricsTaskrunLevel: "task", + CountWithReason: ptr.Bool(false), }, Resolvers: Resolvers{ EnableBundlesResolver: ptr.Bool(true), diff --git a/pkg/apis/operator/v1alpha1/tektonpipeline_types.go b/pkg/apis/operator/v1alpha1/tektonpipeline_types.go index 5eab131df7..a31694691e 100644 --- a/pkg/apis/operator/v1alpha1/tektonpipeline_types.go +++ b/pkg/apis/operator/v1alpha1/tektonpipeline_types.go @@ -107,7 +107,18 @@ type PipelineProperties struct { // ScopeWhenExpressionsToTask Deprecated: remove in next release ScopeWhenExpressionsToTask *bool `json:"scope-when-expressions-to-task,omitempty"` - PipelineMetricsProperties `json:",inline"` + + EnforceNonfalsifiability string `json:"enforce-nonfalsifiability,omitempty"` + EnableKeepPodOnCancel *bool `json:"keep-pod-on-cancel,omitempty"` + ResultExtractionMethod string `json:"results-from,omitempty"` + MaxResultSize *int32 `json:"max-result-size,omitempty"` + SetSecurityContext *bool `json:"set-security-context,omitempty"` + Coschedule string `json:"coschedule,omitempty"` + EnableCELInWhenExpression *bool `json:"enable-cel-in-whenexpression,omitempty"` + EnableStepActions *bool `json:"enable-step-actions,omitempty"` + EnableParamEnum *bool `json:"enable-param-enum,omitempty"` + + PipelineMetricsProperties `json:",inline"` // +optional OptionalPipelineProperties `json:",inline"` // +optional @@ -128,6 +139,7 @@ type OptionalPipelineProperties struct { DefaultTaskRunWorkspaceBinding string `json:"default-task-run-workspace-binding,omitempty"` DefaultMaxMatrixCombinationsCount string `json:"default-max-matrix-combinations-count,omitempty"` DefaultForbiddenEnv string `json:"default-forbidden-env,omitempty"` + DefaultResolverType string `json:"default-resolver-type,omitempty"` } // PipelineMetricsProperties defines the fields which are configurable for @@ -137,6 +149,7 @@ type PipelineMetricsProperties struct { MetricsTaskrunDurationType string `json:"metrics.taskrun.duration-type,omitempty"` MetricsPipelinerunLevel string `json:"metrics.pipelinerun.level,omitempty"` MetricsPipelinerunDurationType string `json:"metrics.pipelinerun.duration-type,omitempty"` + CountWithReason *bool `json:"metrics.count.enable-reason,omitempty"` } // Resolvers defines the fields to configure resolvers diff --git a/pkg/apis/operator/v1alpha1/tektonpipeline_validation.go b/pkg/apis/operator/v1alpha1/tektonpipeline_validation.go index e5d4ac983f..2c3eb7e4aa 100644 --- a/pkg/apis/operator/v1alpha1/tektonpipeline_validation.go +++ b/pkg/apis/operator/v1alpha1/tektonpipeline_validation.go @@ -28,6 +28,9 @@ import ( var ( validatePipelineAllowedApiFields = sets.NewString("", config.AlphaAPIFields, config.BetaAPIFields, config.StableAPIFields) validatePipelineVerificationNoMatchPolicy = sets.NewString("", config.FailNoMatchPolicy, config.WarnNoMatchPolicy, config.IgnoreNoMatchPolicy) + validatePipelineResultExtractionMethod = sets.NewString("", config.ResultExtractionMethodTerminationMessage, config.ResultExtractionMethodSidecarLogs) + validatePipelineEnforceNonFalsifiability = sets.NewString("", config.EnforceNonfalsifiabilityNone, config.EnforceNonfalsifiabilityWithSpire) + validatePipelineCoschedule = sets.NewString("", config.CoscheduleDisabled, config.CoscheduleWorkspaces, config.CoschedulePipelineRuns, config.CoscheduleIsolatePipelineRun) ) func (tp *TektonPipeline) Validate(ctx context.Context) (errs *apis.FieldError) { @@ -59,11 +62,29 @@ func (p *PipelineProperties) validate(path string) (errs *apis.FieldError) { } } + if p.MaxResultSize != nil { + if *p.MaxResultSize >= 1572864 { + errs = errs.Also(apis.ErrInvalidValue(p.MaxResultSize, path+".max-result-size")) + } + } + // validate trusted-resources-verification-no-match-policy if !validatePipelineVerificationNoMatchPolicy.Has(p.VerificationNoMatchPolicy) { errs = errs.Also(apis.ErrInvalidValue(p.VerificationNoMatchPolicy, fmt.Sprintf("%s.trusted-resources-verification-no-match-policy", path))) } + if !validatePipelineResultExtractionMethod.Has(p.ResultExtractionMethod) { + errs = errs.Also(apis.ErrInvalidValue(p.ResultExtractionMethod, fmt.Sprintf("%s.results-from", path))) + } + + if !validatePipelineEnforceNonFalsifiability.Has(p.EnforceNonfalsifiability) { + errs = errs.Also(apis.ErrInvalidValue(p.EnforceNonfalsifiability, fmt.Sprintf("%s.enforce-nonfalsifiability", path))) + } + + if !validatePipelineCoschedule.Has(p.Coschedule) { + errs = errs.Also(apis.ErrInvalidValue(p.Coschedule, fmt.Sprintf("%s.coschedule", path))) + } + // validate performance properties errs = errs.Also(p.Performance.validate(fmt.Sprintf("%s.performance", path))) diff --git a/pkg/apis/operator/v1alpha1/tektonpipeline_validation_test.go b/pkg/apis/operator/v1alpha1/tektonpipeline_validation_test.go index e822f03ad5..cf4e1e8ca9 100644 --- a/pkg/apis/operator/v1alpha1/tektonpipeline_validation_test.go +++ b/pkg/apis/operator/v1alpha1/tektonpipeline_validation_test.go @@ -109,6 +109,107 @@ func TestValidateTektonPipelineVerificationNoMatchPolicy(t *testing.T) { } } +func TestValidateTektonPipelineResultExtractionMethod(t *testing.T) { + tp := &TektonPipeline{ + ObjectMeta: metav1.ObjectMeta{ + Name: "pipeline", + Namespace: "tekton-pipelines-ns", + }, + Spec: TektonPipelineSpec{ + CommonSpec: CommonSpec{ + TargetNamespace: "tekton-pipelines-ns", + }, + }, + } + + tests := []struct { + name string + method string + err string + }{ + {name: "method-empty-value", method: "", err: ""}, + {name: "method-sidecar", method: config.ResultExtractionMethodSidecarLogs, err: ""}, + {name: "method-termination", method: config.ResultExtractionMethodTerminationMessage, err: ""}, + {name: "method-invalid", method: "hello", err: "invalid value: hello: spec.results-from"}, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + tp.Spec.Pipeline.ResultExtractionMethod = test.method + errs := tp.Validate(context.TODO()) + assert.Equal(t, test.err, errs.Error()) + }) + } +} + +func TestValidateTektonPipelineEnforceNonFalsifiability(t *testing.T) { + tp := &TektonPipeline{ + ObjectMeta: metav1.ObjectMeta{ + Name: "pipeline", + Namespace: "tekton-pipelines-ns", + }, + Spec: TektonPipelineSpec{ + CommonSpec: CommonSpec{ + TargetNamespace: "tekton-pipelines-ns", + }, + }, + } + + tests := []struct { + name string + falsifiability string + err string + }{ + {name: "falsifiability-empty-value", falsifiability: "", err: ""}, + {name: "falsifiability-none", falsifiability: config.EnforceNonfalsifiabilityNone, err: ""}, + {name: "falsifiability-spire", falsifiability: config.EnforceNonfalsifiabilityWithSpire, err: ""}, + {name: "falsifiability-invalid", falsifiability: "hello", err: "invalid value: hello: spec.enforce-nonfalsifiability"}, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + tp.Spec.Pipeline.EnforceNonfalsifiability = test.falsifiability + errs := tp.Validate(context.TODO()) + assert.Equal(t, test.err, errs.Error()) + }) + } +} + +func TestValidateTektonPipelineCoschedule(t *testing.T) { + tp := &TektonPipeline{ + ObjectMeta: metav1.ObjectMeta{ + Name: "pipeline", + Namespace: "tekton-pipelines-ns", + }, + Spec: TektonPipelineSpec{ + CommonSpec: CommonSpec{ + TargetNamespace: "tekton-pipelines-ns", + }, + }, + } + + tests := []struct { + name string + coschedule string + err string + }{ + {name: "coschedule-empty-value", coschedule: "", err: ""}, + {name: "coschedule-disabled", coschedule: config.CoscheduleDisabled, err: ""}, + {name: "coschedule-workspaces", coschedule: config.CoscheduleWorkspaces, err: ""}, + {name: "coschedule-pipelineruns", coschedule: config.CoschedulePipelineRuns, err: ""}, + {name: "coschedule-isolate-pipelineruns", coschedule: config.CoscheduleIsolatePipelineRun, err: ""}, + {name: "coschedule-invalid", coschedule: "hello", err: "invalid value: hello: spec.coschedule"}, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + tp.Spec.Pipeline.Coschedule = test.coschedule + errs := tp.Validate(context.TODO()) + assert.Equal(t, test.err, errs.Error()) + }) + } +} + func Test_ValidateTektonPipeline_OnDelete(t *testing.T) { td := &TektonPipeline{ diff --git a/pkg/apis/operator/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/operator/v1alpha1/zz_generated.deepcopy.go index badbfc8421..dbb36d29da 100644 --- a/pkg/apis/operator/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/operator/v1alpha1/zz_generated.deepcopy.go @@ -638,6 +638,11 @@ func (in *PipelineDeploymentPerformanceArgs) DeepCopy() *PipelineDeploymentPerfo // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *PipelineMetricsProperties) DeepCopyInto(out *PipelineMetricsProperties) { *out = *in + if in.CountWithReason != nil { + in, out := &in.CountWithReason, &out.CountWithReason + *out = new(bool) + **out = **in + } return } @@ -748,7 +753,37 @@ func (in *PipelineProperties) DeepCopyInto(out *PipelineProperties) { *out = new(bool) **out = **in } - out.PipelineMetricsProperties = in.PipelineMetricsProperties + if in.EnableKeepPodOnCancel != nil { + in, out := &in.EnableKeepPodOnCancel, &out.EnableKeepPodOnCancel + *out = new(bool) + **out = **in + } + if in.MaxResultSize != nil { + in, out := &in.MaxResultSize, &out.MaxResultSize + *out = new(int32) + **out = **in + } + if in.SetSecurityContext != nil { + in, out := &in.SetSecurityContext, &out.SetSecurityContext + *out = new(bool) + **out = **in + } + if in.EnableCELInWhenExpression != nil { + in, out := &in.EnableCELInWhenExpression, &out.EnableCELInWhenExpression + *out = new(bool) + **out = **in + } + if in.EnableStepActions != nil { + in, out := &in.EnableStepActions, &out.EnableStepActions + *out = new(bool) + **out = **in + } + if in.EnableParamEnum != nil { + in, out := &in.EnableParamEnum, &out.EnableParamEnum + *out = new(bool) + **out = **in + } + in.PipelineMetricsProperties.DeepCopyInto(&out.PipelineMetricsProperties) in.OptionalPipelineProperties.DeepCopyInto(&out.OptionalPipelineProperties) in.Resolvers.DeepCopyInto(&out.Resolvers) in.Performance.DeepCopyInto(&out.Performance)