Skip to content

Commit

Permalink
make the webhook controller name configurable
Browse files Browse the repository at this point in the history
Introduce a new env. variable to provide the admission controller name -
WEBHOOK_ADMISSION_CONTROLLER_NAME

The webhook contains multiple controllers including mutating/validating webhook
and the conversion controller. All controllers are hard coded to
webhook.pipeline.tekton.dev, config.webhook.pipeline.tekton.dev,
and validation.webhook.pipeline.tekton.dev.

This commit adds a new env. variable in the webhook deployment such that this
controller name can be configured from the deployment yaml if needed. Also added
instructions in webhook deployment with the list of changes if the default
value is changed.

Signed-off-by: pritidesai <pdesai@us.ibm.com>
  • Loading branch information
pritidesai authored and tekton-robot committed Jan 23, 2023
1 parent d46b58b commit e5ca63b
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 53 deletions.
120 changes: 67 additions & 53 deletions cmd/webhook/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"log"
"net/http"
"os"
"strings"

defaultconfig "github.com/tektoncd/pipeline/pkg/apis/config"
"github.com/tektoncd/pipeline/pkg/apis/pipeline"
Expand Down Expand Up @@ -74,73 +75,81 @@ var types = map[schema.GroupVersionKind]resourcesemantics.GenericCRD{
resolutionv1beta1.SchemeGroupVersion.WithKind("ResolutionRequest"): &resolutionv1beta1.ResolutionRequest{},
}

func newDefaultingAdmissionController(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)
func newDefaultingAdmissionController(name string) func(context.Context, configmap.Watcher) *controller.Impl {
return func(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 defaulting.NewAdmissionController(ctx,

return defaulting.NewAdmissionController(ctx,
// Name of the resource webhook, it is the value of the environment variable WEBHOOK_ADMISSION_CONTROLLER_NAME
// default is "webhook.pipeline.tekton.dev"
name,

// Name of the resource webhook.
"webhook.pipeline.tekton.dev",
// The path on which to serve the webhook.
"/defaulting",

// The path on which to serve the webhook.
"/defaulting",
// The resources to validate and default.
types,

// The resources to validate and default.
types,

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

// Whether to disallow unknown fields.
true,
)
// Whether to disallow unknown fields.
true,
)
}
}

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,
func newValidationAdmissionController(name string) func(context.Context, configmap.Watcher) *controller.Impl {
return func(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.
"validation.webhook.pipeline.tekton.dev",
// Name of the validation webhook, it is based on the value of the environment variable WEBHOOK_ADMISSION_CONTROLLER_NAME
// default is "validation.webhook.pipeline.tekton.dev"
strings.Join([]string{"validation", name}, "."),

// The path on which to serve the webhook.
"/resource-validation",
// The path on which to serve the webhook.
"/resource-validation",

// The resources to validate and default.
types,
// The resources to validate and default.
types,

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

// Whether to disallow unknown fields.
true,
)
// Whether to disallow unknown fields.
true,
)
}
}

func newConfigValidationController(ctx context.Context, cmw configmap.Watcher) *controller.Impl {
return configmaps.NewAdmissionController(ctx,
func newConfigValidationController(name string) func(context.Context, configmap.Watcher) *controller.Impl {
return func(ctx context.Context, cmw configmap.Watcher) *controller.Impl {
return configmaps.NewAdmissionController(ctx,

// Name of the configmap webhook.
"config.webhook.pipeline.tekton.dev",
// Name of the configmap webhook, it is based on the value of the environment variable WEBHOOK_ADMISSION_CONTROLLER_NAME
// default is "config.webhook.pipeline.tekton.dev"
strings.Join([]string{"config", name}, "."),

// The path on which to serve the webhook.
"/config-validation",
// The path on which to serve the webhook.
"/config-validation",

// The configmaps to validate.
configmap.Constructors{
logging.ConfigMapName(): logging.NewConfigFromConfigMap,
defaultconfig.GetDefaultsConfigName(): defaultconfig.NewDefaultsFromConfigMap,
pkgleaderelection.ConfigMapName(): pkgleaderelection.NewConfigFromConfigMap,
},
)
// The configmaps to validate.
configmap.Constructors{
logging.ConfigMapName(): logging.NewConfigFromConfigMap,
defaultconfig.GetDefaultsConfigName(): defaultconfig.NewDefaultsFromConfigMap,
pkgleaderelection.ConfigMapName(): pkgleaderelection.NewConfigFromConfigMap,
},
)
}
}

func newConversionController(ctx context.Context, cmw configmap.Watcher) *controller.Impl {
Expand Down Expand Up @@ -218,6 +227,11 @@ func main() {
secretName = "webhook-certs" // #nosec
}

webhookName := os.Getenv("WEBHOOK_ADMISSION_CONTROLLER_NAME")
if webhookName == "" {
webhookName = "webhook.pipeline.tekton.dev"
}

// Scope informers to the webhook's namespace instead of cluster-wide
ctx := injection.WithNamespaceScope(signals.NewContext(), system.Namespace())

Expand Down Expand Up @@ -247,9 +261,9 @@ func main() {

sharedmain.MainWithContext(ctx, serviceName,
certificates.NewController,
newDefaultingAdmissionController,
newValidationAdmissionController,
newConfigValidationController,
newDefaultingAdmissionController(webhookName),
newValidationAdmissionController(webhookName),
newConfigValidationController(webhookName),
newConversionController,
)
}
Expand Down
9 changes: 9 additions & 0 deletions config/webhook.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,15 @@ spec:
# containerPort "https-webhook" to the same value.
- name: WEBHOOK_PORT
value: "8443"
# if you change WEBHOOK_ADMISSION_CONTROLLER_NAME, you will also need to update
# the webhooks.name in 500-webhooks.yaml to include the new names of admission webhooks.
# Additionally, you will also need to change the resource names (metadata.name) of
# "MutatingWebhookConfiguration" and "ValidatingWebhookConfiguration" in 500-webhooks.yaml
# to reflect the change in the name of the admission webhook.
# Followed by changing the webhook's Role in 200-clusterrole.yaml to update the "resourceNames" of
# "mutatingwebhookconfigurations" and "validatingwebhookconfigurations" resources.
- name: WEBHOOK_ADMISSION_CONTROLLER_NAME
value: webhook.pipeline.tekton.dev
- name: WEBHOOK_SERVICE_NAME
value: tekton-pipelines-webhook
- name: WEBHOOK_SECRET_NAME
Expand Down

0 comments on commit e5ca63b

Please sign in to comment.