Skip to content

Commit 7fc1d86

Browse files
committed
fix: reject TaskRun taskRef with custom task kind but no apiVersion
A TaskRef that sets kind to a non-default value without apiVersion is not recognized as a Custom Task reference (IsCustomTask requires both fields), and the resolver ignores the kind entirely: the ref resolves as an ordinary namespaced Task when one exists, or fails at runtime with a confusing not-found error. Validate the pairing at admission time in TaskRef.Validate for v1 and v1beta1, mirroring the custom task validation Pipelines already perform, and correct the one example that set a lowercase kind on an ordinary task reference. Fixes #6557 Signed-off-by: Roshan <rosh.s568@gmail.com>
1 parent 83246ab commit 7fc1d86

5 files changed

Lines changed: 38 additions & 2 deletions

File tree

‎examples/v1/taskruns/beta/emit-array-results.yaml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,4 @@ metadata:
3636
spec:
3737
taskRef:
3838
name: write-array
39-
kind: task
39+
kind: Task

‎pkg/apis/pipeline/v1/taskref_validation.go‎

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,13 @@ func (ref *TaskRef) Validate(ctx context.Context) (errs *apis.FieldError) {
2828
if ref == nil {
2929
return errs
3030
}
31-
return validateRef(ctx, ref.Name, ref.Resolver, ref.Params)
31+
// A non-default Kind is only meaningful for a Custom Task reference, which
32+
// requires APIVersion to be set as well (see TaskRef.IsCustomTask). Without
33+
// APIVersion the kind is silently ignored at resolution: the ref resolves
34+
// as an ordinary namespaced Task when one exists, or fails with a
35+
// confusing not-found error.
36+
if ref.Kind != "" && ref.Kind != NamespacedTaskKind && ref.APIVersion == "" {
37+
errs = errs.Also(apis.ErrInvalidValue("custom task ref must specify apiVersion", "apiVersion"))
38+
}
39+
return errs.Also(validateRef(ctx, ref.Name, ref.Resolver, ref.Params))
3240
}

‎pkg/apis/pipeline/v1/taskref_validation_test.go‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,12 @@ func TestTaskRef_Valid(t *testing.T) {
3737
}, {
3838
name: "simple taskref",
3939
taskRef: &v1.TaskRef{Name: "taskrefname"},
40+
}, {
41+
name: "explicit default kind without apiversion",
42+
taskRef: &v1.TaskRef{Name: "taskrefname", Kind: v1.NamespacedTaskKind},
43+
}, {
44+
name: "custom task with kind and apiversion",
45+
taskRef: &v1.TaskRef{Name: "taskrefname", Kind: "Example", APIVersion: "example.dev/v1"},
4046
}, {
4147
name: "beta feature: valid resolver",
4248
taskRef: &v1.TaskRef{ResolverRef: v1.ResolverRef{Resolver: "git"}},
@@ -85,6 +91,10 @@ func TestTaskRef_Invalid(t *testing.T) {
8591
name: "missing taskref name",
8692
taskRef: &v1.TaskRef{},
8793
wantErr: apis.ErrMissingField("name"),
94+
}, {
95+
name: "custom task kind without apiversion",
96+
taskRef: &v1.TaskRef{Name: "foo", Kind: "Example"},
97+
wantErr: apis.ErrInvalidValue("custom task ref must specify apiVersion", "apiVersion"),
8898
}, {
8999
name: "invalid taskref name",
90100
taskRef: &v1.TaskRef{Name: "_foo"},

‎pkg/apis/pipeline/v1beta1/taskref_validation.go‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,14 @@ func (ref *TaskRef) Validate(ctx context.Context) (errs *apis.FieldError) {
3535
if apis.IsInCreate(ctx) && ref.Bundle != "" {
3636
errs = errs.Also(apis.ErrDisallowedFields("bundle"))
3737
}
38+
// A non-default Kind is only meaningful for a Custom Task reference, which
39+
// requires APIVersion to be set as well (see TaskRef.IsCustomTask). Without
40+
// APIVersion the kind is silently ignored at resolution: the ref resolves
41+
// as an ordinary namespaced Task when one exists, or fails with a
42+
// confusing not-found error.
43+
if ref.Kind != "" && ref.Kind != NamespacedTaskKind && ref.APIVersion == "" {
44+
errs = errs.Also(apis.ErrInvalidValue("custom task ref must specify apiVersion", "apiVersion"))
45+
}
3846
switch {
3947
case ref.Resolver != "" || ref.Params != nil:
4048
if ref.Params != nil {

‎pkg/apis/pipeline/v1beta1/taskref_validation_test.go‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,12 @@ func TestTaskRef_Valid(t *testing.T) {
3737
}, {
3838
name: "simple taskref",
3939
taskRef: &v1beta1.TaskRef{Name: "taskrefname"},
40+
}, {
41+
name: "explicit default kind without apiversion",
42+
taskRef: &v1beta1.TaskRef{Name: "taskrefname", Kind: v1beta1.NamespacedTaskKind},
43+
}, {
44+
name: "custom task with kind and apiversion",
45+
taskRef: &v1beta1.TaskRef{Name: "taskrefname", Kind: "Example", APIVersion: "example.dev/v1"},
4046
}, {
4147
name: "beta feature: valid resolver",
4248
taskRef: &v1beta1.TaskRef{ResolverRef: v1beta1.ResolverRef{Resolver: "git"}},
@@ -84,6 +90,10 @@ func TestTaskRef_Invalid(t *testing.T) {
8490
name: "missing taskref name",
8591
taskRef: &v1beta1.TaskRef{},
8692
wantErr: apis.ErrMissingField("name"),
93+
}, {
94+
name: "custom task kind without apiversion",
95+
taskRef: &v1beta1.TaskRef{Name: "foo", Kind: "Example"},
96+
wantErr: apis.ErrInvalidValue("custom task ref must specify apiVersion", "apiVersion"),
8797
}, {
8898
name: "taskRef with resolver and k8s style name",
8999
taskRef: &v1beta1.TaskRef{

0 commit comments

Comments
 (0)