/staging/src/k8s.io/apiserver/pkg/server/resourceconfig/helpers.go

https://gitlab.com/unofficial-mirrors/kubernetes · Go · 164 lines · 115 code · 16 blank · 33 comment · 35 complexity · d389130d6d4f13b7d501ae9d95cc0d56 MD5 · raw file

  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 resourceconfig
  14. import (
  15. "fmt"
  16. "strconv"
  17. "strings"
  18. "k8s.io/apimachinery/pkg/runtime"
  19. "k8s.io/apimachinery/pkg/runtime/schema"
  20. serverstore "k8s.io/apiserver/pkg/server/storage"
  21. utilflag "k8s.io/apiserver/pkg/util/flag"
  22. )
  23. // GroupVersionRegistry provides access to registered group versions.
  24. type GroupVersionRegistry interface {
  25. // IsGroupRegistered returns true if given group is registered.
  26. IsGroupRegistered(group string) bool
  27. // IsVersionRegistered returns true if given version is registered.
  28. IsVersionRegistered(v schema.GroupVersion) bool
  29. // PrioritizedVersionsAllGroups returns all registered group versions.
  30. PrioritizedVersionsAllGroups() []schema.GroupVersion
  31. }
  32. // MergeResourceEncodingConfigs merges the given defaultResourceConfig with specific GroupVersionResource overrides.
  33. func MergeResourceEncodingConfigs(
  34. defaultResourceEncoding *serverstore.DefaultResourceEncodingConfig,
  35. resourceEncodingOverrides []schema.GroupVersionResource,
  36. ) *serverstore.DefaultResourceEncodingConfig {
  37. resourceEncodingConfig := defaultResourceEncoding
  38. for _, gvr := range resourceEncodingOverrides {
  39. resourceEncodingConfig.SetResourceEncoding(gvr.GroupResource(), gvr.GroupVersion(),
  40. schema.GroupVersion{Group: gvr.Group, Version: runtime.APIVersionInternal})
  41. }
  42. return resourceEncodingConfig
  43. }
  44. // MergeGroupEncodingConfigs merges the given defaultResourceConfig with specific GroupVersion overrides.
  45. func MergeGroupEncodingConfigs(
  46. defaultResourceEncoding *serverstore.DefaultResourceEncodingConfig,
  47. storageEncodingOverrides map[string]schema.GroupVersion,
  48. ) *serverstore.DefaultResourceEncodingConfig {
  49. resourceEncodingConfig := defaultResourceEncoding
  50. for group, storageEncodingVersion := range storageEncodingOverrides {
  51. resourceEncodingConfig.SetVersionEncoding(group, storageEncodingVersion, schema.GroupVersion{Group: group, Version: runtime.APIVersionInternal})
  52. }
  53. return resourceEncodingConfig
  54. }
  55. // MergeAPIResourceConfigs merges the given defaultAPIResourceConfig with the given resourceConfigOverrides.
  56. // Exclude the groups not registered in registry, and check if version is
  57. // not registered in group, then it will fail.
  58. func MergeAPIResourceConfigs(
  59. defaultAPIResourceConfig *serverstore.ResourceConfig,
  60. resourceConfigOverrides utilflag.ConfigurationMap,
  61. registry GroupVersionRegistry,
  62. ) (*serverstore.ResourceConfig, error) {
  63. resourceConfig := defaultAPIResourceConfig
  64. overrides := resourceConfigOverrides
  65. // "api/all=false" allows users to selectively enable specific api versions.
  66. allAPIFlagValue, ok := overrides["api/all"]
  67. if ok {
  68. if allAPIFlagValue == "false" {
  69. // Disable all group versions.
  70. resourceConfig.DisableAll()
  71. } else if allAPIFlagValue == "true" {
  72. resourceConfig.EnableAll()
  73. }
  74. }
  75. // "<resourceSpecifier>={true|false} allows users to enable/disable API.
  76. // This takes preference over api/all, if specified.
  77. // Iterate through all group/version overrides specified in runtimeConfig.
  78. for key := range overrides {
  79. // Have already handled them above. Can skip them here.
  80. if key == "api/all" {
  81. continue
  82. }
  83. tokens := strings.Split(key, "/")
  84. if len(tokens) != 2 {
  85. continue
  86. }
  87. groupVersionString := tokens[0] + "/" + tokens[1]
  88. groupVersion, err := schema.ParseGroupVersion(groupVersionString)
  89. if err != nil {
  90. return nil, fmt.Errorf("invalid key %s", key)
  91. }
  92. // Exclude group not registered into the registry.
  93. if !registry.IsGroupRegistered(groupVersion.Group) {
  94. continue
  95. }
  96. // Verify that the groupVersion is registered into registry.
  97. if !registry.IsVersionRegistered(groupVersion) {
  98. return nil, fmt.Errorf("group version %s that has not been registered", groupVersion.String())
  99. }
  100. enabled, err := getRuntimeConfigValue(overrides, key, false)
  101. if err != nil {
  102. return nil, err
  103. }
  104. if enabled {
  105. resourceConfig.EnableVersions(groupVersion)
  106. } else {
  107. resourceConfig.DisableVersions(groupVersion)
  108. }
  109. }
  110. return resourceConfig, nil
  111. }
  112. func getRuntimeConfigValue(overrides utilflag.ConfigurationMap, apiKey string, defaultValue bool) (bool, error) {
  113. flagValue, ok := overrides[apiKey]
  114. if ok {
  115. if flagValue == "" {
  116. return true, nil
  117. }
  118. boolValue, err := strconv.ParseBool(flagValue)
  119. if err != nil {
  120. return false, fmt.Errorf("invalid value of %s: %s, err: %v", apiKey, flagValue, err)
  121. }
  122. return boolValue, nil
  123. }
  124. return defaultValue, nil
  125. }
  126. // ParseGroups takes in resourceConfig and returns parsed groups.
  127. func ParseGroups(resourceConfig utilflag.ConfigurationMap) ([]string, error) {
  128. groups := []string{}
  129. for key := range resourceConfig {
  130. if key == "api/all" {
  131. continue
  132. }
  133. tokens := strings.Split(key, "/")
  134. if len(tokens) != 2 && len(tokens) != 3 {
  135. return groups, fmt.Errorf("runtime-config invalid key %s", key)
  136. }
  137. groupVersionString := tokens[0] + "/" + tokens[1]
  138. groupVersion, err := schema.ParseGroupVersion(groupVersionString)
  139. if err != nil {
  140. return nil, fmt.Errorf("runtime-config invalid key %s", key)
  141. }
  142. groups = append(groups, groupVersion.Group)
  143. }
  144. return groups, nil
  145. }