replace_visitor.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  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 strategy
  14. import (
  15. "k8s.io/kubernetes/pkg/kubectl/apply"
  16. )
  17. // replaceVisitor creates a patch to replace a remote field value with a local field value
  18. type replaceStrategy struct {
  19. strategic *delegatingStrategy
  20. options Options
  21. }
  22. func createReplaceStrategy(options Options, strategic *delegatingStrategy) replaceStrategy {
  23. return replaceStrategy{
  24. strategic,
  25. options,
  26. }
  27. }
  28. // MergeList returns a result by merging the recorded, local and remote values
  29. // - replacing the remote value with the local value
  30. func (v replaceStrategy) MergeList(e apply.ListElement) (apply.Result, error) {
  31. return v.doReplace(e)
  32. }
  33. // MergeMap returns a result by merging the recorded, local and remote values
  34. // - replacing the remote value with the local value
  35. func (v replaceStrategy) MergeMap(e apply.MapElement) (apply.Result, error) {
  36. return v.doReplace(e)
  37. }
  38. // MergeType returns a result by merging the recorded, local and remote values
  39. // - replacing the remote value with the local value
  40. func (v replaceStrategy) MergeType(e apply.TypeElement) (apply.Result, error) {
  41. return v.doReplace(e)
  42. }
  43. // MergePrimitive returns a result by merging the recorded, local and remote values
  44. // - replacing the remote value with the local value
  45. func (v replaceStrategy) MergePrimitive(e apply.PrimitiveElement) (apply.Result, error) {
  46. return v.doReplace(e)
  47. }
  48. // MergeEmpty
  49. func (v replaceStrategy) MergeEmpty(e apply.EmptyElement) (apply.Result, error) {
  50. return apply.Result{Operation: apply.SET}, nil
  51. }
  52. // replace returns the local value if specified, otherwise it returns the remote value
  53. // this works regardless of the approach
  54. func (v replaceStrategy) doReplace(e apply.Element) (apply.Result, error) {
  55. if result, done := v.doAddOrDelete(e); done {
  56. return result, nil
  57. }
  58. if err := v.doConflictDetect(e); err != nil {
  59. return apply.Result{}, err
  60. }
  61. if e.HasLocal() {
  62. // Specified locally, set the local value
  63. return apply.Result{Operation: apply.SET, MergedResult: e.GetLocal()}, nil
  64. } else if e.HasRemote() {
  65. // Not specified locally, set the remote value
  66. return apply.Result{Operation: apply.SET, MergedResult: e.GetRemote()}, nil
  67. } else {
  68. // Only specified in the recorded, drop the field.
  69. return apply.Result{Operation: apply.DROP, MergedResult: e.GetRemote()}, nil
  70. }
  71. }
  72. // doAddOrDelete will check if the field should be either added or deleted. If either is true, it will
  73. // true the operation and true. Otherwise it will return false.
  74. func (v replaceStrategy) doAddOrDelete(e apply.Element) (apply.Result, bool) {
  75. if apply.IsAdd(e) {
  76. return apply.Result{Operation: apply.SET, MergedResult: e.GetLocal()}, true
  77. }
  78. // Delete the List
  79. if apply.IsDrop(e) {
  80. return apply.Result{Operation: apply.DROP}, true
  81. }
  82. return apply.Result{}, false
  83. }
  84. // doConflictDetect returns error if element has conflict
  85. func (v replaceStrategy) doConflictDetect(e apply.Element) error {
  86. return v.strategic.doConflictDetect(e)
  87. }
  88. var _ apply.Strategy = &replaceStrategy{}