namebackreferences.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. /*
  2. Copyright 2018 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 config
  14. import (
  15. "strings"
  16. "sigs.k8s.io/kustomize/pkg/gvk"
  17. )
  18. // NameBackReferences is an association between a gvk.GVK and a list
  19. // of FieldSpec instances that could refer to it.
  20. //
  21. // It is used to handle name changes, and can be thought of as a
  22. // a contact list. If you change your own contact info (name,
  23. // phone number, etc.), you must tell your contacts or they won't
  24. // know about the change.
  25. //
  26. // For example, ConfigMaps can be used by Pods and everything that
  27. // contains a Pod; Deployment, Job, StatefulSet, etc. To change
  28. // the name of a ConfigMap instance from 'alice' to 'bob', one
  29. // must visit all objects that could refer to the ConfigMap, see if
  30. // they mention 'alice', and if so, change the reference to 'bob'.
  31. //
  32. // The NameBackReferences instance to aid in this could look like
  33. // {
  34. // kind: ConfigMap
  35. // version: v1
  36. // FieldSpecs:
  37. // - kind: Pod
  38. // version: v1
  39. // path: spec/volumes/configMap/name
  40. // - kind: Deployment
  41. // path: spec/template/spec/volumes/configMap/name
  42. // - kind: Job
  43. // path: spec/template/spec/volumes/configMap/name
  44. // (etc.)
  45. // }
  46. type NameBackReferences struct {
  47. gvk.Gvk `json:",inline,omitempty" yaml:",inline,omitempty"`
  48. FieldSpecs fsSlice `json:"FieldSpecs,omitempty" yaml:"FieldSpecs,omitempty"`
  49. }
  50. func (n NameBackReferences) String() string {
  51. var r []string
  52. for _, f := range n.FieldSpecs {
  53. r = append(r, f.String())
  54. }
  55. return n.Gvk.String() + ": (\n" +
  56. strings.Join(r, "\n") + "\n)"
  57. }
  58. type nbrSlice []NameBackReferences
  59. func (s nbrSlice) Len() int { return len(s) }
  60. func (s nbrSlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
  61. func (s nbrSlice) Less(i, j int) bool {
  62. return s[i].Gvk.IsLessThan(s[j].Gvk)
  63. }
  64. func (s nbrSlice) mergeAll(o nbrSlice) (result nbrSlice, err error) {
  65. result = s
  66. for _, r := range o {
  67. result, err = result.mergeOne(r)
  68. if err != nil {
  69. return nil, err
  70. }
  71. }
  72. return result, nil
  73. }
  74. func (s nbrSlice) mergeOne(other NameBackReferences) (nbrSlice, error) {
  75. var result nbrSlice
  76. var err error
  77. found := false
  78. for _, c := range s {
  79. if c.Gvk.Equals(other.Gvk) {
  80. c.FieldSpecs, err = c.FieldSpecs.mergeAll(other.FieldSpecs)
  81. if err != nil {
  82. return nil, err
  83. }
  84. found = true
  85. }
  86. result = append(result, c)
  87. }
  88. if !found {
  89. result = append(result, other)
  90. }
  91. return result, nil
  92. }