strategy.go 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. /*
  2. Copyright 2015 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 deployment
  14. import (
  15. "fmt"
  16. "reflect"
  17. "time"
  18. "k8s.io/kubernetes/pkg/api"
  19. "k8s.io/kubernetes/pkg/api/unversioned"
  20. "k8s.io/kubernetes/pkg/apis/extensions"
  21. "k8s.io/kubernetes/pkg/apis/extensions/validation"
  22. "k8s.io/kubernetes/pkg/controller/deployment/util"
  23. "k8s.io/kubernetes/pkg/fields"
  24. "k8s.io/kubernetes/pkg/labels"
  25. "k8s.io/kubernetes/pkg/registry/generic"
  26. "k8s.io/kubernetes/pkg/runtime"
  27. "k8s.io/kubernetes/pkg/util/validation/field"
  28. )
  29. // deploymentStrategy implements behavior for Deployments.
  30. type deploymentStrategy struct {
  31. runtime.ObjectTyper
  32. api.NameGenerator
  33. }
  34. // Strategy is the default logic that applies when creating and updating Deployment
  35. // objects via the REST API.
  36. var Strategy = deploymentStrategy{api.Scheme, api.SimpleNameGenerator}
  37. // NamespaceScoped is true for deployment.
  38. func (deploymentStrategy) NamespaceScoped() bool {
  39. return true
  40. }
  41. // PrepareForCreate clears fields that are not allowed to be set by end users on creation.
  42. func (deploymentStrategy) PrepareForCreate(ctx api.Context, obj runtime.Object) {
  43. deployment := obj.(*extensions.Deployment)
  44. deployment.Status = extensions.DeploymentStatus{}
  45. deployment.Generation = 1
  46. }
  47. // Validate validates a new deployment.
  48. func (deploymentStrategy) Validate(ctx api.Context, obj runtime.Object) field.ErrorList {
  49. deployment := obj.(*extensions.Deployment)
  50. return validation.ValidateDeployment(deployment)
  51. }
  52. // Canonicalize normalizes the object after validation.
  53. func (deploymentStrategy) Canonicalize(obj runtime.Object) {
  54. }
  55. // AllowCreateOnUpdate is false for deployments.
  56. func (deploymentStrategy) AllowCreateOnUpdate() bool {
  57. return false
  58. }
  59. // PrepareForUpdate clears fields that are not allowed to be set by end users on update.
  60. func (deploymentStrategy) PrepareForUpdate(ctx api.Context, obj, old runtime.Object) {
  61. newDeployment := obj.(*extensions.Deployment)
  62. oldDeployment := old.(*extensions.Deployment)
  63. newDeployment.Status = oldDeployment.Status
  64. // Spec updates bump the generation so that we can distinguish between
  65. // scaling events and template changes, annotation updates bump the generation
  66. // because annotations are copied from deployments to their replica sets.
  67. if !reflect.DeepEqual(newDeployment.Spec, oldDeployment.Spec) ||
  68. !reflect.DeepEqual(newDeployment.Annotations, oldDeployment.Annotations) {
  69. newDeployment.Generation = oldDeployment.Generation + 1
  70. }
  71. // Records timestamp on selector updates in annotation
  72. if !reflect.DeepEqual(newDeployment.Spec.Selector, oldDeployment.Spec.Selector) {
  73. if newDeployment.Annotations == nil {
  74. newDeployment.Annotations = make(map[string]string)
  75. }
  76. now := unversioned.Now()
  77. newDeployment.Annotations[util.SelectorUpdateAnnotation] = now.Format(time.RFC3339)
  78. }
  79. }
  80. // ValidateUpdate is the default update validation for an end user.
  81. func (deploymentStrategy) ValidateUpdate(ctx api.Context, obj, old runtime.Object) field.ErrorList {
  82. return validation.ValidateDeploymentUpdate(obj.(*extensions.Deployment), old.(*extensions.Deployment))
  83. }
  84. func (deploymentStrategy) AllowUnconditionalUpdate() bool {
  85. return true
  86. }
  87. type deploymentStatusStrategy struct {
  88. deploymentStrategy
  89. }
  90. var StatusStrategy = deploymentStatusStrategy{Strategy}
  91. // PrepareForUpdate clears fields that are not allowed to be set by end users on update of status
  92. func (deploymentStatusStrategy) PrepareForUpdate(ctx api.Context, obj, old runtime.Object) {
  93. newDeployment := obj.(*extensions.Deployment)
  94. oldDeployment := old.(*extensions.Deployment)
  95. newDeployment.Spec = oldDeployment.Spec
  96. newDeployment.Labels = oldDeployment.Labels
  97. }
  98. // ValidateUpdate is the default update validation for an end user updating status
  99. func (deploymentStatusStrategy) ValidateUpdate(ctx api.Context, obj, old runtime.Object) field.ErrorList {
  100. return validation.ValidateDeploymentStatusUpdate(obj.(*extensions.Deployment), old.(*extensions.Deployment))
  101. }
  102. // DeploymentToSelectableFields returns a field set that represents the object.
  103. func DeploymentToSelectableFields(deployment *extensions.Deployment) fields.Set {
  104. return generic.ObjectMetaFieldsSet(&deployment.ObjectMeta, true)
  105. }
  106. // MatchDeployment is the filter used by the generic etcd backend to route
  107. // watch events from etcd to clients of the apiserver only interested in specific
  108. // labels/fields.
  109. func MatchDeployment(label labels.Selector, field fields.Selector) *generic.SelectionPredicate {
  110. return &generic.SelectionPredicate{
  111. Label: label,
  112. Field: field,
  113. GetAttrs: func(obj runtime.Object) (labels.Set, fields.Set, error) {
  114. deployment, ok := obj.(*extensions.Deployment)
  115. if !ok {
  116. return nil, nil, fmt.Errorf("given object is not a deployment.")
  117. }
  118. return labels.Set(deployment.ObjectMeta.Labels), DeploymentToSelectableFields(deployment), nil
  119. },
  120. }
  121. }