strategy.go 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. /*
  2. Copyright 2017 The Kubernetes Authors.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package volumeattachment
  14. import (
  15. "context"
  16. storageapiv1beta1 "k8s.io/api/storage/v1beta1"
  17. metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
  18. "k8s.io/apimachinery/pkg/runtime"
  19. "k8s.io/apimachinery/pkg/runtime/schema"
  20. "k8s.io/apimachinery/pkg/util/validation/field"
  21. genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
  22. "k8s.io/apiserver/pkg/storage/names"
  23. utilfeature "k8s.io/apiserver/pkg/util/feature"
  24. "k8s.io/kubernetes/pkg/api/legacyscheme"
  25. "k8s.io/kubernetes/pkg/apis/storage"
  26. "k8s.io/kubernetes/pkg/apis/storage/validation"
  27. "k8s.io/kubernetes/pkg/features"
  28. )
  29. // volumeAttachmentStrategy implements behavior for VolumeAttachment objects
  30. type volumeAttachmentStrategy struct {
  31. runtime.ObjectTyper
  32. names.NameGenerator
  33. }
  34. // Strategy is the default logic that applies when creating and updating
  35. // VolumeAttachment objects via the REST API.
  36. var Strategy = volumeAttachmentStrategy{legacyscheme.Scheme, names.SimpleNameGenerator}
  37. func (volumeAttachmentStrategy) NamespaceScoped() bool {
  38. return false
  39. }
  40. // ResetBeforeCreate clears the Status field which is not allowed to be set by end users on creation.
  41. func (volumeAttachmentStrategy) PrepareForCreate(ctx context.Context, obj runtime.Object) {
  42. var groupVersion schema.GroupVersion
  43. if requestInfo, found := genericapirequest.RequestInfoFrom(ctx); found {
  44. groupVersion = schema.GroupVersion{Group: requestInfo.APIGroup, Version: requestInfo.APIVersion}
  45. }
  46. volumeAttachment := obj.(*storage.VolumeAttachment)
  47. switch groupVersion {
  48. case storageapiv1beta1.SchemeGroupVersion:
  49. // allow modification of status for v1beta1
  50. default:
  51. volumeAttachment := obj.(*storage.VolumeAttachment)
  52. volumeAttachment.Status = storage.VolumeAttachmentStatus{}
  53. }
  54. if !utilfeature.DefaultFeatureGate.Enabled(features.CSIMigration) {
  55. volumeAttachment.Spec.Source.InlineVolumeSpec = nil
  56. }
  57. }
  58. func (volumeAttachmentStrategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList {
  59. volumeAttachment := obj.(*storage.VolumeAttachment)
  60. errs := validation.ValidateVolumeAttachment(volumeAttachment)
  61. var groupVersion schema.GroupVersion
  62. if requestInfo, found := genericapirequest.RequestInfoFrom(ctx); found {
  63. groupVersion = schema.GroupVersion{Group: requestInfo.APIGroup, Version: requestInfo.APIVersion}
  64. }
  65. switch groupVersion {
  66. case storageapiv1beta1.SchemeGroupVersion:
  67. // no extra validation
  68. default:
  69. // tighten up validation of newly created v1 attachments
  70. errs = append(errs, validation.ValidateVolumeAttachmentV1(volumeAttachment)...)
  71. }
  72. return errs
  73. }
  74. // Canonicalize normalizes the object after validation.
  75. func (volumeAttachmentStrategy) Canonicalize(obj runtime.Object) {
  76. }
  77. func (volumeAttachmentStrategy) AllowCreateOnUpdate() bool {
  78. return false
  79. }
  80. // PrepareForUpdate sets the Status fields which is not allowed to be set by an end user updating a VolumeAttachment
  81. func (volumeAttachmentStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object) {
  82. var groupVersion schema.GroupVersion
  83. if requestInfo, found := genericapirequest.RequestInfoFrom(ctx); found {
  84. groupVersion = schema.GroupVersion{Group: requestInfo.APIGroup, Version: requestInfo.APIVersion}
  85. }
  86. newVolumeAttachment := obj.(*storage.VolumeAttachment)
  87. oldVolumeAttachment := old.(*storage.VolumeAttachment)
  88. switch groupVersion {
  89. case storageapiv1beta1.SchemeGroupVersion:
  90. // allow modification of Status via main resource for v1beta1
  91. default:
  92. newVolumeAttachment.Status = oldVolumeAttachment.Status
  93. // No need to increment Generation because we don't allow updates to spec
  94. }
  95. if !utilfeature.DefaultFeatureGate.Enabled(features.CSIMigration) && oldVolumeAttachment.Spec.Source.InlineVolumeSpec == nil {
  96. newVolumeAttachment.Spec.Source.InlineVolumeSpec = nil
  97. }
  98. }
  99. func (volumeAttachmentStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList {
  100. newVolumeAttachmentObj := obj.(*storage.VolumeAttachment)
  101. oldVolumeAttachmentObj := old.(*storage.VolumeAttachment)
  102. errorList := validation.ValidateVolumeAttachment(newVolumeAttachmentObj)
  103. return append(errorList, validation.ValidateVolumeAttachmentUpdate(newVolumeAttachmentObj, oldVolumeAttachmentObj)...)
  104. }
  105. func (volumeAttachmentStrategy) AllowUnconditionalUpdate() bool {
  106. return false
  107. }
  108. // volumeAttachmentStatusStrategy implements behavior for VolumeAttachmentStatus subresource
  109. type volumeAttachmentStatusStrategy struct {
  110. volumeAttachmentStrategy
  111. }
  112. // StatusStrategy is the default logic that applies when creating and updating
  113. // VolumeAttachmentStatus subresource via the REST API.
  114. var StatusStrategy = volumeAttachmentStatusStrategy{Strategy}
  115. // PrepareForUpdate sets the Status fields which is not allowed to be set by an end user updating a VolumeAttachment
  116. func (volumeAttachmentStatusStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object) {
  117. newVolumeAttachment := obj.(*storage.VolumeAttachment)
  118. oldVolumeAttachment := old.(*storage.VolumeAttachment)
  119. newVolumeAttachment.Spec = oldVolumeAttachment.Spec
  120. metav1.ResetObjectMetaForStatus(&newVolumeAttachment.ObjectMeta, &oldVolumeAttachment.ObjectMeta)
  121. }