123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- /*
- Copyright 2018 The Kubernetes Authors.
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
- package util
- import (
- "sync"
- "github.com/spf13/pflag"
- "k8s.io/apimachinery/pkg/api/meta"
- "k8s.io/apimachinery/pkg/runtime/schema"
- "k8s.io/client-go/discovery"
- "k8s.io/client-go/rest"
- "k8s.io/client-go/tools/clientcmd"
- "k8s.io/kubernetes/pkg/kubectl/scheme"
- "k8s.io/cli-runtime/pkg/genericclioptions"
- "k8s.io/kubernetes/pkg/kubectl/version"
- )
- const (
- flagMatchBinaryVersion = "match-server-version"
- )
- // MatchVersionFlags is for setting the "match server version" function.
- type MatchVersionFlags struct {
- Delegate genericclioptions.RESTClientGetter
- RequireMatchedServerVersion bool
- checkServerVersion sync.Once
- matchesServerVersionErr error
- }
- var _ genericclioptions.RESTClientGetter = &MatchVersionFlags{}
- func (f *MatchVersionFlags) checkMatchingServerVersion() error {
- f.checkServerVersion.Do(func() {
- if !f.RequireMatchedServerVersion {
- return
- }
- discoveryClient, err := f.Delegate.ToDiscoveryClient()
- if err != nil {
- f.matchesServerVersionErr = err
- return
- }
- f.matchesServerVersionErr = discovery.MatchesServerVersion(version.Get(), discoveryClient)
- })
- return f.matchesServerVersionErr
- }
- // ToRESTConfig implements RESTClientGetter.
- // Returns a REST client configuration based on a provided path
- // to a .kubeconfig file, loading rules, and config flag overrides.
- // Expects the AddFlags method to have been called.
- func (f *MatchVersionFlags) ToRESTConfig() (*rest.Config, error) {
- if err := f.checkMatchingServerVersion(); err != nil {
- return nil, err
- }
- clientConfig, err := f.Delegate.ToRESTConfig()
- if err != nil {
- return nil, err
- }
- // TODO we should not have to do this. It smacks of something going wrong.
- setKubernetesDefaults(clientConfig)
- return clientConfig, nil
- }
- func (f *MatchVersionFlags) ToRawKubeConfigLoader() clientcmd.ClientConfig {
- return f.Delegate.ToRawKubeConfigLoader()
- }
- func (f *MatchVersionFlags) ToDiscoveryClient() (discovery.CachedDiscoveryInterface, error) {
- if err := f.checkMatchingServerVersion(); err != nil {
- return nil, err
- }
- return f.Delegate.ToDiscoveryClient()
- }
- // ToRESTMapper returns a mapper.
- func (f *MatchVersionFlags) ToRESTMapper() (meta.RESTMapper, error) {
- if err := f.checkMatchingServerVersion(); err != nil {
- return nil, err
- }
- return f.Delegate.ToRESTMapper()
- }
- func (f *MatchVersionFlags) AddFlags(flags *pflag.FlagSet) {
- flags.BoolVar(&f.RequireMatchedServerVersion, flagMatchBinaryVersion, f.RequireMatchedServerVersion, "Require server version to match client version")
- }
- func NewMatchVersionFlags(delegate genericclioptions.RESTClientGetter) *MatchVersionFlags {
- return &MatchVersionFlags{
- Delegate: delegate,
- }
- }
- // setKubernetesDefaults sets default values on the provided client config for accessing the
- // Kubernetes API or returns an error if any of the defaults are impossible or invalid.
- // TODO this isn't what we want. Each clientset should be setting defaults as it sees fit.
- func setKubernetesDefaults(config *rest.Config) error {
- // TODO remove this hack. This is allowing the GetOptions to be serialized.
- config.GroupVersion = &schema.GroupVersion{Group: "", Version: "v1"}
- if config.APIPath == "" {
- config.APIPath = "/api"
- }
- if config.NegotiatedSerializer == nil {
- // This codec factory ensures the resources are not converted. Therefore, resources
- // will not be round-tripped through internal versions. Defaulting does not happen
- // on the client.
- config.NegotiatedSerializer = scheme.Codecs.WithoutConversion()
- }
- return rest.SetKubernetesDefaults(config)
- }
|