registrations.go 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  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 componentconfigs
  14. import (
  15. "k8s.io/apimachinery/pkg/runtime"
  16. "k8s.io/apimachinery/pkg/runtime/schema"
  17. "k8s.io/apimachinery/pkg/util/validation/field"
  18. "k8s.io/apimachinery/pkg/util/version"
  19. clientset "k8s.io/client-go/kubernetes"
  20. kubeproxyconfigv1alpha1 "k8s.io/kube-proxy/config/v1alpha1"
  21. kubeletconfigv1beta1 "k8s.io/kubelet/config/v1beta1"
  22. kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
  23. kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
  24. kubeletconfig "k8s.io/kubernetes/pkg/kubelet/apis/config"
  25. kubeletconfigv1beta1scheme "k8s.io/kubernetes/pkg/kubelet/apis/config/v1beta1"
  26. kubeproxyconfig "k8s.io/kubernetes/pkg/proxy/apis/config"
  27. kubeproxyconfigv1alpha1scheme "k8s.io/kubernetes/pkg/proxy/apis/config/v1alpha1"
  28. )
  29. // AddToSchemeFunc is a function that adds known types and API GroupVersions to a scheme
  30. type AddToSchemeFunc func(*runtime.Scheme) error
  31. // Registration is an object for registering a Kubernetes ComponentConfig type to be recognized and handled by kubeadm
  32. type Registration struct {
  33. // MarshalGroupVersion is the preferred external API version to use when marshalling the ComponentConfig
  34. MarshalGroupVersion schema.GroupVersion
  35. // AddToSchemeFuncs are a set of functions that register APIs to the scheme
  36. AddToSchemeFuncs []AddToSchemeFunc
  37. // DefaulterFunc is a function that based on the internal kubeadm configuration defaults the ComponentConfig struct
  38. DefaulterFunc func(*kubeadmapi.ClusterConfiguration)
  39. // ValidateFunc is a function that should validate the ComponentConfig type embedded in the internal kubeadm config struct
  40. ValidateFunc func(*kubeadmapi.ClusterConfiguration, *field.Path) field.ErrorList
  41. // EmptyValue holds a pointer to an empty struct of the internal ComponentConfig type
  42. EmptyValue runtime.Object
  43. // GetFromInternalConfig returns the pointer to the ComponentConfig API object from the internal kubeadm config struct
  44. GetFromInternalConfig func(*kubeadmapi.ClusterConfiguration) (runtime.Object, bool)
  45. // SetToInternalConfig sets the pointer to a ComponentConfig API object embedded in the internal kubeadm config struct
  46. SetToInternalConfig func(runtime.Object, *kubeadmapi.ClusterConfiguration) bool
  47. // GetFromConfigMap returns the pointer to the ComponentConfig API object read from the config map stored in the cluster
  48. GetFromConfigMap func(clientset.Interface, *version.Version) (runtime.Object, error)
  49. }
  50. // Marshal marshals obj to bytes for the current Registration
  51. func (r Registration) Marshal(obj runtime.Object) ([]byte, error) {
  52. return kubeadmutil.MarshalToYamlForCodecs(obj, r.MarshalGroupVersion, Codecs)
  53. }
  54. // Unmarshal unmarshals the bytes to a runtime.Object using the Codecs registered in this Scheme
  55. func (r Registration) Unmarshal(fileContent []byte) (runtime.Object, error) {
  56. // Do a deepcopy of the empty value so we don't mutate it, which could lead to strange errors
  57. obj := r.EmptyValue.DeepCopyObject()
  58. // Decode the file content into obj which is a pointer to an empty struct of the internal ComponentConfig
  59. if err := unmarshalObject(obj, fileContent); err != nil {
  60. return nil, err
  61. }
  62. return obj, nil
  63. }
  64. func unmarshalObject(obj runtime.Object, fileContent []byte) error {
  65. // Decode the file content using the componentconfig Codecs that knows about all APIs
  66. return runtime.DecodeInto(Codecs.UniversalDecoder(), fileContent, obj)
  67. }
  68. const (
  69. // KubeletConfigurationKind is the kind for the kubelet ComponentConfig
  70. KubeletConfigurationKind RegistrationKind = "KubeletConfiguration"
  71. // KubeProxyConfigurationKind is the kind for the kubelet ComponentConfig
  72. KubeProxyConfigurationKind RegistrationKind = "KubeProxyConfiguration"
  73. )
  74. // RegistrationKind is a string type to ensure not any string can be a key in the Registrations map
  75. type RegistrationKind string
  76. // Registrations holds a set of ComponentConfig Registration objects, where the map key is the kind
  77. type Registrations map[RegistrationKind]Registration
  78. // Known contains the known ComponentConfig registrations to kubeadm
  79. var Known Registrations = map[RegistrationKind]Registration{
  80. KubeProxyConfigurationKind: {
  81. // TODO: When a beta version of the kube-proxy ComponentConfig API is available, start using it
  82. MarshalGroupVersion: kubeproxyconfigv1alpha1.SchemeGroupVersion,
  83. // AddToSchemeFuncs must use v1alpha1scheme defined in k8s.io/kubernetes, because the schema defined in k8s.io/kube-proxy doesn't have defaulting functions
  84. AddToSchemeFuncs: []AddToSchemeFunc{kubeproxyconfig.AddToScheme, kubeproxyconfigv1alpha1scheme.AddToScheme},
  85. DefaulterFunc: DefaultKubeProxyConfiguration,
  86. ValidateFunc: ValidateKubeProxyConfiguration,
  87. EmptyValue: &kubeproxyconfig.KubeProxyConfiguration{},
  88. GetFromInternalConfig: func(cfg *kubeadmapi.ClusterConfiguration) (runtime.Object, bool) {
  89. return cfg.ComponentConfigs.KubeProxy, cfg.ComponentConfigs.KubeProxy != nil
  90. },
  91. SetToInternalConfig: func(obj runtime.Object, cfg *kubeadmapi.ClusterConfiguration) bool {
  92. kubeproxyConfig, ok := obj.(*kubeproxyconfig.KubeProxyConfiguration)
  93. if ok {
  94. cfg.ComponentConfigs.KubeProxy = kubeproxyConfig
  95. }
  96. return ok
  97. },
  98. GetFromConfigMap: GetFromKubeProxyConfigMap,
  99. },
  100. KubeletConfigurationKind: {
  101. MarshalGroupVersion: kubeletconfigv1beta1.SchemeGroupVersion,
  102. // PAddToSchemeFuncs must use v1alpha1scheme defined in k8s.io/kubernetes, because the schema defined in k8s.io/kubelet doesn't have defaulting functions
  103. AddToSchemeFuncs: []AddToSchemeFunc{kubeletconfig.AddToScheme, kubeletconfigv1beta1scheme.AddToScheme},
  104. DefaulterFunc: DefaultKubeletConfiguration,
  105. ValidateFunc: ValidateKubeletConfiguration,
  106. EmptyValue: &kubeletconfig.KubeletConfiguration{},
  107. GetFromInternalConfig: func(cfg *kubeadmapi.ClusterConfiguration) (runtime.Object, bool) {
  108. return cfg.ComponentConfigs.Kubelet, cfg.ComponentConfigs.Kubelet != nil
  109. },
  110. SetToInternalConfig: func(obj runtime.Object, cfg *kubeadmapi.ClusterConfiguration) bool {
  111. kubeletConfig, ok := obj.(*kubeletconfig.KubeletConfiguration)
  112. if ok {
  113. cfg.ComponentConfigs.Kubelet = kubeletConfig
  114. }
  115. return ok
  116. },
  117. GetFromConfigMap: GetFromKubeletConfigMap,
  118. },
  119. }
  120. // AddToScheme adds all the known ComponentConfig API types referenced in the Registrations object to the scheme
  121. func (rs *Registrations) AddToScheme(scheme *runtime.Scheme) error {
  122. for _, registration := range *rs {
  123. for _, addToSchemeFunc := range registration.AddToSchemeFuncs {
  124. if err := addToSchemeFunc(scheme); err != nil {
  125. return err
  126. }
  127. }
  128. }
  129. return nil
  130. }
  131. // Default applies to the ComponentConfig defaults to the internal kubeadm API type
  132. func (rs *Registrations) Default(internalcfg *kubeadmapi.ClusterConfiguration) {
  133. for _, registration := range *rs {
  134. registration.DefaulterFunc(internalcfg)
  135. }
  136. }
  137. // Validate validates the ComponentConfig parts of the internal kubeadm API type
  138. func (rs *Registrations) Validate(internalcfg *kubeadmapi.ClusterConfiguration) field.ErrorList {
  139. allErrs := field.ErrorList{}
  140. for kind, registration := range *rs {
  141. allErrs = append(allErrs, registration.ValidateFunc(internalcfg, field.NewPath(string(kind)))...)
  142. }
  143. return allErrs
  144. }