pkg/registry: add certificate storage
This commit is contained in:
		@@ -28,6 +28,7 @@ import (
 | 
			
		||||
type Resource string
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	CertificateSigningRequests Resource = "certificatesigningrequests"
 | 
			
		||||
	ClusterRoles               Resource = "clusterroles"
 | 
			
		||||
	ClusterRoleBindings        Resource = "clusterrolebindings"
 | 
			
		||||
	Controllers                Resource = "controllers"
 | 
			
		||||
@@ -61,6 +62,7 @@ var watchCacheSizes map[Resource]int
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	watchCacheSizes = make(map[Resource]int)
 | 
			
		||||
	watchCacheSizes[CertificateSigningRequests] = 1000
 | 
			
		||||
	watchCacheSizes[ClusterRoles] = 100
 | 
			
		||||
	watchCacheSizes[ClusterRoleBindings] = 100
 | 
			
		||||
	watchCacheSizes[Controllers] = 100
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										19
									
								
								pkg/registry/certificates/doc.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								pkg/registry/certificates/doc.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
			
		||||
/*
 | 
			
		||||
Copyright 2016 The Kubernetes Authors All rights reserved.
 | 
			
		||||
 | 
			
		||||
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 certificates provides Registry interface and its RESTStorage
 | 
			
		||||
// implementation for storing CertificateSigningRequest objects.
 | 
			
		||||
package certificates
 | 
			
		||||
							
								
								
									
										106
									
								
								pkg/registry/certificates/etcd/etcd.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								pkg/registry/certificates/etcd/etcd.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,106 @@
 | 
			
		||||
/*
 | 
			
		||||
Copyright 2016 The Kubernetes Authors All rights reserved.
 | 
			
		||||
 | 
			
		||||
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 etcd
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"k8s.io/kubernetes/pkg/api"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/api/rest"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/apis/certificates"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/fields"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/labels"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/registry/cachesize"
 | 
			
		||||
	csrregistry "k8s.io/kubernetes/pkg/registry/certificates"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/registry/generic"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/registry/generic/registry"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/runtime"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// REST implements a RESTStorage for CertificateSigningRequest against etcd
 | 
			
		||||
type REST struct {
 | 
			
		||||
	*registry.Store
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewREST returns a registry which will store CertificateSigningRequest in the given helper
 | 
			
		||||
func NewREST(opts generic.RESTOptions) (*REST, *StatusREST, *ApprovalREST) {
 | 
			
		||||
	prefix := "/certificatesigningrequests"
 | 
			
		||||
 | 
			
		||||
	newListFunc := func() runtime.Object { return &certificates.CertificateSigningRequestList{} }
 | 
			
		||||
	storageInterface := opts.Decorator(opts.Storage, cachesize.GetWatchCacheSizeByResource(cachesize.CertificateSigningRequests), &certificates.CertificateSigningRequest{}, prefix, csrregistry.Strategy, newListFunc)
 | 
			
		||||
 | 
			
		||||
	store := ®istry.Store{
 | 
			
		||||
		NewFunc:     func() runtime.Object { return &certificates.CertificateSigningRequest{} },
 | 
			
		||||
		NewListFunc: newListFunc,
 | 
			
		||||
		KeyRootFunc: func(ctx api.Context) string {
 | 
			
		||||
			return prefix
 | 
			
		||||
		},
 | 
			
		||||
		KeyFunc: func(ctx api.Context, id string) (string, error) {
 | 
			
		||||
			return registry.NoNamespaceKeyFunc(ctx, prefix, id)
 | 
			
		||||
		},
 | 
			
		||||
		ObjectNameFunc: func(obj runtime.Object) (string, error) {
 | 
			
		||||
			return obj.(*certificates.CertificateSigningRequest).Name, nil
 | 
			
		||||
		},
 | 
			
		||||
		PredicateFunc: func(label labels.Selector, field fields.Selector) generic.Matcher {
 | 
			
		||||
			return csrregistry.Matcher(label, field)
 | 
			
		||||
		},
 | 
			
		||||
		QualifiedResource:       certificates.Resource("certificatesigningrequests"),
 | 
			
		||||
		DeleteCollectionWorkers: opts.DeleteCollectionWorkers,
 | 
			
		||||
 | 
			
		||||
		CreateStrategy: csrregistry.Strategy,
 | 
			
		||||
		UpdateStrategy: csrregistry.Strategy,
 | 
			
		||||
 | 
			
		||||
		Storage: storageInterface,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Subresources use the same store and creation strategy, which only
 | 
			
		||||
	// allows empty subs. Updates to an existing subresource are handled by
 | 
			
		||||
	// dedicated strategies.
 | 
			
		||||
	statusStore := *store
 | 
			
		||||
	statusStore.UpdateStrategy = csrregistry.StatusStrategy
 | 
			
		||||
 | 
			
		||||
	approvalStore := *store
 | 
			
		||||
	approvalStore.UpdateStrategy = csrregistry.ApprovalStrategy
 | 
			
		||||
 | 
			
		||||
	return &REST{store}, &StatusREST{store: &statusStore}, &ApprovalREST{store: &approvalStore}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// StatusREST implements the REST endpoint for changing the status of a CSR.
 | 
			
		||||
type StatusREST struct {
 | 
			
		||||
	store *registry.Store
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (r *StatusREST) New() runtime.Object {
 | 
			
		||||
	return &certificates.CertificateSigningRequest{}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Update alters the status subset of an object.
 | 
			
		||||
func (r *StatusREST) Update(ctx api.Context, name string, objInfo rest.UpdatedObjectInfo) (runtime.Object, bool, error) {
 | 
			
		||||
	return r.store.Update(ctx, name, objInfo)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ApprovalREST implements the REST endpoint for changing the approval state of a CSR.
 | 
			
		||||
type ApprovalREST struct {
 | 
			
		||||
	store *registry.Store
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (r *ApprovalREST) New() runtime.Object {
 | 
			
		||||
	return &certificates.CertificateSigningRequest{}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Update alters the approval subset of an object.
 | 
			
		||||
func (r *ApprovalREST) Update(ctx api.Context, name string, objInfo rest.UpdatedObjectInfo) (runtime.Object, bool, error) {
 | 
			
		||||
	return r.store.Update(ctx, name, objInfo)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										92
									
								
								pkg/registry/certificates/registry.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								pkg/registry/certificates/registry.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,92 @@
 | 
			
		||||
/*
 | 
			
		||||
Copyright 2016 The Kubernetes Authors All rights reserved.
 | 
			
		||||
 | 
			
		||||
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 certificates
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"k8s.io/kubernetes/pkg/api"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/api/rest"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/apis/certificates"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/watch"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Registry is an interface for things that know how to store CSRs.
 | 
			
		||||
type Registry interface {
 | 
			
		||||
	ListCSRs(ctx api.Context, options *api.ListOptions) (*certificates.CertificateSigningRequestList, error)
 | 
			
		||||
	CreateCSR(ctx api.Context, csr *certificates.CertificateSigningRequest) error
 | 
			
		||||
	UpdateCSR(ctx api.Context, csr *certificates.CertificateSigningRequest) error
 | 
			
		||||
	GetCSR(ctx api.Context, csrID string) (*certificates.CertificateSigningRequest, error)
 | 
			
		||||
	DeleteCSR(ctx api.Context, csrID string) error
 | 
			
		||||
	WatchCSRs(ctx api.Context, options *api.ListOptions) (watch.Interface, error)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// storage puts strong typing around storage calls
 | 
			
		||||
type storage struct {
 | 
			
		||||
	rest.StandardStorage
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewRegistry returns a new Registry interface for the given Storage. Any mismatched
 | 
			
		||||
// types will panic.
 | 
			
		||||
func NewRegistry(s rest.StandardStorage) Registry {
 | 
			
		||||
	return &storage{s}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *storage) ListCSRs(ctx api.Context, options *api.ListOptions) (*certificates.CertificateSigningRequestList, error) {
 | 
			
		||||
	obj, err := s.List(ctx, options)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return obj.(*certificates.CertificateSigningRequestList), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *storage) CreateCSR(ctx api.Context, csr *certificates.CertificateSigningRequest) error {
 | 
			
		||||
	// Inject user.Info from request context if available and no
 | 
			
		||||
	// information was supplied. Don't smash existing user information
 | 
			
		||||
	// since it should be possible for a broadly-scoped user to request a
 | 
			
		||||
	// certificate on behalf of a more limited user.
 | 
			
		||||
	if user, ok := api.UserFrom(ctx); ok {
 | 
			
		||||
		if csr.Spec.Username == "" {
 | 
			
		||||
			csr.Spec.Username = user.GetName()
 | 
			
		||||
			csr.Spec.UID = user.GetUID()
 | 
			
		||||
			csr.Spec.Groups = user.GetGroups()
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	_, err := s.Create(ctx, csr)
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *storage) UpdateCSR(ctx api.Context, csr *certificates.CertificateSigningRequest) error {
 | 
			
		||||
	_, _, err := s.Update(ctx, csr.Name, rest.DefaultUpdatedObjectInfo(csr, api.Scheme))
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *storage) WatchCSRs(ctx api.Context, options *api.ListOptions) (watch.Interface, error) {
 | 
			
		||||
	return s.Watch(ctx, options)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *storage) GetCSR(ctx api.Context, name string) (*certificates.CertificateSigningRequest, error) {
 | 
			
		||||
	obj, err := s.Get(ctx, name)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	return obj.(*certificates.CertificateSigningRequest), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *storage) DeleteCSR(ctx api.Context, name string) error {
 | 
			
		||||
	_, err := s.Delete(ctx, name, nil)
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										177
									
								
								pkg/registry/certificates/strategy.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										177
									
								
								pkg/registry/certificates/strategy.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,177 @@
 | 
			
		||||
/*
 | 
			
		||||
Copyright 2016 The Kubernetes Authors All rights reserved.
 | 
			
		||||
 | 
			
		||||
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 certificates
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
 | 
			
		||||
	"k8s.io/kubernetes/pkg/api"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/apis/certificates"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/apis/certificates/validation"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/fields"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/labels"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/registry/generic"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/runtime"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/util/validation/field"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// csrStrategy implements behavior for CSRs
 | 
			
		||||
type csrStrategy struct {
 | 
			
		||||
	runtime.ObjectTyper
 | 
			
		||||
	api.NameGenerator
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// csrStrategy is the default logic that applies when creating and updating
 | 
			
		||||
// CSR objects.
 | 
			
		||||
var Strategy = csrStrategy{api.Scheme, api.SimpleNameGenerator}
 | 
			
		||||
 | 
			
		||||
// NamespaceScoped is true for CSRs.
 | 
			
		||||
func (csrStrategy) NamespaceScoped() bool {
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AllowCreateOnUpdate is false for CSRs.
 | 
			
		||||
func (csrStrategy) AllowCreateOnUpdate() bool {
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// PrepareForCreate clears fields that are not allowed to be set by end users
 | 
			
		||||
// on creation. Users cannot create any derived information, but we expect
 | 
			
		||||
// information about the requesting user to be injected by the registry
 | 
			
		||||
// interface. Clear everything else.
 | 
			
		||||
// TODO: check these ordering assumptions. better way to inject user info?
 | 
			
		||||
func (csrStrategy) PrepareForCreate(obj runtime.Object) {
 | 
			
		||||
	csr := obj.(*certificates.CertificateSigningRequest)
 | 
			
		||||
 | 
			
		||||
	// Be explicit that users cannot create pre-approved certificate requests.
 | 
			
		||||
	csr.Status = certificates.CertificateSigningRequestStatus{}
 | 
			
		||||
	csr.Status.Conditions = []certificates.CertificateSigningRequestCondition{}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// PrepareForUpdate clears fields that are not allowed to be set by end users
 | 
			
		||||
// on update. Certificate requests are immutable after creation except via subresources.
 | 
			
		||||
func (csrStrategy) PrepareForUpdate(obj, old runtime.Object) {
 | 
			
		||||
	newCSR := obj.(*certificates.CertificateSigningRequest)
 | 
			
		||||
	oldCSR := old.(*certificates.CertificateSigningRequest)
 | 
			
		||||
 | 
			
		||||
	newCSR.Spec = oldCSR.Spec
 | 
			
		||||
	newCSR.Status = oldCSR.Status
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Validate validates a new CSR. Validation must check for a correct signature.
 | 
			
		||||
func (csrStrategy) Validate(ctx api.Context, obj runtime.Object) field.ErrorList {
 | 
			
		||||
	csr := obj.(*certificates.CertificateSigningRequest)
 | 
			
		||||
	return validation.ValidateCertificateSigningRequest(csr)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Canonicalize normalizes the object after validation (which includes a signature check).
 | 
			
		||||
func (csrStrategy) Canonicalize(obj runtime.Object) {}
 | 
			
		||||
 | 
			
		||||
// ValidateUpdate is the default update validation for an end user.
 | 
			
		||||
func (csrStrategy) ValidateUpdate(ctx api.Context, obj, old runtime.Object) field.ErrorList {
 | 
			
		||||
	oldCSR := old.(*certificates.CertificateSigningRequest)
 | 
			
		||||
	newCSR := obj.(*certificates.CertificateSigningRequest)
 | 
			
		||||
	return validation.ValidateCertificateSigningRequestUpdate(newCSR, oldCSR)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// If AllowUnconditionalUpdate() is true and the object specified by
 | 
			
		||||
// the user does not have a resource version, then generic Update()
 | 
			
		||||
// populates it with the latest version. Else, it checks that the
 | 
			
		||||
// version specified by the user matches the version of latest etcd
 | 
			
		||||
// object.
 | 
			
		||||
func (csrStrategy) AllowUnconditionalUpdate() bool {
 | 
			
		||||
	return true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s csrStrategy) Export(obj runtime.Object, exact bool) error {
 | 
			
		||||
	csr, ok := obj.(*certificates.CertificateSigningRequest)
 | 
			
		||||
	if !ok {
 | 
			
		||||
		// unexpected programmer error
 | 
			
		||||
		return fmt.Errorf("unexpected object: %v", obj)
 | 
			
		||||
	}
 | 
			
		||||
	s.PrepareForCreate(obj)
 | 
			
		||||
	if exact {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
	// CSRs allow direct subresource edits, we clear them without exact so the CSR value can be reused.
 | 
			
		||||
	csr.Status = certificates.CertificateSigningRequestStatus{}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Storage strategy for the Status subresource
 | 
			
		||||
type csrStatusStrategy struct {
 | 
			
		||||
	csrStrategy
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var StatusStrategy = csrStatusStrategy{Strategy}
 | 
			
		||||
 | 
			
		||||
func (csrStatusStrategy) PrepareForUpdate(obj, old runtime.Object) {
 | 
			
		||||
	newCSR := obj.(*certificates.CertificateSigningRequest)
 | 
			
		||||
	oldCSR := old.(*certificates.CertificateSigningRequest)
 | 
			
		||||
 | 
			
		||||
	// Updating the Status should only update the Status and not the spec
 | 
			
		||||
	// or approval conditions. The intent is to separate the concerns of
 | 
			
		||||
	// approval and certificate issuance.
 | 
			
		||||
	newCSR.Spec = oldCSR.Spec
 | 
			
		||||
	newCSR.Status.Conditions = oldCSR.Status.Conditions
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (csrStatusStrategy) ValidateUpdate(ctx api.Context, obj, old runtime.Object) field.ErrorList {
 | 
			
		||||
	return validation.ValidateCertificateSigningRequestUpdate(obj.(*certificates.CertificateSigningRequest), old.(*certificates.CertificateSigningRequest))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Canonicalize normalizes the object after validation.
 | 
			
		||||
func (csrStatusStrategy) Canonicalize(obj runtime.Object) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Storage strategy for the Approval subresource
 | 
			
		||||
type csrApprovalStrategy struct {
 | 
			
		||||
	csrStrategy
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var ApprovalStrategy = csrApprovalStrategy{Strategy}
 | 
			
		||||
 | 
			
		||||
func (csrApprovalStrategy) PrepareForUpdate(obj, old runtime.Object) {
 | 
			
		||||
	newCSR := obj.(*certificates.CertificateSigningRequest)
 | 
			
		||||
	oldCSR := old.(*certificates.CertificateSigningRequest)
 | 
			
		||||
 | 
			
		||||
	// Updating the approval should only update the conditions.
 | 
			
		||||
	newCSR.Spec = oldCSR.Spec
 | 
			
		||||
	oldCSR.Status.Conditions = newCSR.Status.Conditions
 | 
			
		||||
	newCSR.Status = oldCSR.Status
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (csrApprovalStrategy) ValidateUpdate(ctx api.Context, obj, old runtime.Object) field.ErrorList {
 | 
			
		||||
	return validation.ValidateCertificateSigningRequestUpdate(obj.(*certificates.CertificateSigningRequest), old.(*certificates.CertificateSigningRequest))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Matcher returns a generic matcher for a given label and field selector.
 | 
			
		||||
func Matcher(label labels.Selector, field fields.Selector) generic.Matcher {
 | 
			
		||||
	return generic.MatcherFunc(func(obj runtime.Object) (bool, error) {
 | 
			
		||||
		sa, ok := obj.(*certificates.CertificateSigningRequest)
 | 
			
		||||
		if !ok {
 | 
			
		||||
			return false, fmt.Errorf("not a CertificateSigningRequest")
 | 
			
		||||
		}
 | 
			
		||||
		fields := SelectableFields(sa)
 | 
			
		||||
		return label.Matches(labels.Set(sa.Labels)) && field.Matches(fields), nil
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SelectableFields returns a label set that can be used for filter selection
 | 
			
		||||
func SelectableFields(obj *certificates.CertificateSigningRequest) labels.Set {
 | 
			
		||||
	return labels.Set{}
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user