Update godeps
This commit is contained in:
parent
1c8773fc98
commit
1bc383f9c5
1723 changed files with 287976 additions and 411028 deletions
111
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/BUILD
generated
vendored
Normal file
111
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/BUILD
generated
vendored
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_binary",
|
||||
"go_library",
|
||||
"go_test",
|
||||
"cgo_library",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"cached_discovery.go",
|
||||
"clientcache.go",
|
||||
"factory.go",
|
||||
"helpers.go",
|
||||
"printing.go",
|
||||
"shortcut_restmapper.go",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//federation/apis/federation:go_default_library",
|
||||
"//federation/client/clientset_generated/federation_internalclientset:go_default_library",
|
||||
"//pkg/api:go_default_library",
|
||||
"//pkg/api/errors:go_default_library",
|
||||
"//pkg/api/meta:go_default_library",
|
||||
"//pkg/api/service:go_default_library",
|
||||
"//pkg/api/unversioned:go_default_library",
|
||||
"//pkg/api/validation:go_default_library",
|
||||
"//pkg/apimachinery/registered:go_default_library",
|
||||
"//pkg/apis/apps:go_default_library",
|
||||
"//pkg/apis/batch:go_default_library",
|
||||
"//pkg/apis/extensions:go_default_library",
|
||||
"//pkg/client/clientset_generated/internalclientset:go_default_library",
|
||||
"//pkg/client/clientset_generated/internalclientset/typed/core/internalversion:go_default_library",
|
||||
"//pkg/client/restclient:go_default_library",
|
||||
"//pkg/client/typed/discovery:go_default_library",
|
||||
"//pkg/client/typed/dynamic:go_default_library",
|
||||
"//pkg/client/unversioned:go_default_library",
|
||||
"//pkg/client/unversioned/clientcmd:go_default_library",
|
||||
"//pkg/controller:go_default_library",
|
||||
"//pkg/kubectl:go_default_library",
|
||||
"//pkg/kubectl/resource:go_default_library",
|
||||
"//pkg/labels:go_default_library",
|
||||
"//pkg/registry/extensions/thirdpartyresourcedata:go_default_library",
|
||||
"//pkg/runtime:go_default_library",
|
||||
"//pkg/runtime/serializer/json:go_default_library",
|
||||
"//pkg/util/errors:go_default_library",
|
||||
"//pkg/util/exec:go_default_library",
|
||||
"//pkg/util/flag:go_default_library",
|
||||
"//pkg/util/homedir:go_default_library",
|
||||
"//pkg/util/sets:go_default_library",
|
||||
"//pkg/util/strategicpatch:go_default_library",
|
||||
"//pkg/version:go_default_library",
|
||||
"//pkg/watch:go_default_library",
|
||||
"//vendor:github.com/emicklei/go-restful/swagger",
|
||||
"//vendor:github.com/evanphx/json-patch",
|
||||
"//vendor:github.com/golang/glog",
|
||||
"//vendor:github.com/spf13/cobra",
|
||||
"//vendor:github.com/spf13/pflag",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"cached_discovery_test.go",
|
||||
"factory_test.go",
|
||||
"helpers_test.go",
|
||||
"shortcut_restmapper_test.go",
|
||||
],
|
||||
data = [
|
||||
"//api/swagger-spec",
|
||||
],
|
||||
library = "go_default_library",
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//pkg/api:go_default_library",
|
||||
"//pkg/api/errors:go_default_library",
|
||||
"//pkg/api/meta:go_default_library",
|
||||
"//pkg/api/testapi:go_default_library",
|
||||
"//pkg/api/testing:go_default_library",
|
||||
"//pkg/api/unversioned:go_default_library",
|
||||
"//pkg/api/v1:go_default_library",
|
||||
"//pkg/api/validation:go_default_library",
|
||||
"//pkg/apimachinery/registered:go_default_library",
|
||||
"//pkg/apis/extensions:go_default_library",
|
||||
"//pkg/client/clientset_generated/internalclientset/fake:go_default_library",
|
||||
"//pkg/client/restclient:go_default_library",
|
||||
"//pkg/client/restclient/fake:go_default_library",
|
||||
"//pkg/client/testing/core:go_default_library",
|
||||
"//pkg/client/typed/discovery:go_default_library",
|
||||
"//pkg/client/unversioned/clientcmd:go_default_library",
|
||||
"//pkg/client/unversioned/clientcmd/api:go_default_library",
|
||||
"//pkg/controller:go_default_library",
|
||||
"//pkg/kubectl:go_default_library",
|
||||
"//pkg/kubectl/resource:go_default_library",
|
||||
"//pkg/labels:go_default_library",
|
||||
"//pkg/runtime:go_default_library",
|
||||
"//pkg/util/exec:go_default_library",
|
||||
"//pkg/util/flag:go_default_library",
|
||||
"//pkg/util/validation/field:go_default_library",
|
||||
"//pkg/version:go_default_library",
|
||||
"//pkg/watch:go_default_library",
|
||||
"//vendor:github.com/emicklei/go-restful/swagger",
|
||||
"//vendor:github.com/stretchr/testify/assert",
|
||||
],
|
||||
)
|
||||
252
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/cached_discovery.go
generated
vendored
Normal file
252
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/cached_discovery.go
generated
vendored
Normal file
|
|
@ -0,0 +1,252 @@
|
|||
/*
|
||||
Copyright 2016 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 (
|
||||
"errors"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/emicklei/go-restful/swagger"
|
||||
"github.com/golang/glog"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
"k8s.io/kubernetes/pkg/client/restclient"
|
||||
"k8s.io/kubernetes/pkg/client/typed/discovery"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
"k8s.io/kubernetes/pkg/version"
|
||||
)
|
||||
|
||||
// CachedDiscoveryClient implements the functions that discovery server-supported API groups,
|
||||
// versions and resources.
|
||||
type CachedDiscoveryClient struct {
|
||||
delegate discovery.DiscoveryInterface
|
||||
|
||||
// cacheDirectory is the directory where discovery docs are held. It must be unique per host:port combination to work well.
|
||||
cacheDirectory string
|
||||
|
||||
// ttl is how long the cache should be considered valid
|
||||
ttl time.Duration
|
||||
|
||||
// mutex protects the variables below
|
||||
mutex sync.Mutex
|
||||
|
||||
// ourFiles are all filenames of cache files created by this process
|
||||
ourFiles map[string]struct{}
|
||||
// invalidated is true if all cache files should be ignored that are not ours (e.g. after Invalidate() was called)
|
||||
invalidated bool
|
||||
// fresh is true if all used cache files were ours
|
||||
fresh bool
|
||||
}
|
||||
|
||||
var _ discovery.CachedDiscoveryInterface = &CachedDiscoveryClient{}
|
||||
|
||||
// ServerResourcesForGroupVersion returns the supported resources for a group and version.
|
||||
func (d *CachedDiscoveryClient) ServerResourcesForGroupVersion(groupVersion string) (*unversioned.APIResourceList, error) {
|
||||
filename := filepath.Join(d.cacheDirectory, groupVersion, "serverresources.json")
|
||||
cachedBytes, err := d.getCachedFile(filename)
|
||||
// don't fail on errors, we either don't have a file or won't be able to run the cached check. Either way we can fallback.
|
||||
if err == nil {
|
||||
cachedResources := &unversioned.APIResourceList{}
|
||||
if err := runtime.DecodeInto(api.Codecs.UniversalDecoder(), cachedBytes, cachedResources); err == nil {
|
||||
glog.V(6).Infof("returning cached discovery info from %v", filename)
|
||||
return cachedResources, nil
|
||||
}
|
||||
}
|
||||
|
||||
liveResources, err := d.delegate.ServerResourcesForGroupVersion(groupVersion)
|
||||
if err != nil {
|
||||
return liveResources, err
|
||||
}
|
||||
|
||||
if err := d.writeCachedFile(filename, liveResources); err != nil {
|
||||
glog.V(3).Infof("failed to write cache to %v due to %v", filename, err)
|
||||
}
|
||||
|
||||
return liveResources, nil
|
||||
}
|
||||
|
||||
// ServerResources returns the supported resources for all groups and versions.
|
||||
func (d *CachedDiscoveryClient) ServerResources() (map[string]*unversioned.APIResourceList, error) {
|
||||
apiGroups, err := d.ServerGroups()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
groupVersions := unversioned.ExtractGroupVersions(apiGroups)
|
||||
result := map[string]*unversioned.APIResourceList{}
|
||||
for _, groupVersion := range groupVersions {
|
||||
resources, err := d.ServerResourcesForGroupVersion(groupVersion)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result[groupVersion] = resources
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (d *CachedDiscoveryClient) ServerGroups() (*unversioned.APIGroupList, error) {
|
||||
filename := filepath.Join(d.cacheDirectory, "servergroups.json")
|
||||
cachedBytes, err := d.getCachedFile(filename)
|
||||
// don't fail on errors, we either don't have a file or won't be able to run the cached check. Either way we can fallback.
|
||||
if err == nil {
|
||||
cachedGroups := &unversioned.APIGroupList{}
|
||||
if err := runtime.DecodeInto(api.Codecs.UniversalDecoder(), cachedBytes, cachedGroups); err == nil {
|
||||
glog.V(6).Infof("returning cached discovery info from %v", filename)
|
||||
return cachedGroups, nil
|
||||
}
|
||||
}
|
||||
|
||||
liveGroups, err := d.delegate.ServerGroups()
|
||||
if err != nil {
|
||||
return liveGroups, err
|
||||
}
|
||||
|
||||
if err := d.writeCachedFile(filename, liveGroups); err != nil {
|
||||
glog.V(3).Infof("failed to write cache to %v due to %v", filename, err)
|
||||
}
|
||||
|
||||
return liveGroups, nil
|
||||
}
|
||||
|
||||
func (d *CachedDiscoveryClient) getCachedFile(filename string) ([]byte, error) {
|
||||
// after invalidation ignore cache files not created by this process
|
||||
d.mutex.Lock()
|
||||
_, ourFile := d.ourFiles[filename]
|
||||
if d.invalidated && !ourFile {
|
||||
d.mutex.Unlock()
|
||||
return nil, errors.New("cache invalidated")
|
||||
}
|
||||
d.mutex.Unlock()
|
||||
|
||||
file, err := os.Open(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fileInfo, err := file.Stat()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if time.Now().After(fileInfo.ModTime().Add(d.ttl)) {
|
||||
return nil, errors.New("cache expired")
|
||||
}
|
||||
|
||||
// the cache is present and its valid. Try to read and use it.
|
||||
cachedBytes, err := ioutil.ReadAll(file)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
d.mutex.Lock()
|
||||
defer d.mutex.Unlock()
|
||||
d.fresh = d.fresh && ourFile
|
||||
|
||||
return cachedBytes, nil
|
||||
}
|
||||
|
||||
func (d *CachedDiscoveryClient) writeCachedFile(filename string, obj runtime.Object) error {
|
||||
if err := os.MkdirAll(filepath.Dir(filename), 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
bytes, err := runtime.Encode(api.Codecs.LegacyCodec(), obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
f, err := ioutil.TempFile(filepath.Dir(filename), filepath.Base(filename)+".")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer os.Remove(f.Name())
|
||||
_, err = f.Write(bytes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = f.Chmod(0755)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
name := f.Name()
|
||||
err = f.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// atomic rename
|
||||
d.mutex.Lock()
|
||||
defer d.mutex.Unlock()
|
||||
err = os.Rename(name, filename)
|
||||
if err == nil {
|
||||
d.ourFiles[filename] = struct{}{}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (d *CachedDiscoveryClient) RESTClient() restclient.Interface {
|
||||
return d.delegate.RESTClient()
|
||||
}
|
||||
|
||||
func (d *CachedDiscoveryClient) ServerPreferredResources() ([]unversioned.GroupVersionResource, error) {
|
||||
return d.delegate.ServerPreferredResources()
|
||||
}
|
||||
|
||||
func (d *CachedDiscoveryClient) ServerPreferredNamespacedResources() ([]unversioned.GroupVersionResource, error) {
|
||||
return d.delegate.ServerPreferredNamespacedResources()
|
||||
}
|
||||
|
||||
func (d *CachedDiscoveryClient) ServerVersion() (*version.Info, error) {
|
||||
return d.delegate.ServerVersion()
|
||||
}
|
||||
|
||||
func (d *CachedDiscoveryClient) SwaggerSchema(version unversioned.GroupVersion) (*swagger.ApiDeclaration, error) {
|
||||
return d.delegate.SwaggerSchema(version)
|
||||
}
|
||||
|
||||
func (d *CachedDiscoveryClient) Fresh() bool {
|
||||
d.mutex.Lock()
|
||||
defer d.mutex.Unlock()
|
||||
|
||||
return d.fresh
|
||||
}
|
||||
|
||||
func (d *CachedDiscoveryClient) Invalidate() {
|
||||
d.mutex.Lock()
|
||||
defer d.mutex.Unlock()
|
||||
|
||||
d.ourFiles = map[string]struct{}{}
|
||||
d.fresh = true
|
||||
d.invalidated = true
|
||||
}
|
||||
|
||||
// NewCachedDiscoveryClient creates a new DiscoveryClient. cacheDirectory is the directory where discovery docs are held. It must be unique per host:port combination to work well.
|
||||
func NewCachedDiscoveryClient(delegate discovery.DiscoveryInterface, cacheDirectory string, ttl time.Duration) *CachedDiscoveryClient {
|
||||
return &CachedDiscoveryClient{
|
||||
delegate: delegate,
|
||||
cacheDirectory: cacheDirectory,
|
||||
ttl: ttl,
|
||||
ourFiles: map[string]struct{}{},
|
||||
fresh: true,
|
||||
}
|
||||
}
|
||||
123
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/clientcache.go
generated
vendored
123
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/clientcache.go
generated
vendored
|
|
@ -17,17 +17,21 @@ limitations under the License.
|
|||
package util
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
fed_clientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_internalclientset"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
"k8s.io/kubernetes/pkg/apimachinery/registered"
|
||||
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
|
||||
"k8s.io/kubernetes/pkg/client/restclient"
|
||||
client "k8s.io/kubernetes/pkg/client/unversioned"
|
||||
"k8s.io/kubernetes/pkg/client/typed/discovery"
|
||||
oldclient "k8s.io/kubernetes/pkg/client/unversioned"
|
||||
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
|
||||
)
|
||||
|
||||
func NewClientCache(loader clientcmd.ClientConfig) *ClientCache {
|
||||
return &ClientCache{
|
||||
clients: make(map[unversioned.GroupVersion]*client.Client),
|
||||
clientsets: make(map[unversioned.GroupVersion]*internalclientset.Clientset),
|
||||
configs: make(map[unversioned.GroupVersion]*restclient.Config),
|
||||
fedClientSets: make(map[unversioned.GroupVersion]fed_clientset.Interface),
|
||||
loader: loader,
|
||||
|
|
@ -38,53 +42,78 @@ func NewClientCache(loader clientcmd.ClientConfig) *ClientCache {
|
|||
// is invoked only once
|
||||
type ClientCache struct {
|
||||
loader clientcmd.ClientConfig
|
||||
clients map[unversioned.GroupVersion]*client.Client
|
||||
clientsets map[unversioned.GroupVersion]*internalclientset.Clientset
|
||||
fedClientSets map[unversioned.GroupVersion]fed_clientset.Interface
|
||||
configs map[unversioned.GroupVersion]*restclient.Config
|
||||
defaultConfig *restclient.Config
|
||||
defaultClient *client.Client
|
||||
matchVersion bool
|
||||
|
||||
matchVersion bool
|
||||
|
||||
defaultConfigLock sync.Mutex
|
||||
defaultConfig *restclient.Config
|
||||
discoveryClient discovery.DiscoveryInterface
|
||||
}
|
||||
|
||||
// also looks up the discovery client. We can't do this during init because the flags won't have been set
|
||||
// because this is constructed pre-command execution before the command tree is even set up
|
||||
func (c *ClientCache) getDefaultConfig() (restclient.Config, discovery.DiscoveryInterface, error) {
|
||||
c.defaultConfigLock.Lock()
|
||||
defer c.defaultConfigLock.Unlock()
|
||||
|
||||
if c.defaultConfig != nil && c.discoveryClient != nil {
|
||||
return *c.defaultConfig, c.discoveryClient, nil
|
||||
}
|
||||
|
||||
config, err := c.loader.ClientConfig()
|
||||
if err != nil {
|
||||
return restclient.Config{}, nil, err
|
||||
}
|
||||
discoveryClient, err := discovery.NewDiscoveryClientForConfig(config)
|
||||
if err != nil {
|
||||
return restclient.Config{}, nil, err
|
||||
}
|
||||
if c.matchVersion {
|
||||
if err := discovery.MatchesServerVersion(discoveryClient); err != nil {
|
||||
return restclient.Config{}, nil, err
|
||||
}
|
||||
}
|
||||
|
||||
c.defaultConfig = config
|
||||
c.discoveryClient = discoveryClient
|
||||
return *c.defaultConfig, c.discoveryClient, nil
|
||||
}
|
||||
|
||||
// ClientConfigForVersion returns the correct config for a server
|
||||
func (c *ClientCache) ClientConfigForVersion(version *unversioned.GroupVersion) (*restclient.Config, error) {
|
||||
if c.defaultConfig == nil {
|
||||
config, err := c.loader.ClientConfig()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
c.defaultConfig = config
|
||||
if c.matchVersion {
|
||||
if err := client.MatchesServerVersion(c.defaultClient, config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
func (c *ClientCache) ClientConfigForVersion(requiredVersion *unversioned.GroupVersion) (*restclient.Config, error) {
|
||||
// TODO: have a better config copy method
|
||||
config, discoveryClient, err := c.getDefaultConfig()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if version != nil {
|
||||
if config, ok := c.configs[*version]; ok {
|
||||
if requiredVersion == nil && config.GroupVersion != nil {
|
||||
// if someone has set the values via flags, our config will have the groupVersion set
|
||||
// that means it is required.
|
||||
requiredVersion = config.GroupVersion
|
||||
}
|
||||
|
||||
// required version may still be nil, since config.GroupVersion may have been nil. Do the check
|
||||
// before looking up from the cache
|
||||
if requiredVersion != nil {
|
||||
if config, ok := c.configs[*requiredVersion]; ok {
|
||||
return config, nil
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: have a better config copy method
|
||||
config := *c.defaultConfig
|
||||
|
||||
// TODO these fall out when we finish the refactor
|
||||
var preferredGV *unversioned.GroupVersion
|
||||
if version != nil {
|
||||
versionCopy := *version
|
||||
preferredGV = &versionCopy
|
||||
}
|
||||
|
||||
client.SetKubernetesDefaults(&config)
|
||||
negotiatedVersion, err := client.NegotiateVersion(c.defaultClient, &config, preferredGV, registered.EnabledVersions())
|
||||
negotiatedVersion, err := discovery.NegotiateVersion(discoveryClient, requiredVersion, registered.EnabledVersions())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
config.GroupVersion = negotiatedVersion
|
||||
|
||||
if version != nil {
|
||||
c.configs[*version] = &config
|
||||
// TODO this isn't what we want. Each clientset should be setting defaults as it sees fit.
|
||||
oldclient.SetKubernetesDefaults(&config)
|
||||
|
||||
if requiredVersion != nil {
|
||||
c.configs[*requiredVersion] = &config
|
||||
}
|
||||
|
||||
// `version` does not necessarily equal `config.Version`. However, we know that we call this method again with
|
||||
|
|
@ -95,38 +124,38 @@ func (c *ClientCache) ClientConfigForVersion(version *unversioned.GroupVersion)
|
|||
return &config, nil
|
||||
}
|
||||
|
||||
// ClientForVersion initializes or reuses a client for the specified version, or returns an
|
||||
// ClientSetForVersion initializes or reuses a clientset for the specified version, or returns an
|
||||
// error if that is not possible
|
||||
func (c *ClientCache) ClientForVersion(version *unversioned.GroupVersion) (*client.Client, error) {
|
||||
if version != nil {
|
||||
if client, ok := c.clients[*version]; ok {
|
||||
return client, nil
|
||||
func (c *ClientCache) ClientSetForVersion(requiredVersion *unversioned.GroupVersion) (*internalclientset.Clientset, error) {
|
||||
if requiredVersion != nil {
|
||||
if clientset, ok := c.clientsets[*requiredVersion]; ok {
|
||||
return clientset, nil
|
||||
}
|
||||
}
|
||||
config, err := c.ClientConfigForVersion(version)
|
||||
config, err := c.ClientConfigForVersion(requiredVersion)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
kubeclient, err := client.New(config)
|
||||
clientset, err := internalclientset.NewForConfig(config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
c.clients[*config.GroupVersion] = kubeclient
|
||||
c.clientsets[*config.GroupVersion] = clientset
|
||||
|
||||
// `version` does not necessarily equal `config.Version`. However, we know that if we call this method again with
|
||||
// `version`, we should get a client based on the same config we just found. There's no guarantee that a client
|
||||
// is copiable, so create a new client and save it in the cache.
|
||||
if version != nil {
|
||||
if requiredVersion != nil {
|
||||
configCopy := *config
|
||||
kubeclient, err := client.New(&configCopy)
|
||||
clientset, err := internalclientset.NewForConfig(&configCopy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
c.clients[*version] = kubeclient
|
||||
c.clientsets[*requiredVersion] = clientset
|
||||
}
|
||||
|
||||
return kubeclient, nil
|
||||
return clientset, nil
|
||||
}
|
||||
|
||||
func (c *ClientCache) FederationClientSetForVersion(version *unversioned.GroupVersion) (fed_clientset.Interface, error) {
|
||||
|
|
@ -164,5 +193,5 @@ func (c *ClientCache) FederationClientForVersion(version *unversioned.GroupVersi
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return fedClientSet.(*fed_clientset.Clientset).FederationClient.RESTClient, nil
|
||||
return fedClientSet.Federation().RESTClient().(*restclient.RESTClient), nil
|
||||
}
|
||||
|
|
|
|||
1467
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/factory.go
generated
vendored
1467
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/factory.go
generated
vendored
File diff suppressed because it is too large
Load diff
250
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/helpers.go
generated
vendored
250
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/helpers.go
generated
vendored
|
|
@ -28,12 +28,12 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
kerrors "k8s.io/kubernetes/pkg/api/errors"
|
||||
"k8s.io/kubernetes/pkg/api/meta"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
"k8s.io/kubernetes/pkg/apimachinery/registered"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/client/typed/discovery"
|
||||
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
|
||||
"k8s.io/kubernetes/pkg/kubectl"
|
||||
"k8s.io/kubernetes/pkg/kubectl/resource"
|
||||
|
|
@ -43,10 +43,9 @@ import (
|
|||
"k8s.io/kubernetes/pkg/util/sets"
|
||||
"k8s.io/kubernetes/pkg/util/strategicpatch"
|
||||
|
||||
"github.com/evanphx/json-patch"
|
||||
jsonpatch "github.com/evanphx/json-patch"
|
||||
"github.com/golang/glog"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
@ -60,7 +59,7 @@ type debugError interface {
|
|||
|
||||
// AddSourceToErr adds handleResourcePrefix and source string to error message.
|
||||
// verb is the string like "creating", "deleting" etc.
|
||||
// souce is the filename or URL to the template file(*.json or *.yaml), or stdin to use to handle the resource.
|
||||
// source is the filename or URL to the template file(*.json or *.yaml), or stdin to use to handle the resource.
|
||||
func AddSourceToErr(verb string, source string, err error) error {
|
||||
if source != "" {
|
||||
if statusError, ok := err.(kerrors.APIStatus); ok {
|
||||
|
|
@ -88,23 +87,26 @@ func DefaultBehaviorOnFatal() {
|
|||
fatalErrHandler = fatal
|
||||
}
|
||||
|
||||
// fatal prints the message if set and then exits. If V(2) or greater, glog.Fatal
|
||||
// is invoked for extended information.
|
||||
// fatal prints the message (if provided) and then exits. If V(2) or greater,
|
||||
// glog.Fatal is invoked for extended information.
|
||||
func fatal(msg string, code int) {
|
||||
if glog.V(2) {
|
||||
glog.FatalDepth(2, msg)
|
||||
}
|
||||
if len(msg) > 0 {
|
||||
// add newline if needed
|
||||
if !strings.HasSuffix(msg, "\n") {
|
||||
msg += "\n"
|
||||
}
|
||||
|
||||
if glog.V(2) {
|
||||
glog.FatalDepth(2, msg)
|
||||
}
|
||||
fmt.Fprint(os.Stderr, msg)
|
||||
}
|
||||
os.Exit(code)
|
||||
}
|
||||
|
||||
// ErrExit may be passed to CheckError to instruct it to output nothing but exit with
|
||||
// status code 1.
|
||||
var ErrExit = fmt.Errorf("exit")
|
||||
|
||||
// CheckErr prints a user friendly error to STDERR and exits with a non-zero
|
||||
// exit code. Unrecognized errors will be printed with an "error: " prefix.
|
||||
//
|
||||
|
|
@ -122,9 +124,17 @@ func checkErrWithPrefix(prefix string, err error) {
|
|||
// checkErr formats a given error as a string and calls the passed handleErr
|
||||
// func with that string and an kubectl exit code.
|
||||
func checkErr(prefix string, err error, handleErr func(string, int)) {
|
||||
// unwrap aggregates of 1
|
||||
if agg, ok := err.(utilerrors.Aggregate); ok && len(agg.Errors()) == 1 {
|
||||
err = agg.Errors()[0]
|
||||
}
|
||||
|
||||
switch {
|
||||
case err == nil:
|
||||
return
|
||||
case err == ErrExit:
|
||||
handleErr("", DefaultErrorExitCode)
|
||||
return
|
||||
case kerrors.IsInvalid(err):
|
||||
details := err.(*kerrors.StatusError).Status().Details
|
||||
s := fmt.Sprintf("%sThe %s %q is invalid", prefix, details.Kind, details.Name)
|
||||
|
|
@ -196,8 +206,10 @@ func StandardErrorMessage(err error) (string, bool) {
|
|||
switch {
|
||||
case isStatus:
|
||||
switch s := status.Status(); {
|
||||
case s.Reason == "Unauthorized":
|
||||
case s.Reason == unversioned.StatusReasonUnauthorized:
|
||||
return fmt.Sprintf("error: You must be logged in to the server (%s)", s.Message), true
|
||||
case len(s.Reason) > 0:
|
||||
return fmt.Sprintf("Error from server (%s): %s", s.Reason, err.Error()), true
|
||||
default:
|
||||
return fmt.Sprintf("Error from server: %s", err.Error()), true
|
||||
}
|
||||
|
|
@ -242,6 +254,26 @@ func MultilineError(prefix string, err error) string {
|
|||
return fmt.Sprintf("%s%s\n", prefix, err)
|
||||
}
|
||||
|
||||
// PrintErrorWithCauses prints an error's kind, name, and each of the error's causes in a new line.
|
||||
// The returned string will end with a newline.
|
||||
// Returns true if a case exists to handle the error type, or false otherwise.
|
||||
func PrintErrorWithCauses(err error, errOut io.Writer) bool {
|
||||
switch t := err.(type) {
|
||||
case *kerrors.StatusError:
|
||||
errorDetails := t.Status().Details
|
||||
if errorDetails != nil {
|
||||
fmt.Fprintf(errOut, "error: %s %q is invalid\n\n", errorDetails.Kind, errorDetails.Name)
|
||||
for _, cause := range errorDetails.Causes {
|
||||
fmt.Fprintf(errOut, "* %s: %s\n", cause.Field, cause.Message)
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Fprintf(errOut, "error: %v\n", err)
|
||||
return false
|
||||
}
|
||||
|
||||
// MultipleErrors returns a newline delimited string containing
|
||||
// the prefix and referenced errors in standard form.
|
||||
func MultipleErrors(prefix string, errs []error) string {
|
||||
|
|
@ -266,6 +298,13 @@ func UsageError(cmd *cobra.Command, format string, args ...interface{}) error {
|
|||
return fmt.Errorf("%s\nSee '%s -h' for help and examples.", msg, cmd.CommandPath())
|
||||
}
|
||||
|
||||
func IsFilenameEmpty(filenames []string) bool {
|
||||
if len(filenames) == 0 {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Whether this cmd need watching objects.
|
||||
func isWatch(cmd *cobra.Command) bool {
|
||||
if w, err := cmd.Flags().GetBool("watch"); w && err == nil {
|
||||
|
|
@ -279,25 +318,26 @@ func isWatch(cmd *cobra.Command) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func getFlag(cmd *cobra.Command, flag string) *pflag.Flag {
|
||||
f := cmd.Flags().Lookup(flag)
|
||||
if f == nil {
|
||||
glog.Fatalf("flag accessed but not defined for command %s: %s", cmd.Name(), flag)
|
||||
}
|
||||
return f
|
||||
}
|
||||
|
||||
func GetFlagString(cmd *cobra.Command, flag string) string {
|
||||
s, err := cmd.Flags().GetString(flag)
|
||||
if err != nil {
|
||||
glog.Fatalf("err accessing flag %s for command %s: %v", flag, cmd.Name(), err)
|
||||
glog.Fatalf("error accessing flag %s for command %s: %v", flag, cmd.Name(), err)
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// GetFlagStringList can be used to accept multiple argument with flag repetition (e.g. -f arg1 -f arg2 ...)
|
||||
// GetFlagStringSlice can be used to accept multiple argument with flag repetition (e.g. -f arg1,arg2 -f arg3 ...)
|
||||
func GetFlagStringSlice(cmd *cobra.Command, flag string) []string {
|
||||
s, err := cmd.Flags().GetStringSlice(flag)
|
||||
if err != nil {
|
||||
glog.Fatalf("error accessing flag %s for command %s: %v", flag, cmd.Name(), err)
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// GetFlagStringArray can be used to accept multiple argument with flag repetition (e.g. -f arg1 -f arg2 ...)
|
||||
func GetFlagStringArray(cmd *cobra.Command, flag string) []string {
|
||||
s, err := cmd.Flags().GetStringArray(flag)
|
||||
if err != nil {
|
||||
glog.Fatalf("err accessing flag %s for command %s: %v", flag, cmd.Name(), err)
|
||||
}
|
||||
|
|
@ -316,7 +356,7 @@ func GetWideFlag(cmd *cobra.Command) bool {
|
|||
func GetFlagBool(cmd *cobra.Command, flag string) bool {
|
||||
b, err := cmd.Flags().GetBool(flag)
|
||||
if err != nil {
|
||||
glog.Fatalf("err accessing flag %s for command %s: %v", flag, cmd.Name(), err)
|
||||
glog.Fatalf("error accessing flag %s for command %s: %v", flag, cmd.Name(), err)
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
|
@ -325,7 +365,7 @@ func GetFlagBool(cmd *cobra.Command, flag string) bool {
|
|||
func GetFlagInt(cmd *cobra.Command, flag string) int {
|
||||
i, err := cmd.Flags().GetInt(flag)
|
||||
if err != nil {
|
||||
glog.Fatalf("err accessing flag %s for command %s: %v", flag, cmd.Name(), err)
|
||||
glog.Fatalf("error accessing flag %s for command %s: %v", flag, cmd.Name(), err)
|
||||
}
|
||||
return i
|
||||
}
|
||||
|
|
@ -334,7 +374,7 @@ func GetFlagInt(cmd *cobra.Command, flag string) int {
|
|||
func GetFlagInt64(cmd *cobra.Command, flag string) int64 {
|
||||
i, err := cmd.Flags().GetInt64(flag)
|
||||
if err != nil {
|
||||
glog.Fatalf("err accessing flag %s for command %s: %v", flag, cmd.Name(), err)
|
||||
glog.Fatalf("error accessing flag %s for command %s: %v", flag, cmd.Name(), err)
|
||||
}
|
||||
return i
|
||||
}
|
||||
|
|
@ -342,7 +382,7 @@ func GetFlagInt64(cmd *cobra.Command, flag string) int64 {
|
|||
func GetFlagDuration(cmd *cobra.Command, flag string) time.Duration {
|
||||
d, err := cmd.Flags().GetDuration(flag)
|
||||
if err != nil {
|
||||
glog.Fatalf("err accessing flag %s for command %s: %v", flag, cmd.Name(), err)
|
||||
glog.Fatalf("error accessing flag %s for command %s: %v", flag, cmd.Name(), err)
|
||||
}
|
||||
return d
|
||||
}
|
||||
|
|
@ -353,8 +393,9 @@ func AddValidateFlags(cmd *cobra.Command) {
|
|||
cmd.MarkFlagFilename("schema-cache-dir")
|
||||
}
|
||||
|
||||
func AddRecursiveFlag(cmd *cobra.Command, value *bool) {
|
||||
cmd.Flags().BoolVarP(value, "recursive", "R", *value, "Process the directory used in -f, --filename recursively. Useful when you want to manage related manifests organized within the same directory.")
|
||||
func AddFilenameOptionFlags(cmd *cobra.Command, options *resource.FilenameOptions, usage string) {
|
||||
kubectl.AddJsonFilenameFlag(cmd, &options.Filenames, "Filename, directory, or URL to files "+usage)
|
||||
cmd.Flags().BoolVarP(&options.Recursive, "recursive", "R", options.Recursive, "Process the directory used in -f, --filename recursively. Useful when you want to manage related manifests organized within the same directory.")
|
||||
}
|
||||
|
||||
// AddDryRunFlag adds dry-run flag to a command. Usually used by mutations.
|
||||
|
|
@ -509,58 +550,9 @@ func ShouldRecord(cmd *cobra.Command, info *resource.Info) bool {
|
|||
return GetRecordFlag(cmd) || (ContainsChangeCause(info) && !cmd.Flags().Changed("record"))
|
||||
}
|
||||
|
||||
// GetThirdPartyGroupVersions returns the thirdparty "group/versions"s and
|
||||
// resources supported by the server. A user may delete a thirdparty resource
|
||||
// when this function is running, so this function may return a "NotFound" error
|
||||
// due to the race.
|
||||
func GetThirdPartyGroupVersions(discovery discovery.DiscoveryInterface) ([]unversioned.GroupVersion, []unversioned.GroupVersionKind, error) {
|
||||
result := []unversioned.GroupVersion{}
|
||||
gvks := []unversioned.GroupVersionKind{}
|
||||
|
||||
groupList, err := discovery.ServerGroups()
|
||||
if err != nil {
|
||||
// On forbidden or not found, just return empty lists.
|
||||
if kerrors.IsForbidden(err) || kerrors.IsNotFound(err) {
|
||||
return result, gvks, nil
|
||||
}
|
||||
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
for ix := range groupList.Groups {
|
||||
group := &groupList.Groups[ix]
|
||||
for jx := range group.Versions {
|
||||
gv, err2 := unversioned.ParseGroupVersion(group.Versions[jx].GroupVersion)
|
||||
if err2 != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
// Skip GroupVersionKinds that have been statically registered.
|
||||
if registered.IsRegisteredVersion(gv) {
|
||||
continue
|
||||
}
|
||||
result = append(result, gv)
|
||||
|
||||
resourceList, err := discovery.ServerResourcesForGroupVersion(group.Versions[jx].GroupVersion)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
for kx := range resourceList.APIResources {
|
||||
gvks = append(gvks, gv.WithKind(resourceList.APIResources[kx].Kind))
|
||||
}
|
||||
}
|
||||
}
|
||||
return result, gvks, nil
|
||||
}
|
||||
|
||||
func GetIncludeThirdPartyAPIs(cmd *cobra.Command) bool {
|
||||
if cmd.Flags().Lookup("include-extended-apis") == nil {
|
||||
return false
|
||||
}
|
||||
return GetFlagBool(cmd, "include-extended-apis")
|
||||
}
|
||||
|
||||
func AddInclude3rdPartyFlags(cmd *cobra.Command) {
|
||||
cmd.Flags().Bool("include-extended-apis", true, "If true, include definitions of new APIs via calls to the API server. [default true]")
|
||||
cmd.Flags().MarkDeprecated("include-extended-apis", "No longer required.")
|
||||
}
|
||||
|
||||
// GetResourcesAndPairs retrieves resources and "KEY=VALUE or KEY-" pair args from given args
|
||||
|
|
@ -595,7 +587,7 @@ func ParsePairs(pairArgs []string, pairType string, supportRemove bool) (newPair
|
|||
for _, pairArg := range pairArgs {
|
||||
if strings.Index(pairArg, "=") != -1 {
|
||||
parts := strings.SplitN(pairArg, "=", 2)
|
||||
if len(parts) != 2 || len(parts[1]) == 0 {
|
||||
if len(parts) != 2 {
|
||||
if invalidBuf.Len() > 0 {
|
||||
invalidBuf.WriteString(", ")
|
||||
}
|
||||
|
|
@ -631,3 +623,105 @@ func MaybeConvertObject(obj runtime.Object, gv unversioned.GroupVersion, convert
|
|||
return converter.ConvertToVersion(obj, gv)
|
||||
}
|
||||
}
|
||||
|
||||
// MustPrintWithKinds determines if printer is dealing
|
||||
// with multiple resource kinds, in which case it will
|
||||
// return true, indicating resource kind will be
|
||||
// included as part of printer output
|
||||
func MustPrintWithKinds(objs []runtime.Object, infos []*resource.Info, sorter *kubectl.RuntimeSort, printAll bool) bool {
|
||||
var lastMap *meta.RESTMapping
|
||||
|
||||
if len(infos) == 1 && printAll {
|
||||
return true
|
||||
}
|
||||
|
||||
for ix := range objs {
|
||||
var mapping *meta.RESTMapping
|
||||
if sorter != nil {
|
||||
mapping = infos[sorter.OriginalPosition(ix)].Mapping
|
||||
} else {
|
||||
mapping = infos[ix].Mapping
|
||||
}
|
||||
|
||||
// display "kind" only if we have mixed resources
|
||||
if lastMap != nil && mapping.Resource != lastMap.Resource {
|
||||
return true
|
||||
}
|
||||
lastMap = mapping
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// FilterResourceList receives a list of runtime objects.
|
||||
// If any objects are filtered, that number is returned along with a modified list.
|
||||
func FilterResourceList(obj runtime.Object, filterFuncs kubectl.Filters, filterOpts *kubectl.PrintOptions) (int, []runtime.Object, error) {
|
||||
items, err := meta.ExtractList(obj)
|
||||
if err != nil {
|
||||
return 0, []runtime.Object{obj}, utilerrors.NewAggregate([]error{err})
|
||||
}
|
||||
if errs := runtime.DecodeList(items, api.Codecs.UniversalDecoder(), runtime.UnstructuredJSONScheme); len(errs) > 0 {
|
||||
return 0, []runtime.Object{obj}, utilerrors.NewAggregate(errs)
|
||||
}
|
||||
|
||||
filterCount := 0
|
||||
list := make([]runtime.Object, 0, len(items))
|
||||
for _, obj := range items {
|
||||
if isFiltered, err := filterFuncs.Filter(obj, filterOpts); !isFiltered {
|
||||
if err != nil {
|
||||
glog.V(2).Infof("Unable to filter resource: %v", err)
|
||||
continue
|
||||
}
|
||||
list = append(list, obj)
|
||||
} else if isFiltered {
|
||||
filterCount++
|
||||
}
|
||||
}
|
||||
return filterCount, list, nil
|
||||
}
|
||||
|
||||
func PrintFilterCount(hiddenObjNum int, resource string, options *kubectl.PrintOptions) {
|
||||
if !options.NoHeaders && !options.ShowAll && hiddenObjNum > 0 {
|
||||
glog.V(2).Infof(" info: %d completed object(s) was(were) not shown in %s list. Pass --show-all to see all objects.\n\n", hiddenObjNum, resource)
|
||||
}
|
||||
}
|
||||
|
||||
// ObjectListToVersionedObject receives a list of api objects and a group version
|
||||
// and squashes the list's items into a single versioned runtime.Object.
|
||||
func ObjectListToVersionedObject(objects []runtime.Object, version unversioned.GroupVersion) (runtime.Object, error) {
|
||||
objectList := &api.List{Items: objects}
|
||||
converted, err := resource.TryConvert(api.Scheme, objectList, version, registered.GroupOrDie(api.GroupName).GroupVersion)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return converted, nil
|
||||
}
|
||||
|
||||
// IsSiblingCommandExists receives a pointer to a cobra command and a target string.
|
||||
// Returns true if the target string is found in the list of sibling commands.
|
||||
func IsSiblingCommandExists(cmd *cobra.Command, targetCmdName string) bool {
|
||||
for _, c := range cmd.Parent().Commands() {
|
||||
if c.Name() == targetCmdName {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// DefaultSubCommandRun prints a command's help string to the specified output if no
|
||||
// arguments (sub-commands) are provided, or a usage error otherwise.
|
||||
func DefaultSubCommandRun(out io.Writer) func(c *cobra.Command, args []string) {
|
||||
return func(c *cobra.Command, args []string) {
|
||||
c.SetOutput(out)
|
||||
RequireNoArguments(c, args)
|
||||
c.Help()
|
||||
}
|
||||
}
|
||||
|
||||
// RequireNoArguments exits with a usage error if extra arguments are provided.
|
||||
func RequireNoArguments(c *cobra.Command, args []string) {
|
||||
if len(args) > 0 {
|
||||
CheckErr(UsageError(c, fmt.Sprintf(`unknown command %q`, strings.Join(args, " "))))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
10
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/printing.go
generated
vendored
10
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/printing.go
generated
vendored
|
|
@ -56,8 +56,12 @@ func AddNoHeadersFlags(cmd *cobra.Command) {
|
|||
}
|
||||
|
||||
// PrintSuccess prints message after finishing mutating operations
|
||||
func PrintSuccess(mapper meta.RESTMapper, shortOutput bool, out io.Writer, resource string, name string, operation string) {
|
||||
func PrintSuccess(mapper meta.RESTMapper, shortOutput bool, out io.Writer, resource string, name string, dryRun bool, operation string) {
|
||||
resource, _ = mapper.ResourceSingularizer(resource)
|
||||
dryRunMsg := ""
|
||||
if dryRun {
|
||||
dryRunMsg = " (dry run)"
|
||||
}
|
||||
if shortOutput {
|
||||
// -o name: prints resource/name
|
||||
if len(resource) > 0 {
|
||||
|
|
@ -68,9 +72,9 @@ func PrintSuccess(mapper meta.RESTMapper, shortOutput bool, out io.Writer, resou
|
|||
} else {
|
||||
// understandable output by default
|
||||
if len(resource) > 0 {
|
||||
fmt.Fprintf(out, "%s \"%s\" %s\n", resource, name, operation)
|
||||
fmt.Fprintf(out, "%s \"%s\" %s%s\n", resource, name, operation, dryRunMsg)
|
||||
} else {
|
||||
fmt.Fprintf(out, "\"%s\" %s\n", name, operation)
|
||||
fmt.Fprintf(out, "\"%s\" %s%s\n", name, operation, dryRunMsg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
147
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/shortcut_restmapper.go
generated
vendored
Normal file
147
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/shortcut_restmapper.go
generated
vendored
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
/*
|
||||
Copyright 2016 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 (
|
||||
"strings"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api/meta"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
"k8s.io/kubernetes/pkg/client/typed/discovery"
|
||||
"k8s.io/kubernetes/pkg/kubectl"
|
||||
)
|
||||
|
||||
// ShortcutExpander is a RESTMapper that can be used for Kubernetes resources. It expands the resource first, then invokes the wrapped
|
||||
type ShortcutExpander struct {
|
||||
RESTMapper meta.RESTMapper
|
||||
|
||||
All []unversioned.GroupResource
|
||||
|
||||
discoveryClient discovery.DiscoveryInterface
|
||||
}
|
||||
|
||||
var _ meta.RESTMapper = &ShortcutExpander{}
|
||||
|
||||
func NewShortcutExpander(delegate meta.RESTMapper, client discovery.DiscoveryInterface) ShortcutExpander {
|
||||
return ShortcutExpander{All: userResources, RESTMapper: delegate, discoveryClient: client}
|
||||
}
|
||||
|
||||
func (e ShortcutExpander) getAll() []unversioned.GroupResource {
|
||||
if e.discoveryClient == nil {
|
||||
return e.All
|
||||
}
|
||||
|
||||
// Check if we have access to server resources
|
||||
apiResources, err := e.discoveryClient.ServerResources()
|
||||
if err != nil {
|
||||
return e.All
|
||||
}
|
||||
|
||||
availableResources := []unversioned.GroupVersionResource{}
|
||||
for groupVersionString, resourceList := range apiResources {
|
||||
currVersion, err := unversioned.ParseGroupVersion(groupVersionString)
|
||||
if err != nil {
|
||||
return e.All
|
||||
}
|
||||
|
||||
for _, resource := range resourceList.APIResources {
|
||||
availableResources = append(availableResources, currVersion.WithResource(resource.Name))
|
||||
}
|
||||
}
|
||||
|
||||
availableAll := []unversioned.GroupResource{}
|
||||
for _, requestedResource := range e.All {
|
||||
for _, availableResource := range availableResources {
|
||||
if requestedResource.Group == availableResource.Group &&
|
||||
requestedResource.Resource == availableResource.Resource {
|
||||
availableAll = append(availableAll, requestedResource)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return availableAll
|
||||
}
|
||||
|
||||
func (e ShortcutExpander) KindFor(resource unversioned.GroupVersionResource) (unversioned.GroupVersionKind, error) {
|
||||
return e.RESTMapper.KindFor(expandResourceShortcut(resource))
|
||||
}
|
||||
|
||||
func (e ShortcutExpander) KindsFor(resource unversioned.GroupVersionResource) ([]unversioned.GroupVersionKind, error) {
|
||||
return e.RESTMapper.KindsFor(expandResourceShortcut(resource))
|
||||
}
|
||||
|
||||
func (e ShortcutExpander) ResourcesFor(resource unversioned.GroupVersionResource) ([]unversioned.GroupVersionResource, error) {
|
||||
return e.RESTMapper.ResourcesFor(expandResourceShortcut(resource))
|
||||
}
|
||||
|
||||
func (e ShortcutExpander) ResourceFor(resource unversioned.GroupVersionResource) (unversioned.GroupVersionResource, error) {
|
||||
return e.RESTMapper.ResourceFor(expandResourceShortcut(resource))
|
||||
}
|
||||
|
||||
func (e ShortcutExpander) ResourceSingularizer(resource string) (string, error) {
|
||||
return e.RESTMapper.ResourceSingularizer(expandResourceShortcut(unversioned.GroupVersionResource{Resource: resource}).Resource)
|
||||
}
|
||||
|
||||
func (e ShortcutExpander) RESTMapping(gk unversioned.GroupKind, versions ...string) (*meta.RESTMapping, error) {
|
||||
return e.RESTMapper.RESTMapping(gk, versions...)
|
||||
}
|
||||
|
||||
func (e ShortcutExpander) RESTMappings(gk unversioned.GroupKind) ([]*meta.RESTMapping, error) {
|
||||
return e.RESTMapper.RESTMappings(gk)
|
||||
}
|
||||
|
||||
// userResources are the resource names that apply to the primary, user facing resources used by
|
||||
// client tools. They are in deletion-first order - dependent resources should be last.
|
||||
var userResources = []unversioned.GroupResource{
|
||||
{Group: "", Resource: "pods"},
|
||||
{Group: "", Resource: "replicationcontrollers"},
|
||||
{Group: "", Resource: "services"},
|
||||
{Group: "apps", Resource: "statefulsets"},
|
||||
{Group: "autoscaling", Resource: "horizontalpodautoscalers"},
|
||||
{Group: "extensions", Resource: "jobs"},
|
||||
{Group: "extensions", Resource: "deployments"},
|
||||
{Group: "extensions", Resource: "replicasets"},
|
||||
}
|
||||
|
||||
// AliasesForResource returns whether a resource has an alias or not
|
||||
func (e ShortcutExpander) AliasesForResource(resource string) ([]string, bool) {
|
||||
if strings.ToLower(resource) == "all" {
|
||||
var resources []unversioned.GroupResource
|
||||
if resources = e.getAll(); len(resources) == 0 {
|
||||
resources = userResources
|
||||
}
|
||||
aliases := []string{}
|
||||
for _, r := range resources {
|
||||
aliases = append(aliases, r.Resource)
|
||||
}
|
||||
return aliases, true
|
||||
}
|
||||
expanded := expandResourceShortcut(unversioned.GroupVersionResource{Resource: resource}).Resource
|
||||
return []string{expanded}, (expanded != resource)
|
||||
}
|
||||
|
||||
// expandResourceShortcut will return the expanded version of resource
|
||||
// (something that a pkg/api/meta.RESTMapper can understand), if it is
|
||||
// indeed a shortcut. Otherwise, will return resource unmodified.
|
||||
func expandResourceShortcut(resource unversioned.GroupVersionResource) unversioned.GroupVersionResource {
|
||||
if expanded, ok := kubectl.ShortForms[resource.Resource]; ok {
|
||||
resource.Resource = expanded
|
||||
return resource
|
||||
}
|
||||
return resource
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue