pkg/registry: add certificate storage
This commit is contained in:
		@@ -28,39 +28,41 @@ import (
 | 
				
			|||||||
type Resource string
 | 
					type Resource string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
	ClusterRoles             Resource = "clusterroles"
 | 
						CertificateSigningRequests Resource = "certificatesigningrequests"
 | 
				
			||||||
	ClusterRoleBindings      Resource = "clusterrolebindings"
 | 
						ClusterRoles               Resource = "clusterroles"
 | 
				
			||||||
	Controllers              Resource = "controllers"
 | 
						ClusterRoleBindings        Resource = "clusterrolebindings"
 | 
				
			||||||
	Daemonsets               Resource = "daemonsets"
 | 
						Controllers                Resource = "controllers"
 | 
				
			||||||
	Deployments              Resource = "deployments"
 | 
						Daemonsets                 Resource = "daemonsets"
 | 
				
			||||||
	Endpoints                Resource = "endpoints"
 | 
						Deployments                Resource = "deployments"
 | 
				
			||||||
	HorizontalPodAutoscalers Resource = "horizontalpodautoscalers"
 | 
						Endpoints                  Resource = "endpoints"
 | 
				
			||||||
	Ingress                  Resource = "ingress"
 | 
						HorizontalPodAutoscalers   Resource = "horizontalpodautoscalers"
 | 
				
			||||||
	PodDisruptionBudget      Resource = "poddisruptionbudgets"
 | 
						Ingress                    Resource = "ingress"
 | 
				
			||||||
	PetSet                   Resource = "petset"
 | 
						PodDisruptionBudget        Resource = "poddisruptionbudgets"
 | 
				
			||||||
	Jobs                     Resource = "jobs"
 | 
						PetSet                     Resource = "petset"
 | 
				
			||||||
	LimitRanges              Resource = "limitranges"
 | 
						Jobs                       Resource = "jobs"
 | 
				
			||||||
	Namespaces               Resource = "namespaces"
 | 
						LimitRanges                Resource = "limitranges"
 | 
				
			||||||
	NetworkPolicys           Resource = "networkpolicies"
 | 
						Namespaces                 Resource = "namespaces"
 | 
				
			||||||
	Nodes                    Resource = "nodes"
 | 
						NetworkPolicys             Resource = "networkpolicies"
 | 
				
			||||||
	PersistentVolumes        Resource = "persistentvolumes"
 | 
						Nodes                      Resource = "nodes"
 | 
				
			||||||
	PersistentVolumeClaims   Resource = "persistentvolumeclaims"
 | 
						PersistentVolumes          Resource = "persistentvolumes"
 | 
				
			||||||
	Pods                     Resource = "pods"
 | 
						PersistentVolumeClaims     Resource = "persistentvolumeclaims"
 | 
				
			||||||
	PodTemplates             Resource = "podtemplates"
 | 
						Pods                       Resource = "pods"
 | 
				
			||||||
	Replicasets              Resource = "replicasets"
 | 
						PodTemplates               Resource = "podtemplates"
 | 
				
			||||||
	ResourceQuotas           Resource = "resourcequotas"
 | 
						Replicasets                Resource = "replicasets"
 | 
				
			||||||
	ScheduledJobs            Resource = "scheduledjobs"
 | 
						ResourceQuotas             Resource = "resourcequotas"
 | 
				
			||||||
	Roles                    Resource = "roles"
 | 
						ScheduledJobs              Resource = "scheduledjobs"
 | 
				
			||||||
	RoleBindings             Resource = "rolebindings"
 | 
						Roles                      Resource = "roles"
 | 
				
			||||||
	Secrets                  Resource = "secrets"
 | 
						RoleBindings               Resource = "rolebindings"
 | 
				
			||||||
	ServiceAccounts          Resource = "serviceaccounts"
 | 
						Secrets                    Resource = "secrets"
 | 
				
			||||||
	Services                 Resource = "services"
 | 
						ServiceAccounts            Resource = "serviceaccounts"
 | 
				
			||||||
 | 
						Services                   Resource = "services"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var watchCacheSizes map[Resource]int
 | 
					var watchCacheSizes map[Resource]int
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func init() {
 | 
					func init() {
 | 
				
			||||||
	watchCacheSizes = make(map[Resource]int)
 | 
						watchCacheSizes = make(map[Resource]int)
 | 
				
			||||||
 | 
						watchCacheSizes[CertificateSigningRequests] = 1000
 | 
				
			||||||
	watchCacheSizes[ClusterRoles] = 100
 | 
						watchCacheSizes[ClusterRoles] = 100
 | 
				
			||||||
	watchCacheSizes[ClusterRoleBindings] = 100
 | 
						watchCacheSizes[ClusterRoleBindings] = 100
 | 
				
			||||||
	watchCacheSizes[Controllers] = 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