mirror of https://github.com/knative/pkg.git
				
				
				
			
		
			
				
	
	
		
			256 lines
		
	
	
		
			8.6 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			256 lines
		
	
	
		
			8.6 KiB
		
	
	
	
		
			Go
		
	
	
	
| /*
 | |
| Copyright 2019 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
 | |
| 
 | |
|     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 apis
 | |
| 
 | |
| import (
 | |
| 	"context"
 | |
| 	"net/http"
 | |
| 
 | |
| 	authenticationv1 "k8s.io/api/authentication/v1"
 | |
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | |
| )
 | |
| 
 | |
| // This is attached to contexts passed to webhook interfaces when
 | |
| // the receiver being validated is being created.
 | |
| type inCreateKey struct{}
 | |
| 
 | |
| // WithinCreate is used to note that the webhook is calling within
 | |
| // the context of a Create operation.
 | |
| func WithinCreate(ctx context.Context) context.Context {
 | |
| 	return context.WithValue(ctx, inCreateKey{}, struct{}{})
 | |
| }
 | |
| 
 | |
| // IsInCreate checks whether the context is a Create.
 | |
| func IsInCreate(ctx context.Context) bool {
 | |
| 	return ctx.Value(inCreateKey{}) != nil
 | |
| }
 | |
| 
 | |
| // This is attached to contexts passed to webhook interfaces when
 | |
| // the receiver being validated is being deleted.
 | |
| type inDeleteKey struct{}
 | |
| 
 | |
| // WithinDelete is used to note that the webhook is calling within
 | |
| // the context of a Delete operation.
 | |
| func WithinDelete(ctx context.Context) context.Context {
 | |
| 	return context.WithValue(ctx, inDeleteKey{}, struct{}{})
 | |
| }
 | |
| 
 | |
| // IsInDelete checks whether the context is a Delete.
 | |
| func IsInDelete(ctx context.Context) bool {
 | |
| 	return ctx.Value(inDeleteKey{}) != nil
 | |
| }
 | |
| 
 | |
| // This is attached to contexts passed to webhook interfaces when
 | |
| // the receiver being validated is being updated.
 | |
| type inUpdateKey struct{}
 | |
| 
 | |
| type updatePayload struct {
 | |
| 	base        interface{}
 | |
| 	subresource string
 | |
| }
 | |
| 
 | |
| // WithinUpdate is used to note that the webhook is calling within
 | |
| // the context of a Update operation.
 | |
| func WithinUpdate(ctx context.Context, base interface{}) context.Context {
 | |
| 	return context.WithValue(ctx, inUpdateKey{}, &updatePayload{
 | |
| 		base: base,
 | |
| 	})
 | |
| }
 | |
| 
 | |
| // WithinSubResourceUpdate is used to note that the webhook is calling within
 | |
| // the context of a Update operation on a subresource.
 | |
| func WithinSubResourceUpdate(ctx context.Context, base interface{}, sr string) context.Context {
 | |
| 	return context.WithValue(ctx, inUpdateKey{}, &updatePayload{
 | |
| 		base:        base,
 | |
| 		subresource: sr,
 | |
| 	})
 | |
| }
 | |
| 
 | |
| // IsInUpdate checks whether the context is an Update.
 | |
| func IsInUpdate(ctx context.Context) bool {
 | |
| 	return ctx.Value(inUpdateKey{}) != nil
 | |
| }
 | |
| 
 | |
| // IsInStatusUpdate checks whether the context is an Update.
 | |
| func IsInStatusUpdate(ctx context.Context) bool {
 | |
| 	value := ctx.Value(inUpdateKey{})
 | |
| 	if value == nil {
 | |
| 		return false
 | |
| 	}
 | |
| 	up := value.(*updatePayload)
 | |
| 	return up.subresource == "status"
 | |
| }
 | |
| 
 | |
| // GetBaseline returns the baseline of the update, or nil when we
 | |
| // are not within an update context.
 | |
| func GetBaseline(ctx context.Context) interface{} {
 | |
| 	value := ctx.Value(inUpdateKey{})
 | |
| 	if value == nil {
 | |
| 		return nil
 | |
| 	}
 | |
| 	return value.(*updatePayload).base
 | |
| }
 | |
| 
 | |
| // This is attached to contexts passed to webhook interfaces when
 | |
| // the receiver being validated is being created.
 | |
| type userInfoKey struct{}
 | |
| 
 | |
| // WithUserInfo is used to note that the webhook is calling within
 | |
| // the context of a Create operation.
 | |
| func WithUserInfo(ctx context.Context, ui *authenticationv1.UserInfo) context.Context {
 | |
| 	return context.WithValue(ctx, userInfoKey{}, ui)
 | |
| }
 | |
| 
 | |
| // GetUserInfo accesses the UserInfo attached to the webhook context.
 | |
| func GetUserInfo(ctx context.Context) *authenticationv1.UserInfo {
 | |
| 	if ui, ok := ctx.Value(userInfoKey{}).(*authenticationv1.UserInfo); ok {
 | |
| 		return ui
 | |
| 	}
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| // This is attached to contexts as they are passed down through a resource
 | |
| // being validated or defaulted to signal the ObjectMeta of the enclosing
 | |
| // resource.
 | |
| type parentMetaKey struct{}
 | |
| 
 | |
| // WithinParent attaches the ObjectMeta of the resource enclosing the
 | |
| // nested resources we are validating.  This is intended for use with
 | |
| // interfaces like apis.Defaultable and apis.Validatable.
 | |
| func WithinParent(ctx context.Context, om metav1.ObjectMeta) context.Context {
 | |
| 	return context.WithValue(ctx, parentMetaKey{}, om)
 | |
| }
 | |
| 
 | |
| // IsWithinParent returns true if we're within parent context.
 | |
| func IsWithinParent(ctx context.Context) bool {
 | |
| 	_, ok := ctx.Value(parentMetaKey{}).(metav1.ObjectMeta)
 | |
| 	return ok
 | |
| }
 | |
| 
 | |
| // ParentMeta accesses the ObjectMeta of the enclosing parent resource
 | |
| // from the context.  See WithinParent for how to attach the parent's
 | |
| // ObjectMeta to the context.
 | |
| func ParentMeta(ctx context.Context) metav1.ObjectMeta {
 | |
| 	if om, ok := ctx.Value(parentMetaKey{}).(metav1.ObjectMeta); ok {
 | |
| 		return om
 | |
| 	}
 | |
| 	return metav1.ObjectMeta{}
 | |
| }
 | |
| 
 | |
| // This is attached to contexts as they are passed down through a resource
 | |
| // being validated or defaulted to signal that we are within a Spec.
 | |
| type inSpec struct{}
 | |
| 
 | |
| // WithinSpec notes on the context that further validation or defaulting
 | |
| // is within the context of a Spec.  This is intended for use with
 | |
| // interfaces like apis.Defaultable and apis.Validatable.
 | |
| func WithinSpec(ctx context.Context) context.Context {
 | |
| 	return context.WithValue(ctx, inSpec{}, struct{}{})
 | |
| }
 | |
| 
 | |
| // IsInSpec returns whether the context of validation or defaulting is
 | |
| // the Spec of the parent resource.
 | |
| func IsInSpec(ctx context.Context) bool {
 | |
| 	return ctx.Value(inSpec{}) != nil
 | |
| }
 | |
| 
 | |
| // This is attached to contexts as they are passed down through a resource
 | |
| // being validated or defaulted to signal that we are within a Status.
 | |
| type inStatus struct{}
 | |
| 
 | |
| // WithinStatus notes on the context that further validation or defaulting
 | |
| // is within the context of a Status.  This is intended for use with
 | |
| // interfaces like apis.Defaultable and apis.Validatable.
 | |
| func WithinStatus(ctx context.Context) context.Context {
 | |
| 	return context.WithValue(ctx, inStatus{}, struct{}{})
 | |
| }
 | |
| 
 | |
| // IsInStatus returns whether the context of validation or defaulting is
 | |
| // the Status of the parent resource.
 | |
| func IsInStatus(ctx context.Context) bool {
 | |
| 	return ctx.Value(inStatus{}) != nil
 | |
| }
 | |
| 
 | |
| // This is attached to contexts as they are passed down through a resource
 | |
| // being validated to direct them to disallow deprecated fields.
 | |
| type disallowDeprecated struct{}
 | |
| 
 | |
| // DisallowDeprecated notes on the context that further validation
 | |
| // should disallow the used of deprecated fields. This may be used
 | |
| // to ensure that new paths through resources to a common type don't
 | |
| // allow the mistakes of old versions to be introduced.
 | |
| func DisallowDeprecated(ctx context.Context) context.Context {
 | |
| 	return context.WithValue(ctx, disallowDeprecated{}, struct{}{})
 | |
| }
 | |
| 
 | |
| // IsDeprecatedAllowed checks the context to see whether deprecated fields
 | |
| // are allowed.
 | |
| func IsDeprecatedAllowed(ctx context.Context) bool {
 | |
| 	return ctx.Value(disallowDeprecated{}) == nil
 | |
| }
 | |
| 
 | |
| // This is attached to contexts as they are passed down through a resource
 | |
| // being validated to direct them to allow namespaces (or missing namespace)
 | |
| // outside the parent (as indicated by WithinParent.
 | |
| type allowDifferentNamespace struct{}
 | |
| 
 | |
| // AllowDifferentNamespace notes on the context that further validation
 | |
| // should allow different namespaces from the encapsulating object. Mainly
 | |
| // used by KReference, since it by default requires namespaces to match.
 | |
| func AllowDifferentNamespace(ctx context.Context) context.Context {
 | |
| 	return context.WithValue(ctx, allowDifferentNamespace{}, struct{}{})
 | |
| }
 | |
| 
 | |
| // IsDifferentNamespaceAllowed checks the context to see whether different
 | |
| // namespace is allowed from the encapsulating object.
 | |
| func IsDifferentNamespaceAllowed(ctx context.Context) bool {
 | |
| 	return ctx.Value(allowDifferentNamespace{}) != nil
 | |
| }
 | |
| 
 | |
| // This is attached to contexts passed to webhook interfaces when the user
 | |
| // has requested DryRun mode.
 | |
| type isDryRun struct{}
 | |
| 
 | |
| // WithDryRun is used to indicate that this call is in DryRun mode.
 | |
| func WithDryRun(ctx context.Context) context.Context {
 | |
| 	return context.WithValue(ctx, isDryRun{}, struct{}{})
 | |
| }
 | |
| 
 | |
| // IsDryRun indicates that this request is in DryRun mode.
 | |
| func IsDryRun(ctx context.Context) bool {
 | |
| 	return ctx.Value(isDryRun{}) != nil
 | |
| }
 | |
| 
 | |
| // This is attached to contexts passed to webhook interfaces with
 | |
| // additional context from the HTTP request.
 | |
| type httpReq struct{}
 | |
| 
 | |
| // WithHTTPRequest associated the HTTP request object the webhook
 | |
| // received with the context.
 | |
| func WithHTTPRequest(ctx context.Context, r *http.Request) context.Context {
 | |
| 	return context.WithValue(ctx, httpReq{}, r)
 | |
| }
 | |
| 
 | |
| // GetHTTPRequest fetches the raw HTTP request received by the webhook.
 | |
| func GetHTTPRequest(ctx context.Context) *http.Request {
 | |
| 	v := ctx.Value(httpReq{})
 | |
| 	if v == nil {
 | |
| 		return nil
 | |
| 	}
 | |
| 	return v.(*http.Request)
 | |
| }
 |