map_element.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  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 parse
  14. import (
  15. "k8s.io/kube-openapi/pkg/util/proto"
  16. "k8s.io/kubernetes/pkg/kubectl/apply"
  17. )
  18. // mapElement builds a new mapElement from a mapItem
  19. func (v ElementBuildingVisitor) mapElement(meta apply.FieldMetaImpl, item *mapItem) (*apply.MapElement, error) {
  20. // Function to return schema type of the map values
  21. var fn schemaFn = func(string) proto.Schema {
  22. // All map values share the same schema
  23. if item.Map != nil && item.Map.SubType != nil {
  24. return item.Map.SubType
  25. }
  26. return nil
  27. }
  28. // Collect same fields from multiple maps into a map of elements
  29. values, err := v.createMapValues(fn, meta, item.MapElementData)
  30. if err != nil {
  31. return nil, err
  32. }
  33. // Return the result
  34. return &apply.MapElement{
  35. FieldMetaImpl: meta,
  36. MapElementData: item.MapElementData,
  37. Values: values,
  38. }, nil
  39. }
  40. // schemaFn returns the schema for a field or map value based on its name or key
  41. type schemaFn func(key string) proto.Schema
  42. // createMapValues combines the recorded, local and remote values from
  43. // data into a map of elements.
  44. func (v ElementBuildingVisitor) createMapValues(
  45. schemaFn schemaFn,
  46. meta apply.FieldMetaImpl,
  47. data apply.MapElementData) (map[string]apply.Element, error) {
  48. // Collate each key in the map
  49. values := map[string]apply.Element{}
  50. for _, key := range keysUnion(data.GetRecordedMap(), data.GetLocalMap(), data.GetRemoteMap()) {
  51. combined := apply.RawElementData{}
  52. if recorded, recordedSet := nilSafeLookup(key, data.GetRecordedMap()); recordedSet {
  53. combined.SetRecorded(recorded)
  54. }
  55. if local, localSet := nilSafeLookup(key, data.GetLocalMap()); localSet {
  56. combined.SetLocal(local)
  57. }
  58. if remote, remoteSet := nilSafeLookup(key, data.GetRemoteMap()); remoteSet {
  59. combined.SetRemote(remote)
  60. }
  61. // Create an item for the field
  62. field, err := v.getItem(schemaFn(key), key, combined)
  63. if err != nil {
  64. return nil, err
  65. }
  66. // Build the element for this field
  67. element, err := field.CreateElement(v)
  68. if err != nil {
  69. return nil, err
  70. }
  71. // Add the field element to the map
  72. values[key] = element
  73. }
  74. return values, nil
  75. }