Skip to content

Commit

Permalink
Add support for conversion webhook 🍸
Browse files Browse the repository at this point in the history
This adds a new webhook controller : ConversionController.
The `HubVersion` is the stored version, and Zygotes stores the types
of supported versions.

The CRDs are updated to setup the conversion strategy to webhook,
pointing to the tekton-pipelines-webhook.

An update in the webhook clusterrole is required for customresourcedefinitions.

Signed-off-by: Vincent Demeester <vdemeest@redhat.com>
  • Loading branch information
vdemeester committed Apr 16, 2020
1 parent 2b5dc48 commit 8186199
Show file tree
Hide file tree
Showing 8 changed files with 190 additions and 6 deletions.
69 changes: 68 additions & 1 deletion cmd/webhook/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"os"

defaultconfig "github.com/tektoncd/pipeline/pkg/apis/config"
"github.com/tektoncd/pipeline/pkg/apis/pipeline"
"github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1"
"github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1"
"github.com/tektoncd/pipeline/pkg/contexts"
Expand All @@ -37,6 +38,7 @@ import (
"knative.dev/pkg/webhook/certificates"
"knative.dev/pkg/webhook/configmaps"
"knative.dev/pkg/webhook/resourcesemantics"
"knative.dev/pkg/webhook/resourcesemantics/conversion"
"knative.dev/pkg/webhook/resourcesemantics/defaulting"
"knative.dev/pkg/webhook/resourcesemantics/validation"
)
Expand Down Expand Up @@ -85,6 +87,9 @@ func NewDefaultingAdmissionController(ctx context.Context, cmw configmap.Watcher
}

func NewValidationAdmissionController(ctx context.Context, cmw configmap.Watcher) *controller.Impl {
// Decorate contexts with the current state of the config.
store := defaultconfig.NewStore(logging.FromContext(ctx).Named("config-store"))
store.WatchConfigs(cmw)
return validation.NewAdmissionController(ctx,

// Name of the resource webhook.
Expand All @@ -98,7 +103,7 @@ func NewValidationAdmissionController(ctx context.Context, cmw configmap.Watcher

// A function that infuses the context passed to Validate/SetDefaults with custom metadata.
func(ctx context.Context) context.Context {
return ctx
return contexts.WithUpgradeViaDefaulting(store.ToContext(ctx))
},

// Whether to disallow unknown fields.
Expand All @@ -124,6 +129,67 @@ func NewConfigValidationController(ctx context.Context, cmw configmap.Watcher) *
)
}

func NewConversionController(ctx context.Context, cmw configmap.Watcher) *controller.Impl {
var (
v1alpha1_ = v1alpha1.SchemeGroupVersion.Version
v1beta1_ = v1beta1.SchemeGroupVersion.Version
)

return conversion.NewConversionController(ctx,
// The path on which to serve the webhook
"/resource-conversion",

// Specify the types of custom resource definitions that should be converted
map[schema.GroupKind]conversion.GroupKindConversion{
v1beta1.Kind("Task"): {
DefinitionName: pipeline.TaskResource.String(),
HubVersion: v1alpha1_,
Zygotes: map[string]conversion.ConvertibleObject{
v1alpha1_: &v1alpha1.Task{},
v1beta1_: &v1beta1.Task{},
},
},
v1beta1.Kind("ClusterTask"): {
DefinitionName: pipeline.ClusterTaskResource.String(),
HubVersion: v1alpha1_,
Zygotes: map[string]conversion.ConvertibleObject{
v1alpha1_: &v1alpha1.ClusterTask{},
v1beta1_: &v1beta1.ClusterTask{},
},
},
v1beta1.Kind("TaskRun"): {
DefinitionName: pipeline.TaskRunResource.String(),
HubVersion: v1alpha1_,
Zygotes: map[string]conversion.ConvertibleObject{
v1alpha1_: &v1alpha1.TaskRun{},
v1beta1_: &v1beta1.TaskRun{},
},
},
v1beta1.Kind("Pipeline"): {
DefinitionName: pipeline.PipelineResource.String(),
HubVersion: v1alpha1_,
Zygotes: map[string]conversion.ConvertibleObject{
v1alpha1_: &v1alpha1.Pipeline{},
v1beta1_: &v1beta1.Pipeline{},
},
},
v1beta1.Kind("PipelineRun"): {
DefinitionName: pipeline.PipelineRunResource.String(),
HubVersion: v1alpha1_,
Zygotes: map[string]conversion.ConvertibleObject{
v1alpha1_: &v1alpha1.PipelineRun{},
v1beta1_: &v1beta1.PipelineRun{},
},
},
},

// A function that infuses the context passed to ConvertTo/ConvertFrom/SetDefaults with custom metadata
func(ctx context.Context) context.Context {
return ctx
},
)
}

func main() {
serviceName := os.Getenv("WEBHOOK_SERVICE_NAME")
if serviceName == "" {
Expand All @@ -146,5 +212,6 @@ func main() {
NewDefaultingAdmissionController,
NewValidationAdmissionController,
NewConfigValidationController,
NewConversionController,
)
}
6 changes: 6 additions & 0 deletions config/200-clusterrole.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,12 @@ apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: tekton-pipelines-webhook-cluster-access
rules:
# The webhook needs to be able to list and update customresourcedefinitions,
# mainly to update the webhook certificates.ku
- apiGroups: ["apiextensions.k8s.io"]
resources: ["customresourcedefinitions", "customresourcedefinitions/status"]
verbs: ["get", "list", "update", "patch", "watch"]
# verbs: ["get", "list", "create", "update", "delete", "patch", "watch"]
- apiGroups: ["admissionregistration.k8s.io"]
# The webhook performs a reconciliation on these two resources and continuously
# updates configuration.
Expand Down
16 changes: 15 additions & 1 deletion config/300-clustertask.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,15 @@ metadata:
name: clustertasks.tekton.dev
spec:
group: tekton.dev
preserveUnknownFields: false
validation:
openAPIV3Schema:
type: object
# this is a work around so we don't need to flush out the
# schema for each version at this time
#
# see issue: https://github.com/knative/serving/issues/912
x-kubernetes-preserve-unknown-fields: true
versions:
- name: v1alpha1
served: true
Expand All @@ -36,4 +45,9 @@ spec:
# starts to increment
subresources:
status: {}
version: v1alpha1
conversion:
strategy: Webhook
webhookClientConfig:
service:
name: tekton-pipelines-webhook
namespace: tekton-pipelines
16 changes: 15 additions & 1 deletion config/300-pipeline.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,15 @@ metadata:
name: pipelines.tekton.dev
spec:
group: tekton.dev
preserveUnknownFields: false
validation:
openAPIV3Schema:
type: object
# this is a work around so we don't need to flush out the
# schema for each version at this time
#
# see issue: https://github.com/knative/serving/issues/912
x-kubernetes-preserve-unknown-fields: true
versions:
- name: v1alpha1
served: true
Expand All @@ -36,4 +45,9 @@ spec:
# starts to increment
subresources:
status: {}
version: v1alpha1
conversion:
strategy: Webhook
webhookClientConfig:
service:
name: tekton-pipelines-webhook
namespace: tekton-pipelines
16 changes: 15 additions & 1 deletion config/300-pipelinerun.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,15 @@ metadata:
name: pipelineruns.tekton.dev
spec:
group: tekton.dev
preserveUnknownFields: false
validation:
openAPIV3Schema:
type: object
# this is a work around so we don't need to flush out the
# schema for each version at this time
#
# see issue: https://github.com/knative/serving/issues/912
x-kubernetes-preserve-unknown-fields: true
versions:
- name: v1alpha1
served: true
Expand Down Expand Up @@ -52,4 +61,9 @@ spec:
# starts to increment
subresources:
status: {}
version: v1alpha1
conversion:
strategy: Webhook
webhookClientConfig:
service:
name: tekton-pipelines-webhook
namespace: tekton-pipelines
16 changes: 15 additions & 1 deletion config/300-task.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,15 @@ metadata:
name: tasks.tekton.dev
spec:
group: tekton.dev
preserveUnknownFields: false
validation:
openAPIV3Schema:
type: object
# this is a work around so we don't need to flush out the
# schema for each version at this time
#
# see issue: https://github.com/knative/serving/issues/912
x-kubernetes-preserve-unknown-fields: true
versions:
- name: v1alpha1
served: true
Expand All @@ -36,4 +45,9 @@ spec:
# starts to increment
subresources:
status: {}
version: v1alpha1
conversion:
strategy: Webhook
webhookClientConfig:
service:
name: tekton-pipelines-webhook
namespace: tekton-pipelines
16 changes: 15 additions & 1 deletion config/300-taskrun.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,15 @@ metadata:
name: taskruns.tekton.dev
spec:
group: tekton.dev
preserveUnknownFields: false
validation:
openAPIV3Schema:
type: object
# this is a work around so we don't need to flush out the
# schema for each version at this time
#
# see issue: https://github.com/knative/serving/issues/912
x-kubernetes-preserve-unknown-fields: true
versions:
- name: v1alpha1
served: true
Expand Down Expand Up @@ -52,4 +61,9 @@ spec:
# starts to increment
subresources:
status: {}
version: v1alpha1
conversion:
strategy: Webhook
webhookClientConfig:
service:
name: tekton-pipelines-webhook
namespace: tekton-pipelines
41 changes: 41 additions & 0 deletions pkg/apis/pipeline/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ limitations under the License.

package pipeline

import "k8s.io/apimachinery/pkg/runtime/schema"

const (
// GroupName is the Kubernetes resource group name for Pipeline types.
GroupName = "tekton.dev"
Expand All @@ -41,3 +43,42 @@ const (
// ConditionCheckKey is used as the label identifier for a ConditionCheck
ConditionCheckKey = "/conditionCheck"
)

var (
// TaskResource represents a Tekton Task
TaskResource = schema.GroupResource{
Group: GroupName,
Resource: "tasks",
}
// ClusterTaskResource represents a Tekton ClusterTask
ClusterTaskResource = schema.GroupResource{
Group: GroupName,
Resource: "clustertasks",
}
// TaskRunResource represents a Tekton TaskRun
TaskRunResource = schema.GroupResource{
Group: GroupName,
Resource: "taskruns",
}
// PipelineResource represents a Tekton Pipeline
PipelineResource = schema.GroupResource{
Group: GroupName,
Resource: "pipelines",
}
// PipelineRunResource represents a Tekton PipelineRun
PipelineRunResource = schema.GroupResource{
Group: GroupName,
Resource: "pipelineruns",
}

// PipelineResourceResource represents a Tekton PipelineResource
PipelineResourceResource = schema.GroupResource{
Group: GroupName,
Resource: "pipelineresources",
}
// ConditionResource represents a Tekton Condition
ConditionResource = schema.GroupResource{
Group: GroupName,
Resource: "conditions",
}
)

0 comments on commit 8186199

Please sign in to comment.