strategy.go 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. /*
  2. Copyright 2014 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. // If you make changes to this file, you should also make the corresponding change in ReplicaSet.
  14. package controller
  15. import (
  16. "fmt"
  17. "reflect"
  18. "strconv"
  19. "k8s.io/kubernetes/pkg/api"
  20. "k8s.io/kubernetes/pkg/api/rest"
  21. "k8s.io/kubernetes/pkg/api/validation"
  22. "k8s.io/kubernetes/pkg/fields"
  23. "k8s.io/kubernetes/pkg/labels"
  24. "k8s.io/kubernetes/pkg/registry/generic"
  25. "k8s.io/kubernetes/pkg/runtime"
  26. "k8s.io/kubernetes/pkg/util/validation/field"
  27. )
  28. // rcStrategy implements verification logic for Replication Controllers.
  29. type rcStrategy struct {
  30. runtime.ObjectTyper
  31. api.NameGenerator
  32. }
  33. // Strategy is the default logic that applies when creating and updating Replication Controller objects.
  34. var Strategy = rcStrategy{api.Scheme, api.SimpleNameGenerator}
  35. // DefaultGarbageCollectionPolicy returns Orphan because that was the default
  36. // behavior before the server-side garbage collection was implemented.
  37. func (rcStrategy) DefaultGarbageCollectionPolicy() rest.GarbageCollectionPolicy {
  38. return rest.OrphanDependents
  39. }
  40. // NamespaceScoped returns true because all Replication Controllers need to be within a namespace.
  41. func (rcStrategy) NamespaceScoped() bool {
  42. return true
  43. }
  44. // PrepareForCreate clears the status of a replication controller before creation.
  45. func (rcStrategy) PrepareForCreate(ctx api.Context, obj runtime.Object) {
  46. controller := obj.(*api.ReplicationController)
  47. controller.Status = api.ReplicationControllerStatus{}
  48. controller.Generation = 1
  49. }
  50. // PrepareForUpdate clears fields that are not allowed to be set by end users on update.
  51. func (rcStrategy) PrepareForUpdate(ctx api.Context, obj, old runtime.Object) {
  52. newController := obj.(*api.ReplicationController)
  53. oldController := old.(*api.ReplicationController)
  54. // update is not allowed to set status
  55. newController.Status = oldController.Status
  56. // Any changes to the spec increment the generation number, any changes to the
  57. // status should reflect the generation number of the corresponding object. We push
  58. // the burden of managing the status onto the clients because we can't (in general)
  59. // know here what version of spec the writer of the status has seen. It may seem like
  60. // we can at first -- since obj contains spec -- but in the future we will probably make
  61. // status its own object, and even if we don't, writes may be the result of a
  62. // read-update-write loop, so the contents of spec may not actually be the spec that
  63. // the controller has *seen*.
  64. if !reflect.DeepEqual(oldController.Spec, newController.Spec) {
  65. newController.Generation = oldController.Generation + 1
  66. }
  67. }
  68. // Validate validates a new replication controller.
  69. func (rcStrategy) Validate(ctx api.Context, obj runtime.Object) field.ErrorList {
  70. controller := obj.(*api.ReplicationController)
  71. return validation.ValidateReplicationController(controller)
  72. }
  73. // Canonicalize normalizes the object after validation.
  74. func (rcStrategy) Canonicalize(obj runtime.Object) {
  75. }
  76. // AllowCreateOnUpdate is false for replication controllers; this means a POST is
  77. // needed to create one.
  78. func (rcStrategy) AllowCreateOnUpdate() bool {
  79. return false
  80. }
  81. // ValidateUpdate is the default update validation for an end user.
  82. func (rcStrategy) ValidateUpdate(ctx api.Context, obj, old runtime.Object) field.ErrorList {
  83. validationErrorList := validation.ValidateReplicationController(obj.(*api.ReplicationController))
  84. updateErrorList := validation.ValidateReplicationControllerUpdate(obj.(*api.ReplicationController), old.(*api.ReplicationController))
  85. return append(validationErrorList, updateErrorList...)
  86. }
  87. func (rcStrategy) AllowUnconditionalUpdate() bool {
  88. return true
  89. }
  90. // ControllerToSelectableFields returns a field set that represents the object.
  91. func ControllerToSelectableFields(controller *api.ReplicationController) fields.Set {
  92. objectMetaFieldsSet := generic.ObjectMetaFieldsSet(&controller.ObjectMeta, true)
  93. controllerSpecificFieldsSet := fields.Set{
  94. "status.replicas": strconv.Itoa(int(controller.Status.Replicas)),
  95. }
  96. return generic.MergeFieldsSets(objectMetaFieldsSet, controllerSpecificFieldsSet)
  97. }
  98. // MatchController is the filter used by the generic etcd backend to route
  99. // watch events from etcd to clients of the apiserver only interested in specific
  100. // labels/fields.
  101. func MatchController(label labels.Selector, field fields.Selector) *generic.SelectionPredicate {
  102. return &generic.SelectionPredicate{
  103. Label: label,
  104. Field: field,
  105. GetAttrs: func(obj runtime.Object) (labels.Set, fields.Set, error) {
  106. rc, ok := obj.(*api.ReplicationController)
  107. if !ok {
  108. return nil, nil, fmt.Errorf("Given object is not a replication controller.")
  109. }
  110. return labels.Set(rc.ObjectMeta.Labels), ControllerToSelectableFields(rc), nil
  111. },
  112. }
  113. }
  114. type rcStatusStrategy struct {
  115. rcStrategy
  116. }
  117. var StatusStrategy = rcStatusStrategy{Strategy}
  118. func (rcStatusStrategy) PrepareForUpdate(ctx api.Context, obj, old runtime.Object) {
  119. newRc := obj.(*api.ReplicationController)
  120. oldRc := old.(*api.ReplicationController)
  121. // update is not allowed to set spec
  122. newRc.Spec = oldRc.Spec
  123. }
  124. func (rcStatusStrategy) ValidateUpdate(ctx api.Context, obj, old runtime.Object) field.ErrorList {
  125. return validation.ValidateReplicationControllerStatusUpdate(obj.(*api.ReplicationController), old.(*api.ReplicationController))
  126. }