mirror of https://github.com/k3s-io/k3s
Make expandResourceShortcuts part of RESTMapper on client
parent
a1ee782df5
commit
8a4f225941
|
@ -19,11 +19,15 @@ package main
|
|||
import (
|
||||
"os"
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd"
|
||||
|
||||
"github.com/golang/glog"
|
||||
)
|
||||
|
||||
func main() {
|
||||
clientBuilder := clientcmd.NewInteractiveClientConfig(clientcmd.Config{}, "", &clientcmd.ConfigOverrides{}, os.Stdin)
|
||||
cmd.NewFactory(clientBuilder).Run(os.Stdout)
|
||||
cmd := cmd.NewFactory().NewKubectlCommand(os.Stdout)
|
||||
if err := cmd.Execute(); err != nil {
|
||||
glog.Errorf("error: %v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ import (
|
|||
|
||||
"github.com/golang/glog"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -42,55 +43,108 @@ const (
|
|||
// Factory provides abstractions that allow the Kubectl command to be extended across multiple types
|
||||
// of resources and different API sets.
|
||||
type Factory struct {
|
||||
ClientConfig clientcmd.ClientConfig
|
||||
Mapper meta.RESTMapper
|
||||
Typer runtime.ObjectTyper
|
||||
Client func(cmd *cobra.Command, mapping *meta.RESTMapping) (kubectl.RESTClient, error)
|
||||
Describer func(cmd *cobra.Command, mapping *meta.RESTMapping) (kubectl.Describer, error)
|
||||
Printer func(cmd *cobra.Command, mapping *meta.RESTMapping, noHeaders bool) (kubectl.ResourcePrinter, error)
|
||||
Validator func(*cobra.Command) (validation.Schema, error)
|
||||
clients *clientCache
|
||||
flags *pflag.FlagSet
|
||||
|
||||
Mapper meta.RESTMapper
|
||||
Typer runtime.ObjectTyper
|
||||
|
||||
// Returns a client for accessing Kubernetes resources or an error.
|
||||
Client func(cmd *cobra.Command) (*client.Client, error)
|
||||
// Returns a client.Config for accessing the Kubernetes server.
|
||||
ClientConfig func(cmd *cobra.Command) (*client.Config, error)
|
||||
// Returns a RESTClient for working with the specified RESTMapping or an error. This is intended
|
||||
// for working with arbitrary resources and is not guaranteed to point to a Kubernetes APIServer.
|
||||
RESTClient func(cmd *cobra.Command, mapping *meta.RESTMapping) (kubectl.RESTClient, error)
|
||||
// Returns a Describer for displaying the specified RESTMapping type or an error.
|
||||
Describer func(cmd *cobra.Command, mapping *meta.RESTMapping) (kubectl.Describer, error)
|
||||
// Returns a Printer for formatting objects of the given type or an error.
|
||||
Printer func(cmd *cobra.Command, mapping *meta.RESTMapping, noHeaders bool) (kubectl.ResourcePrinter, error)
|
||||
// Returns a schema that can validate objects stored on disk.
|
||||
Validator func(*cobra.Command) (validation.Schema, error)
|
||||
}
|
||||
|
||||
// NewFactory creates a factory with the default Kubernetes resources defined
|
||||
func NewFactory(clientConfig clientcmd.ClientConfig) *Factory {
|
||||
ret := &Factory{
|
||||
ClientConfig: clientConfig,
|
||||
Mapper: latest.RESTMapper,
|
||||
Typer: api.Scheme,
|
||||
Printer: func(cmd *cobra.Command, mapping *meta.RESTMapping, noHeaders bool) (kubectl.ResourcePrinter, error) {
|
||||
return kubectl.NewHumanReadablePrinter(noHeaders), nil
|
||||
},
|
||||
func NewFactory() *Factory {
|
||||
mapper := kubectl.ShortcutExpander{latest.RESTMapper}
|
||||
|
||||
flags := pflag.NewFlagSet("", pflag.ContinueOnError)
|
||||
clientConfig := DefaultClientConfig(flags)
|
||||
clients := &clientCache{
|
||||
clients: make(map[string]*client.Client),
|
||||
loader: clientConfig,
|
||||
}
|
||||
|
||||
ret.Validator = func(cmd *cobra.Command) (validation.Schema, error) {
|
||||
if GetFlagBool(cmd, "validate") {
|
||||
client, err := getClient(ret.ClientConfig, GetFlagBool(cmd, FlagMatchBinaryVersion))
|
||||
return &Factory{
|
||||
clients: clients,
|
||||
flags: flags,
|
||||
|
||||
Mapper: mapper,
|
||||
Typer: api.Scheme,
|
||||
|
||||
Client: func(cmd *cobra.Command) (*client.Client, error) {
|
||||
return clients.ClientForVersion("")
|
||||
},
|
||||
ClientConfig: func(cmd *cobra.Command) (*client.Config, error) {
|
||||
return clients.ClientConfigForVersion("")
|
||||
},
|
||||
RESTClient: func(cmd *cobra.Command, mapping *meta.RESTMapping) (kubectl.RESTClient, error) {
|
||||
client, err := clients.ClientForVersion(mapping.APIVersion)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &clientSwaggerSchema{client, api.Scheme}, nil
|
||||
} else {
|
||||
return client.RESTClient, nil
|
||||
},
|
||||
Describer: func(cmd *cobra.Command, mapping *meta.RESTMapping) (kubectl.Describer, error) {
|
||||
client, err := clients.ClientForVersion(mapping.APIVersion)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
describer, ok := kubectl.DescriberFor(mapping.Kind, client)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("no description has been implemented for %q", mapping.Kind)
|
||||
}
|
||||
return describer, nil
|
||||
},
|
||||
Printer: func(cmd *cobra.Command, mapping *meta.RESTMapping, noHeaders bool) (kubectl.ResourcePrinter, error) {
|
||||
return kubectl.NewHumanReadablePrinter(noHeaders), nil
|
||||
},
|
||||
Validator: func(cmd *cobra.Command) (validation.Schema, error) {
|
||||
if GetFlagBool(cmd, "validate") {
|
||||
client, err := clients.ClientForVersion("")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &clientSwaggerSchema{client, api.Scheme}, nil
|
||||
}
|
||||
return validation.NullSchema{}, nil
|
||||
}
|
||||
},
|
||||
}
|
||||
ret.Client = func(cmd *cobra.Command, mapping *meta.RESTMapping) (kubectl.RESTClient, error) {
|
||||
return getClient(ret.ClientConfig, GetFlagBool(cmd, FlagMatchBinaryVersion))
|
||||
}
|
||||
ret.Describer = func(cmd *cobra.Command, mapping *meta.RESTMapping) (kubectl.Describer, error) {
|
||||
client, err := getClient(ret.ClientConfig, GetFlagBool(cmd, FlagMatchBinaryVersion))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
describer, ok := kubectl.DescriberFor(mapping.Kind, client)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("no description has been implemented for %q", mapping.Kind)
|
||||
}
|
||||
return describer, nil
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (f *Factory) Run(out io.Writer) {
|
||||
// BindFlags adds any flags that are common to all kubectl sub commands.
|
||||
func (f *Factory) BindFlags(flags *pflag.FlagSet) {
|
||||
// any flags defined by external projects (not part of pflags)
|
||||
util.AddAllFlagsToPFlagSet(flags)
|
||||
|
||||
if f.flags != nil {
|
||||
f.flags.VisitAll(func(flag *pflag.Flag) {
|
||||
flags.AddFlag(flag)
|
||||
})
|
||||
}
|
||||
|
||||
// Globally persistent flags across all subcommands.
|
||||
// TODO Change flag names to consts to allow safer lookup from subcommands.
|
||||
// TODO Add a verbose flag that turns on glog logging. Probably need a way
|
||||
// to do that automatically for every subcommand.
|
||||
flags.BoolVar(&f.clients.matchVersion, FlagMatchBinaryVersion, false, "Require server version to match client version")
|
||||
flags.String("ns-path", os.Getenv("HOME")+"/.kubernetes_ns", "Path to the namespace info file that holds the namespace context to use for CLI requests.")
|
||||
flags.StringP("namespace", "n", "", "If present, the namespace scope for this CLI request.")
|
||||
flags.Bool("validate", false, "If true, use a schema to validate the input before sending it")
|
||||
}
|
||||
|
||||
// NewKubectlCommand creates the `kubectl` command and its nested children.
|
||||
func (f *Factory) NewKubectlCommand(out io.Writer) *cobra.Command {
|
||||
// Parent command to which all subcommands are added.
|
||||
cmds := &cobra.Command{
|
||||
Use: "kubectl",
|
||||
|
@ -101,15 +155,7 @@ Find more information at https://github.com/GoogleCloudPlatform/kubernetes.`,
|
|||
Run: runHelp,
|
||||
}
|
||||
|
||||
util.AddAllFlagsToPFlagSet(cmds.PersistentFlags())
|
||||
f.ClientConfig = getClientConfig(cmds)
|
||||
|
||||
// Globally persistent flags across all subcommands.
|
||||
// TODO Change flag names to consts to allow safer lookup from subcommands.
|
||||
cmds.PersistentFlags().Bool(FlagMatchBinaryVersion, false, "Require server version to match client version")
|
||||
cmds.PersistentFlags().String("ns-path", os.Getenv("HOME")+"/.kubernetes_ns", "Path to the namespace info file that holds the namespace context to use for CLI requests.")
|
||||
cmds.PersistentFlags().StringP("namespace", "n", "", "If present, the namespace scope for this CLI request.")
|
||||
cmds.PersistentFlags().Bool("validate", false, "If true, use a schema to validate the input before sending it")
|
||||
f.BindFlags(cmds.PersistentFlags())
|
||||
|
||||
cmds.AddCommand(f.NewCmdVersion(out))
|
||||
cmds.AddCommand(f.NewCmdProxy(out))
|
||||
|
@ -125,12 +171,10 @@ Find more information at https://github.com/GoogleCloudPlatform/kubernetes.`,
|
|||
cmds.AddCommand(f.NewCmdLog(out))
|
||||
cmds.AddCommand(f.NewCmdRollingUpdate(out))
|
||||
|
||||
if err := cmds.Execute(); err != nil {
|
||||
os.Exit(1)
|
||||
}
|
||||
return cmds
|
||||
}
|
||||
|
||||
// getClientBuilder creates a clientcmd.ClientConfig that has a hierarchy like this:
|
||||
// DefaultClientConfig creates a clientcmd.ClientConfig with the following hierarchy:
|
||||
// 1. Use the kubeconfig builder. The number of merges and overrides here gets a little crazy. Stay with me.
|
||||
// 1. Merge together the kubeconfig itself. This is done with the following hierarchy and merge rules:
|
||||
// 1. CommandLineLocation - this parsed from the command line, so it must be late bound
|
||||
|
@ -162,13 +206,13 @@ Find more information at https://github.com/GoogleCloudPlatform/kubernetes.`,
|
|||
// 2. If the command line does not specify one, and the auth info has conflicting techniques, fail.
|
||||
// 3. If the command line specifies one and the auth info specifies another, honor the command line technique.
|
||||
// 2. Use default values and potentially prompt for auth information
|
||||
func getClientConfig(cmd *cobra.Command) clientcmd.ClientConfig {
|
||||
func DefaultClientConfig(flags *pflag.FlagSet) clientcmd.ClientConfig {
|
||||
loadingRules := clientcmd.NewClientConfigLoadingRules()
|
||||
loadingRules.EnvVarPath = os.Getenv(clientcmd.RecommendedConfigPathEnvVar)
|
||||
cmd.PersistentFlags().StringVar(&loadingRules.CommandLinePath, "kubeconfig", "", "Path to the kubeconfig file to use for CLI requests.")
|
||||
flags.StringVar(&loadingRules.CommandLinePath, "kubeconfig", "", "Path to the kubeconfig file to use for CLI requests.")
|
||||
|
||||
overrides := &clientcmd.ConfigOverrides{}
|
||||
overrides.BindFlags(cmd.PersistentFlags(), clientcmd.RecommendedConfigOverrideFlags(""))
|
||||
overrides.BindFlags(flags, clientcmd.RecommendedConfigOverrideFlags(""))
|
||||
clientConfig := clientcmd.NewInteractiveDeferredLoadingClientConfig(loadingRules, overrides, os.Stdin)
|
||||
|
||||
return clientConfig
|
||||
|
@ -246,18 +290,55 @@ func (c *clientSwaggerSchema) ValidateBytes(data []byte) error {
|
|||
return schema.ValidateBytes(data)
|
||||
}
|
||||
|
||||
// TODO Need to only run server version match once per client host creation
|
||||
func getClient(clientConfig clientcmd.ClientConfig, matchServerVersion bool) (*client.Client, error) {
|
||||
config, err := clientConfig.ClientConfig()
|
||||
// clientCache caches previously loaded clients for reuse, and ensures MatchServerVersion
|
||||
// is invoked only once
|
||||
type clientCache struct {
|
||||
loader clientcmd.ClientConfig
|
||||
clients map[string]*client.Client
|
||||
defaultConfig *client.Config
|
||||
matchVersion bool
|
||||
}
|
||||
|
||||
// ClientConfigForVersion returns the correct config for a server
|
||||
func (c *clientCache) ClientConfigForVersion(version string) (*client.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(config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: remove when SetKubernetesDefaults gets added
|
||||
if len(version) == 0 {
|
||||
version = c.defaultConfig.Version
|
||||
}
|
||||
|
||||
// TODO: have a better config copy method
|
||||
config := *c.defaultConfig
|
||||
|
||||
// TODO: call new client.SetKubernetesDefaults method
|
||||
// instead of doing this
|
||||
config.Version = version
|
||||
return &config, nil
|
||||
}
|
||||
|
||||
// ClientForVersion initializes or reuses a client for the specified version, or returns an
|
||||
// error if that is not possible
|
||||
func (c *clientCache) ClientForVersion(version string) (*client.Client, error) {
|
||||
config, err := c.ClientConfigForVersion(version)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if matchServerVersion {
|
||||
err := client.MatchesServerVersion(config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if client, ok := c.clients[config.Version]; ok {
|
||||
return client, nil
|
||||
}
|
||||
|
||||
client, err := client.New(config)
|
||||
|
@ -265,5 +346,6 @@ func getClient(clientConfig clientcmd.ClientConfig, matchServerVersion bool) (*c
|
|||
return nil, err
|
||||
}
|
||||
|
||||
c.clients[config.Version] = client
|
||||
return client, nil
|
||||
}
|
||||
|
|
|
@ -100,7 +100,7 @@ func NewTestFactory() (*Factory, *testFactory, runtime.Codec) {
|
|||
return &Factory{
|
||||
Mapper: mapper,
|
||||
Typer: scheme,
|
||||
Client: func(*cobra.Command, *meta.RESTMapping) (kubectl.RESTClient, error) {
|
||||
RESTClient: func(*cobra.Command, *meta.RESTMapping) (kubectl.RESTClient, error) {
|
||||
return t.Client, t.Err
|
||||
},
|
||||
Describer: func(*cobra.Command, *meta.RESTMapping) (kubectl.Describer, error) {
|
||||
|
|
|
@ -46,7 +46,7 @@ Examples:
|
|||
schema, err := f.Validator(cmd)
|
||||
checkErr(err)
|
||||
mapping, namespace, name, data := ResourceFromFile(cmd, filename, f.Typer, f.Mapper, schema)
|
||||
client, err := f.Client(cmd, mapping)
|
||||
client, err := f.RESTClient(cmd, mapping)
|
||||
checkErr(err)
|
||||
|
||||
// use the default namespace if not specified, or check for conflict with the file's namespace
|
||||
|
|
|
@ -79,7 +79,7 @@ Examples:
|
|||
<creates all resources listed in config.json>`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
clientFunc := func(mapper *meta.RESTMapping) (config.RESTClientPoster, error) {
|
||||
client, err := f.Client(cmd, mapper)
|
||||
client, err := f.RESTClient(cmd, mapper)
|
||||
checkErr(err)
|
||||
return client, nil
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ Examples:
|
|||
checkErr(err)
|
||||
selector := GetFlagString(cmd, "selector")
|
||||
found := 0
|
||||
ResourcesFromArgsOrFile(cmd, args, filename, selector, f.Typer, f.Mapper, f.Client, schema).Visit(func(r *resource.Info) error {
|
||||
ResourcesFromArgsOrFile(cmd, args, filename, selector, f.Typer, f.Mapper, f.RESTClient, schema).Visit(func(r *resource.Info) error {
|
||||
found++
|
||||
if err := resource.NewHelper(r.Client, r.Mapping).Delete(r.Namespace, r.Name); err != nil {
|
||||
return err
|
||||
|
|
|
@ -56,7 +56,7 @@ Examples:
|
|||
labelSelector, err := labels.ParseSelector(selector)
|
||||
checkErr(err)
|
||||
|
||||
client, err := f.Client(cmd, mapping)
|
||||
client, err := f.RESTClient(cmd, mapping)
|
||||
checkErr(err)
|
||||
|
||||
outputFormat := GetFlagString(cmd, "output")
|
||||
|
|
|
@ -21,8 +21,6 @@ import (
|
|||
"strconv"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
|
||||
)
|
||||
|
||||
func (f *Factory) NewCmdLog(out io.Writer) *cobra.Command {
|
||||
|
@ -46,9 +44,7 @@ Examples:
|
|||
}
|
||||
|
||||
namespace := GetKubeNamespace(cmd)
|
||||
config, err := f.ClientConfig.ClientConfig()
|
||||
checkErr(err)
|
||||
client, err := client.New(config)
|
||||
client, err := f.Client(cmd)
|
||||
checkErr(err)
|
||||
|
||||
podID := args[0]
|
||||
|
|
|
@ -33,7 +33,7 @@ func (f *Factory) NewCmdProxy(out io.Writer) *cobra.Command {
|
|||
port := GetFlagInt(cmd, "port")
|
||||
glog.Infof("Starting to serve on localhost:%d", port)
|
||||
|
||||
clientConfig, err := f.ClientConfig.ClientConfig()
|
||||
clientConfig, err := f.ClientConfig(cmd)
|
||||
checkErr(err)
|
||||
|
||||
server, err := kubectl.NewProxyServer(GetFlagString(cmd, "www"), clientConfig, port)
|
||||
|
|
|
@ -63,7 +63,7 @@ func ResourcesFromArgsOrFile(
|
|||
}
|
||||
types := SplitResourceArgument(args[0])
|
||||
for _, arg := range types {
|
||||
resourceName := kubectl.ExpandResourceShortcut(arg)
|
||||
resourceName := arg
|
||||
if len(resourceName) == 0 {
|
||||
usageError(cmd, "Unknown resource %s", resourceName)
|
||||
}
|
||||
|
@ -91,7 +91,7 @@ func ResourceFromArgsOrFile(cmd *cobra.Command, args []string, filename string,
|
|||
}
|
||||
|
||||
if len(args) == 2 {
|
||||
resource := kubectl.ExpandResourceShortcut(args[0])
|
||||
resource := args[0]
|
||||
namespace = GetKubeNamespace(cmd)
|
||||
name = args[1]
|
||||
if len(name) == 0 || len(resource) == 0 {
|
||||
|
@ -129,7 +129,7 @@ func ResourceFromArgs(cmd *cobra.Command, args []string, mapper meta.RESTMapper)
|
|||
usageError(cmd, "Must provide resource and name command line params")
|
||||
}
|
||||
|
||||
resource := kubectl.ExpandResourceShortcut(args[0])
|
||||
resource := args[0]
|
||||
namespace = GetKubeNamespace(cmd)
|
||||
name = args[1]
|
||||
if len(name) == 0 || len(resource) == 0 {
|
||||
|
@ -152,7 +152,7 @@ func ResourceOrTypeFromArgs(cmd *cobra.Command, args []string, mapper meta.RESTM
|
|||
usageError(cmd, "Must provide resource or a resource and name as command line params")
|
||||
}
|
||||
|
||||
resource := kubectl.ExpandResourceShortcut(args[0])
|
||||
resource := args[0]
|
||||
if len(resource) == 0 {
|
||||
usageError(cmd, "Must provide resource or a resource and name as command line params")
|
||||
}
|
||||
|
|
|
@ -21,7 +21,6 @@ import (
|
|||
"io"
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
@ -69,9 +68,7 @@ $ cat frontend-v2.json | kubectl rollingupdate frontend-v1 -f -
|
|||
err = CompareNamespaceFromFile(cmd, namespace)
|
||||
checkErr(err)
|
||||
|
||||
config, err := f.ClientConfig.ClientConfig()
|
||||
checkErr(err)
|
||||
client, err := client.New(config)
|
||||
client, err := f.Client(cmd)
|
||||
checkErr(err)
|
||||
|
||||
obj, err := mapping.Codec.Decode(data)
|
||||
|
|
|
@ -46,7 +46,7 @@ Examples:
|
|||
schema, err := f.Validator(cmd)
|
||||
checkErr(err)
|
||||
mapping, namespace, name, data := ResourceFromFile(cmd, filename, f.Typer, f.Mapper, schema)
|
||||
client, err := f.Client(cmd, mapping)
|
||||
client, err := f.RESTClient(cmd, mapping)
|
||||
checkErr(err)
|
||||
|
||||
err = CompareNamespaceFromFile(cmd, namespace)
|
||||
|
|
|
@ -21,7 +21,6 @@ import (
|
|||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl"
|
||||
)
|
||||
|
||||
|
@ -32,14 +31,13 @@ func (f *Factory) NewCmdVersion(out io.Writer) *cobra.Command {
|
|||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if GetFlagBool(cmd, "client") {
|
||||
kubectl.GetClientVersion(out)
|
||||
} else {
|
||||
config, err := f.ClientConfig.ClientConfig()
|
||||
checkErr(err)
|
||||
client, err := client.New(config)
|
||||
checkErr(err)
|
||||
|
||||
kubectl.GetVersion(out, client)
|
||||
return
|
||||
}
|
||||
|
||||
client, err := f.Client(cmd)
|
||||
checkErr(err)
|
||||
|
||||
kubectl.GetVersion(out, client)
|
||||
},
|
||||
}
|
||||
cmd.Flags().BoolP("client", "c", false, "Client version only (no server required)")
|
||||
|
|
|
@ -26,6 +26,7 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/meta"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
||||
|
@ -111,12 +112,23 @@ func makeImageList(spec *api.PodSpec) string {
|
|||
return strings.Join(listOfImages(spec), ",")
|
||||
}
|
||||
|
||||
// ExpandResourceShortcut will return the expanded version of resource
|
||||
// ShortcutExpander is a RESTMapper that can be used for Kubernetes
|
||||
// resources.
|
||||
type ShortcutExpander struct {
|
||||
meta.RESTMapper
|
||||
}
|
||||
|
||||
// VersionAndKindForResource implements meta.RESTMapper. It expands the resource first, then invokes the wrapped
|
||||
// mapper.
|
||||
func (e ShortcutExpander) VersionAndKindForResource(resource string) (defaultVersion, kind string, err error) {
|
||||
resource = expandResourceShortcut(resource)
|
||||
return e.RESTMapper.VersionAndKindForResource(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.
|
||||
// TODO: Combine with RESTMapper stuff to provide a general solution
|
||||
// to this problem.
|
||||
func ExpandResourceShortcut(resource string) string {
|
||||
func expandResourceShortcut(resource string) string {
|
||||
shortForms := map[string]string{
|
||||
"po": "pods",
|
||||
"rc": "replicationcontrollers",
|
||||
|
|
Loading…
Reference in New Issue