Skip to content

Commit

Permalink
Add APIs for Conditionals
Browse files Browse the repository at this point in the history
This commit adds the basic APIs for conditionals in Tekton:
1. Condition CRD defines a condition how a condition is evaluated i.e.
   the container spec and any input parameters.
2. The `Conditions` field in `PipelineTask` references `Condition`
   resources that have to pass before the task is executed.
3. The `ConditionChecks` field in `PipelineRun.Status.TaskRuns` surfaces
   the status of conditions that were evaluated for that particular task.
  • Loading branch information
dibyom committed Jul 9, 2019
1 parent d05b43c commit a52b36b
Show file tree
Hide file tree
Showing 18 changed files with 932 additions and 1 deletion.
2 changes: 1 addition & 1 deletion config/200-clusterrole.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ rules:
resources: ["mutatingwebhookconfigurations"]
verbs: ["get", "list", "create", "update", "delete", "patch", "watch"]
- apiGroups: ["tekton.dev"]
resources: ["tasks", "clustertasks", "taskruns", "pipelines", "pipelineruns", "pipelineresources"]
resources: ["tasks", "clustertasks", "taskruns", "pipelines", "pipelineruns", "pipelineresources", "conditions"]
verbs: ["get", "list", "create", "update", "delete", "patch", "watch"]
- apiGroups: ["tekton.dev"]
resources: ["taskruns/finalizers", "pipelineruns/finalizers"]
Expand Down
31 changes: 31 additions & 0 deletions config/500-condition.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Copyright 2018 The Knative Authors
#
# 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
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: conditions.tekton.dev
spec:
group: tekton.dev
names:
kind: Condition
plural: conditions
categories:
- all
- tekton-pipelines
scope: Namespaced
# Opt into the status subresource so metadata.generation
# starts to increment
subresources:
status: {}
version: v1alpha1
86 changes: 86 additions & 0 deletions pkg/apis/pipeline/v1alpha1/condition_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*
*
* Copyright 2019 The Tekton Authors
*
* 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 v1alpha1

import (
"github.com/knative/pkg/apis"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// Add validation for TaskConditions?
type TaskCondition struct {
ConditionRef string `json:"conditionRef"`
// TODO: Support a ConditionSpec?
// +optional
Params []Param `json:"params,omitempty"`
}

// Check that Task may be validated and defaulted.
var _ apis.Validatable = (*Condition)(nil)

// +genclient
// +genclient:noStatus
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

// Task represents a collection of sequential steps that are run as part of a
// Pipeline using a set of inputs and producing a set of outputs. Tasks execute
// when TaskRuns are created that provide the input parameters and resources and
// output resources the Task requires.
//
// +k8s:openapi-gen=true
type Condition struct {
metav1.TypeMeta `json:",inline"`
// +optional
metav1.ObjectMeta `json:"metadata"`

// Spec holds the desired state of the Condition from the client
// +optional
Spec ConditionSpec `json:"spec"`
}

type ConditionSpec struct {
// +optional
Params []ParamSpec `json:"params,omitempty"`
// Check is a container whose exit code determines where a condition is true or false
Check corev1.Container `json:"check,omitempty"`
}

type ConditionCheck TaskRun

type ConditionCheckStatus TaskRunStatus

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

// ConditionList contains a list of Conditions
type ConditionList struct {
metav1.TypeMeta `json:",inline"`
// +optional
metav1.ListMeta `json:"metadata,omitempty"`
Items []Condition `json:"items"`
}

func NewConditionCheck(tr *TaskRun) *ConditionCheck {
if tr == nil {
return nil
}

cc := ConditionCheck(*tr)
return &cc
}
37 changes: 37 additions & 0 deletions pkg/apis/pipeline/v1alpha1/condition_validation.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
Copyright 2019 The Tekton Authors
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 v1alpha1

import (
"context"
"github.com/knative/pkg/apis"
"k8s.io/apimachinery/pkg/api/equality"
)

func (c *Condition) Validate(ctx context.Context) *apis.FieldError {
if err := validateObjectMetadata(c.GetObjectMeta()); err != nil {
return err.ViaField("metadata")
}
return c.Spec.Validate(ctx)
}

func (cs *ConditionSpec) Validate(ctx context.Context) *apis.FieldError {
if equality.Semantic.DeepEqual(cs, &ConditionSpec{}) {
return apis.ErrMissingField(apis.CurrentField)
}
return nil
}
48 changes: 48 additions & 0 deletions pkg/apis/pipeline/v1alpha1/condition_validation_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
*
* Copyright 2019 The Tekton Authors
*
* 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 v1alpha1

import (
"context"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"testing"
)

func TestCondition_Validate(t *testing.T) {
c := Condition{
ObjectMeta: metav1.ObjectMeta{
Name: "taskname",
},
Spec: ConditionSpec{
Check: corev1.Container{
Name: "foo",
Image: "bar",
},
Params: []ParamSpec{
{
Name: "expected",
},
},
},
}
if err := c.Validate(context.Background()); err != nil {
t.Errorf("TaskRun.Validate() error = %v", err)
}
}
4 changes: 4 additions & 0 deletions pkg/apis/pipeline/v1alpha1/pipeline_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@ type PipelineTask struct {
// TaskRef is a reference to a task definition.
TaskRef TaskRef `json:"taskRef"`

// Conditions is a list of conditions that need to be true for the task to run
// +optional
Conditions []TaskCondition `json:"conditions,omitempty"`

// Retries represents how many times this task should be retried in case of task failure: ConditionSucceeded set to False
// +optional
Retries int `json:"retries,omitempty"`
Expand Down
11 changes: 11 additions & 0 deletions pkg/apis/pipeline/v1alpha1/pipelinerun_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,17 @@ type PipelineRunTaskRunStatus struct {
// Status is the TaskRunStatus for the corresponding TaskRun
// +optional
Status *TaskRunStatus `json:"status,omitempty"`
// ConditionChecks is the Status for the corresponding ConditionCheck
// +optional
ConditionChecks map[string]*PipelineRunConditionCheckStatus `json:"conditionChecks,omitempty"`
}

type PipelineRunConditionCheckStatus struct {
// ConditionName is the name of the Condition
ConditionName string `json:"conditionName,omitempty"`
// Status is the ConditionCheckStatus for the corresponding ConditionCheck
// +optional
Status *ConditionCheckStatus `json:"status,omitempty"`
}

var pipelineRunCondSet = apis.NewBatchConditionSet()
Expand Down
Loading

0 comments on commit a52b36b

Please sign in to comment.