Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
bb137f0b
Commit
bb137f0b
authored
Apr 07, 2015
by
Clayton Coleman
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #6534 from deads2k/deads-kubeconfig-cmd-factory
refactor to move kubectl.cmd.Factory to kubect/cmd/util
parents
6eb54e73
6344cf3c
Hide whitespace changes
Inline
Side-by-side
Showing
34 changed files
with
664 additions
and
611 deletions
+664
-611
gen_kubectl_docs.go
cmd/gendocs/gen_kubectl_docs.go
+2
-1
gen_kubectl_man.go
cmd/genman/gen_kubectl_man.go
+2
-1
kubectl.go
cmd/kubectl/kubectl.go
+2
-1
apiversions.go
pkg/kubectl/cmd/apiversions.go
+4
-4
clusterinfo.go
pkg/kubectl/cmd/clusterinfo.go
+4
-4
cmd.go
pkg/kubectl/cmd/cmd.go
+20
-441
cmd_test.go
pkg/kubectl/cmd/cmd_test.go
+7
-6
config.go
pkg/kubectl/cmd/config/config.go
+2
-1
config_test.go
pkg/kubectl/cmd/config/config_test.go
+3
-1
create.go
pkg/kubectl/cmd/create.go
+2
-2
create_test.go
pkg/kubectl/cmd/create_test.go
+4
-4
delete.go
pkg/kubectl/cmd/delete.go
+2
-2
delete_test.go
pkg/kubectl/cmd/delete_test.go
+6
-6
describe.go
pkg/kubectl/cmd/describe.go
+5
-5
describe_test.go
pkg/kubectl/cmd/describe_test.go
+1
-1
exec.go
pkg/kubectl/cmd/exec.go
+10
-10
expose.go
pkg/kubectl/cmd/expose.go
+18
-18
get.go
pkg/kubectl/cmd/get.go
+9
-9
get_test.go
pkg/kubectl/cmd/get_test.go
+11
-11
label.go
pkg/kubectl/cmd/label.go
+13
-13
label_test.go
pkg/kubectl/cmd/label_test.go
+2
-2
log.go
pkg/kubectl/cmd/log.go
+7
-7
portforward.go
pkg/kubectl/cmd/portforward.go
+7
-7
proxy.go
pkg/kubectl/cmd/proxy.go
+8
-8
resize.go
pkg/kubectl/cmd/resize.go
+9
-9
rollingupdate.go
pkg/kubectl/cmd/rollingupdate.go
+13
-13
run.go
pkg/kubectl/cmd/run.go
+11
-11
stop.go
pkg/kubectl/cmd/stop.go
+1
-1
update.go
pkg/kubectl/cmd/update.go
+3
-3
update_test.go
pkg/kubectl/cmd/update_test.go
+3
-3
clientcache.go
pkg/kubectl/cmd/util/clientcache.go
+76
-0
factory.go
pkg/kubectl/cmd/util/factory.go
+391
-0
factory_test.go
pkg/kubectl/cmd/util/factory_test.go
+1
-1
version.go
pkg/kubectl/cmd/version.go
+5
-5
No files found.
cmd/gendocs/gen_kubectl_docs.go
View file @
bb137f0b
...
...
@@ -25,6 +25,7 @@ import (
"strings"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd"
cmdutil
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/util"
"github.com/spf13/cobra"
)
...
...
@@ -139,7 +140,7 @@ func main() {
// regardless of where we run.
os
.
Setenv
(
"HOME"
,
"/home/username"
)
//TODO os.Stdin should really be something like ioutil.Discard, but a Reader
kubectl
:=
cmd
.
New
Factory
(
nil
)
.
NewKubectlCommand
(
os
.
Stdin
,
ioutil
.
Discard
,
ioutil
.
Discard
)
kubectl
:=
cmd
.
New
KubectlCommand
(
cmdutil
.
NewFactory
(
nil
),
os
.
Stdin
,
ioutil
.
Discard
,
ioutil
.
Discard
)
genMarkdown
(
kubectl
,
""
,
docsDir
)
for
_
,
c
:=
range
kubectl
.
Commands
()
{
genMarkdown
(
c
,
"kubectl"
,
docsDir
)
...
...
cmd/genman/gen_kubectl_man.go
View file @
bb137f0b
...
...
@@ -25,6 +25,7 @@ import (
"strings"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd"
cmdutil
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/util"
"github.com/cpuguy83/go-md2man/mangen"
"github.com/russross/blackfriday"
"github.com/spf13/cobra"
...
...
@@ -63,7 +64,7 @@ func main() {
// regardless of where we run.
os
.
Setenv
(
"HOME"
,
"/home/username"
)
//TODO os.Stdin should really be something like ioutil.Discard, but a Reader
kubectl
:=
cmd
.
New
Factory
(
nil
)
.
NewKubectlCommand
(
os
.
Stdin
,
ioutil
.
Discard
,
ioutil
.
Discard
)
kubectl
:=
cmd
.
New
KubectlCommand
(
cmdutil
.
NewFactory
(
nil
),
os
.
Stdin
,
ioutil
.
Discard
,
ioutil
.
Discard
)
genMarkdown
(
kubectl
,
""
,
docsDir
)
for
_
,
c
:=
range
kubectl
.
Commands
()
{
genMarkdown
(
c
,
"kubectl"
,
docsDir
)
...
...
cmd/kubectl/kubectl.go
View file @
bb137f0b
...
...
@@ -21,11 +21,12 @@ import (
"runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd"
cmdutil
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/util"
)
func
main
()
{
runtime
.
GOMAXPROCS
(
runtime
.
NumCPU
())
cmd
:=
cmd
.
New
Factory
(
nil
)
.
NewKubectlCommand
(
os
.
Stdin
,
os
.
Stdout
,
os
.
Stderr
)
cmd
:=
cmd
.
New
KubectlCommand
(
cmdutil
.
NewFactory
(
nil
),
os
.
Stdin
,
os
.
Stdout
,
os
.
Stderr
)
if
err
:=
cmd
.
Execute
();
err
!=
nil
{
os
.
Exit
(
1
)
}
...
...
pkg/kubectl/cmd/apiversions.go
View file @
bb137f0b
...
...
@@ -23,10 +23,10 @@ import (
"github.com/spf13/cobra"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/util"
cmdutil
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/util"
)
func
(
f
*
Factory
)
NewCmdApiVersions
(
out
io
.
Writer
)
*
cobra
.
Command
{
func
NewCmdApiVersions
(
f
*
cmdutil
.
Factory
,
out
io
.
Writer
)
*
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
Use
:
"api-versions"
,
// apiversions is deprecated.
...
...
@@ -34,13 +34,13 @@ func (f *Factory) NewCmdApiVersions(out io.Writer) *cobra.Command {
Short
:
"Print available API versions."
,
Run
:
func
(
cmd
*
cobra
.
Command
,
args
[]
string
)
{
err
:=
RunApiVersions
(
f
,
out
)
util
.
CheckErr
(
err
)
cmd
util
.
CheckErr
(
err
)
},
}
return
cmd
}
func
RunApiVersions
(
f
*
Factory
,
out
io
.
Writer
)
error
{
func
RunApiVersions
(
f
*
cmdutil
.
Factory
,
out
io
.
Writer
)
error
{
if
os
.
Args
[
1
]
==
"apiversions"
{
printDeprecationWarning
(
"api-versions"
,
"apiversions"
)
}
...
...
pkg/kubectl/cmd/clusterinfo.go
View file @
bb137f0b
...
...
@@ -23,14 +23,14 @@ import (
"strings"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/util"
cmdutil
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/util"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/resource"
"github.com/daviddengcn/go-colortext"
"github.com/spf13/cobra"
)
func
(
f
*
Factory
)
NewCmdClusterInfo
(
out
io
.
Writer
)
*
cobra
.
Command
{
func
NewCmdClusterInfo
(
f
*
cmdutil
.
Factory
,
out
io
.
Writer
)
*
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
Use
:
"cluster-info"
,
// clusterinfo is deprecated.
...
...
@@ -39,13 +39,13 @@ func (f *Factory) NewCmdClusterInfo(out io.Writer) *cobra.Command {
Long
:
"Display addresses of the master and services with label kubernetes.io/cluster-service=true"
,
Run
:
func
(
cmd
*
cobra
.
Command
,
args
[]
string
)
{
err
:=
RunClusterInfo
(
f
,
out
,
cmd
)
util
.
CheckErr
(
err
)
cmd
util
.
CheckErr
(
err
)
},
}
return
cmd
}
func
RunClusterInfo
(
factory
*
Factory
,
out
io
.
Writer
,
cmd
*
cobra
.
Command
)
error
{
func
RunClusterInfo
(
factory
*
cmdutil
.
Factory
,
out
io
.
Writer
,
cmd
*
cobra
.
Command
)
error
{
if
os
.
Args
[
1
]
==
"clusterinfo"
{
printDeprecationWarning
(
"cluster-info"
,
"clusterinfo"
)
}
...
...
pkg/kubectl/cmd/cmd.go
View file @
bb137f0b
...
...
@@ -17,254 +17,17 @@ limitations under the License.
package
cmd
import
(
"fmt"
"io"
"os"
"strconv"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/meta"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/validation"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl"
cmdconfig
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/config"
cmdutil
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/util"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/resource"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/golang/glog"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)
const
(
FlagMatchBinaryVersion
=
"match-server-version"
)
// Factory provides abstractions that allow the Kubectl command to be extended across multiple types
// of resources and different API sets.
// TODO: make the functions interfaces
// TODO: pass the various interfaces on the factory directly into the command constructors (so the
// commands are decoupled from the factory).
type
Factory
struct
{
clients
*
clientCache
flags
*
pflag
.
FlagSet
// Returns interfaces for dealing with arbitrary runtime.Objects.
Object
func
()
(
meta
.
RESTMapper
,
runtime
.
ObjectTyper
)
// Returns a client for accessing Kubernetes resources or an error.
Client
func
()
(
*
client
.
Client
,
error
)
// Returns a client.Config for accessing the Kubernetes server.
ClientConfig
func
()
(
*
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
(
mapping
*
meta
.
RESTMapping
)
(
resource
.
RESTClient
,
error
)
// Returns a Describer for displaying the specified RESTMapping type or an error.
Describer
func
(
mapping
*
meta
.
RESTMapping
)
(
kubectl
.
Describer
,
error
)
// Returns a Printer for formatting objects of the given type or an error.
Printer
func
(
mapping
*
meta
.
RESTMapping
,
noHeaders
bool
)
(
kubectl
.
ResourcePrinter
,
error
)
// Returns a Resizer for changing the size of the specified RESTMapping type or an error
Resizer
func
(
mapping
*
meta
.
RESTMapping
)
(
kubectl
.
Resizer
,
error
)
// Returns a Reaper for gracefully shutting down resources.
Reaper
func
(
mapping
*
meta
.
RESTMapping
)
(
kubectl
.
Reaper
,
error
)
// PodSelectorForResource returns the pod selector associated with the provided resource name
// or an error.
PodSelectorForResource
func
(
mapping
*
meta
.
RESTMapping
,
namespace
,
name
string
)
(
string
,
error
)
// PortForResource returns the ports associated with the provided resource name or an error
PortsForResource
func
(
mapping
*
meta
.
RESTMapping
,
namespace
,
name
string
)
([]
string
,
error
)
// Returns a schema that can validate objects stored on disk.
Validator
func
()
(
validation
.
Schema
,
error
)
// Returns the default namespace to use in cases where no other namespace is specified
DefaultNamespace
func
()
(
string
,
error
)
}
func
getPorts
(
spec
api
.
PodSpec
)
[]
string
{
result
:=
[]
string
{}
for
_
,
container
:=
range
spec
.
Containers
{
for
_
,
port
:=
range
container
.
Ports
{
result
=
append
(
result
,
strconv
.
Itoa
(
port
.
ContainerPort
))
}
}
return
result
}
// NewFactory creates a factory with the default Kubernetes resources defined
// if optionalClientConfig is nil, then flags will be bound to a new clientcmd.ClientConfig.
// if optionalClientConfig is not nil, then this factory will make use of it.
func
NewFactory
(
optionalClientConfig
clientcmd
.
ClientConfig
)
*
Factory
{
mapper
:=
kubectl
.
ShortcutExpander
{
latest
.
RESTMapper
}
flags
:=
pflag
.
NewFlagSet
(
""
,
pflag
.
ContinueOnError
)
clientConfig
:=
optionalClientConfig
if
optionalClientConfig
==
nil
{
clientConfig
=
DefaultClientConfig
(
flags
)
}
clients
:=
&
clientCache
{
clients
:
make
(
map
[
string
]
*
client
.
Client
),
loader
:
clientConfig
,
}
return
&
Factory
{
clients
:
clients
,
flags
:
flags
,
Object
:
func
()
(
meta
.
RESTMapper
,
runtime
.
ObjectTyper
)
{
cfg
,
err
:=
clientConfig
.
ClientConfig
()
cmdutil
.
CheckErr
(
err
)
cmdApiVersion
:=
cfg
.
Version
return
kubectl
.
OutputVersionMapper
{
mapper
,
cmdApiVersion
},
api
.
Scheme
},
Client
:
func
()
(
*
client
.
Client
,
error
)
{
return
clients
.
ClientForVersion
(
""
)
},
ClientConfig
:
func
()
(
*
client
.
Config
,
error
)
{
return
clients
.
ClientConfigForVersion
(
""
)
},
RESTClient
:
func
(
mapping
*
meta
.
RESTMapping
)
(
resource
.
RESTClient
,
error
)
{
client
,
err
:=
clients
.
ClientForVersion
(
mapping
.
APIVersion
)
if
err
!=
nil
{
return
nil
,
err
}
return
client
.
RESTClient
,
nil
},
Describer
:
func
(
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
(
mapping
*
meta
.
RESTMapping
,
noHeaders
bool
)
(
kubectl
.
ResourcePrinter
,
error
)
{
return
kubectl
.
NewHumanReadablePrinter
(
noHeaders
),
nil
},
PodSelectorForResource
:
func
(
mapping
*
meta
.
RESTMapping
,
namespace
,
name
string
)
(
string
,
error
)
{
// TODO: replace with a swagger schema based approach (identify pod selector via schema introspection)
client
,
err
:=
clients
.
ClientForVersion
(
""
)
if
err
!=
nil
{
return
""
,
err
}
switch
mapping
.
Kind
{
case
"ReplicationController"
:
rc
,
err
:=
client
.
ReplicationControllers
(
namespace
)
.
Get
(
name
)
if
err
!=
nil
{
return
""
,
err
}
return
kubectl
.
MakeLabels
(
rc
.
Spec
.
Selector
),
nil
case
"Pod"
:
rc
,
err
:=
client
.
Pods
(
namespace
)
.
Get
(
name
)
if
err
!=
nil
{
return
""
,
err
}
if
len
(
rc
.
Labels
)
==
0
{
return
""
,
fmt
.
Errorf
(
"the pod has no labels and cannot be exposed"
)
}
return
kubectl
.
MakeLabels
(
rc
.
Labels
),
nil
case
"Service"
:
rc
,
err
:=
client
.
ReplicationControllers
(
namespace
)
.
Get
(
name
)
if
err
!=
nil
{
return
""
,
err
}
if
rc
.
Spec
.
Selector
==
nil
{
return
""
,
fmt
.
Errorf
(
"the service has no pod selector set"
)
}
return
kubectl
.
MakeLabels
(
rc
.
Spec
.
Selector
),
nil
default
:
return
""
,
fmt
.
Errorf
(
"it is not possible to get a pod selector from %s"
,
mapping
.
Kind
)
}
},
PortsForResource
:
func
(
mapping
*
meta
.
RESTMapping
,
namespace
,
name
string
)
([]
string
,
error
)
{
// TODO: replace with a swagger schema based approach (identify pod selector via schema introspection)
client
,
err
:=
clients
.
ClientForVersion
(
""
)
if
err
!=
nil
{
return
nil
,
err
}
switch
mapping
.
Kind
{
case
"ReplicationController"
:
rc
,
err
:=
client
.
ReplicationControllers
(
namespace
)
.
Get
(
name
)
if
err
!=
nil
{
return
nil
,
err
}
return
getPorts
(
rc
.
Spec
.
Template
.
Spec
),
nil
case
"Pod"
:
pod
,
err
:=
client
.
Pods
(
namespace
)
.
Get
(
name
)
if
err
!=
nil
{
return
nil
,
err
}
return
getPorts
(
pod
.
Spec
),
nil
default
:
return
nil
,
fmt
.
Errorf
(
"it is not possible to get ports from %s"
,
mapping
.
Kind
)
}
},
Resizer
:
func
(
mapping
*
meta
.
RESTMapping
)
(
kubectl
.
Resizer
,
error
)
{
client
,
err
:=
clients
.
ClientForVersion
(
mapping
.
APIVersion
)
if
err
!=
nil
{
return
nil
,
err
}
return
kubectl
.
ResizerFor
(
mapping
.
Kind
,
client
)
},
Reaper
:
func
(
mapping
*
meta
.
RESTMapping
)
(
kubectl
.
Reaper
,
error
)
{
client
,
err
:=
clients
.
ClientForVersion
(
mapping
.
APIVersion
)
if
err
!=
nil
{
return
nil
,
err
}
return
kubectl
.
ReaperFor
(
mapping
.
Kind
,
client
)
},
Validator
:
func
()
(
validation
.
Schema
,
error
)
{
if
flags
.
Lookup
(
"validate"
)
.
Value
.
String
()
==
"true"
{
client
,
err
:=
clients
.
ClientForVersion
(
""
)
if
err
!=
nil
{
return
nil
,
err
}
return
&
clientSwaggerSchema
{
client
,
api
.
Scheme
},
nil
}
return
validation
.
NullSchema
{},
nil
},
DefaultNamespace
:
func
()
(
string
,
error
)
{
return
clientConfig
.
Namespace
()
},
}
}
// 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
)
// This is necessary as github.com/spf13/cobra doesn't support "global"
// pflags currently. See https://github.com/spf13/cobra/issues/44.
util
.
AddPFlagSetToPFlagSet
(
pflag
.
CommandLine
,
flags
)
// Hack for global access to validation flag.
// TODO: Refactor out after configuration flag overhaul.
if
f
.
flags
.
Lookup
(
"validate"
)
==
nil
{
f
.
flags
.
Bool
(
"validate"
,
false
,
"If true, use a schema to validate the input before sending it"
)
}
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"
)
}
// NewKubectlCommand creates the `kubectl` command and its nested children.
func
(
f
*
Factory
)
NewKubectlCommand
(
in
io
.
Reader
,
out
,
err
io
.
Writer
)
*
cobra
.
Command
{
func
NewKubectlCommand
(
f
*
cmdutil
.
Factory
,
in
io
.
Reader
,
out
,
err
io
.
Writer
)
*
cobra
.
Command
{
// Parent command to which all subcommands are added.
cmds
:=
&
cobra
.
Command
{
Use
:
"kubectl"
,
...
...
@@ -277,223 +40,39 @@ Find more information at https://github.com/GoogleCloudPlatform/kubernetes.`,
f
.
BindFlags
(
cmds
.
PersistentFlags
())
cmds
.
AddCommand
(
f
.
NewCmdGet
(
out
))
cmds
.
AddCommand
(
f
.
NewCmdDescribe
(
out
))
cmds
.
AddCommand
(
f
.
NewCmdCreate
(
out
))
cmds
.
AddCommand
(
f
.
NewCmdUpdate
(
out
))
cmds
.
AddCommand
(
f
.
NewCmdDelete
(
out
))
cmds
.
AddCommand
(
NewCmdGet
(
f
,
out
))
cmds
.
AddCommand
(
NewCmdDescribe
(
f
,
out
))
cmds
.
AddCommand
(
NewCmdCreate
(
f
,
out
))
cmds
.
AddCommand
(
NewCmdUpdate
(
f
,
out
))
cmds
.
AddCommand
(
NewCmdDelete
(
f
,
out
))
cmds
.
AddCommand
(
NewCmdNamespace
(
out
))
cmds
.
AddCommand
(
f
.
NewCmdLog
(
out
))
cmds
.
AddCommand
(
f
.
NewCmdRollingUpdate
(
out
))
cmds
.
AddCommand
(
f
.
NewCmdResize
(
out
))
cmds
.
AddCommand
(
NewCmdLog
(
f
,
out
))
cmds
.
AddCommand
(
NewCmdRollingUpdate
(
f
,
out
))
cmds
.
AddCommand
(
NewCmdResize
(
f
,
out
))
cmds
.
AddCommand
(
f
.
NewCmdExec
(
in
,
out
,
err
))
cmds
.
AddCommand
(
f
.
NewCmdPortForward
(
))
cmds
.
AddCommand
(
f
.
NewCmdProxy
(
out
))
cmds
.
AddCommand
(
NewCmdExec
(
f
,
in
,
out
,
err
))
cmds
.
AddCommand
(
NewCmdPortForward
(
f
))
cmds
.
AddCommand
(
NewCmdProxy
(
f
,
out
))
cmds
.
AddCommand
(
f
.
NewCmdRunContainer
(
out
))
cmds
.
AddCommand
(
f
.
NewCmdStop
(
out
))
cmds
.
AddCommand
(
f
.
NewCmdExposeService
(
out
))
cmds
.
AddCommand
(
NewCmdRunContainer
(
f
,
out
))
cmds
.
AddCommand
(
NewCmdStop
(
f
,
out
))
cmds
.
AddCommand
(
NewCmdExposeService
(
f
,
out
))
cmds
.
AddCommand
(
f
.
NewCmdLabel
(
out
))
cmds
.
AddCommand
(
NewCmdLabel
(
f
,
out
))
cmds
.
AddCommand
(
cmdconfig
.
NewCmdConfig
(
out
))
cmds
.
AddCommand
(
f
.
NewCmdClusterInfo
(
out
))
cmds
.
AddCommand
(
f
.
NewCmdApiVersions
(
out
))
cmds
.
AddCommand
(
f
.
NewCmdVersion
(
out
))
cmds
.
AddCommand
(
cmdconfig
.
NewCmdConfig
(
f
,
out
))
cmds
.
AddCommand
(
NewCmdClusterInfo
(
f
,
out
))
cmds
.
AddCommand
(
NewCmdApiVersions
(
f
,
out
))
cmds
.
AddCommand
(
NewCmdVersion
(
f
,
out
))
return
cmds
}
// PrintObject prints an api object given command line flags to modify the output format
func
(
f
*
Factory
)
PrintObject
(
cmd
*
cobra
.
Command
,
obj
runtime
.
Object
,
out
io
.
Writer
)
error
{
mapper
,
_
:=
f
.
Object
()
_
,
kind
,
err
:=
api
.
Scheme
.
ObjectVersionAndKind
(
obj
)
if
err
!=
nil
{
return
err
}
mapping
,
err
:=
mapper
.
RESTMapping
(
kind
)
if
err
!=
nil
{
return
err
}
printer
,
err
:=
f
.
PrinterForMapping
(
cmd
,
mapping
)
if
err
!=
nil
{
return
err
}
return
printer
.
PrintObj
(
obj
,
out
)
}
// PrinterForMapping returns a printer suitable for displaying the provided resource type.
// Requires that printer flags have been added to cmd (see AddPrinterFlags).
func
(
f
*
Factory
)
PrinterForMapping
(
cmd
*
cobra
.
Command
,
mapping
*
meta
.
RESTMapping
)
(
kubectl
.
ResourcePrinter
,
error
)
{
printer
,
ok
,
err
:=
cmdutil
.
PrinterForCommand
(
cmd
)
if
err
!=
nil
{
return
nil
,
err
}
if
ok
{
clientConfig
,
err
:=
f
.
ClientConfig
()
if
err
!=
nil
{
return
nil
,
err
}
defaultVersion
:=
clientConfig
.
Version
version
:=
cmdutil
.
OutputVersion
(
cmd
,
defaultVersion
)
if
len
(
version
)
==
0
{
version
=
mapping
.
APIVersion
}
if
len
(
version
)
==
0
{
return
nil
,
fmt
.
Errorf
(
"you must specify an output-version when using this output format"
)
}
printer
=
kubectl
.
NewVersionedPrinter
(
printer
,
mapping
.
ObjectConvertor
,
version
)
}
else
{
printer
,
err
=
f
.
Printer
(
mapping
,
cmdutil
.
GetFlagBool
(
cmd
,
"no-headers"
))
if
err
!=
nil
{
return
nil
,
err
}
}
return
printer
,
nil
}
// ClientMapperForCommand returns a ClientMapper for the factory.
func
(
f
*
Factory
)
ClientMapperForCommand
()
resource
.
ClientMapper
{
return
resource
.
ClientMapperFunc
(
func
(
mapping
*
meta
.
RESTMapping
)
(
resource
.
RESTClient
,
error
)
{
return
f
.
RESTClient
(
mapping
)
})
}
// 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
// 2. EnvVarLocation
// 3. CurrentDirectoryLocation
// 4. HomeDirectoryLocation
// Empty filenames are ignored. Files with non-deserializable content produced errors.
// The first file to set a particular value or map key wins and the value or map key is never changed.
// This means that the first file to set CurrentContext will have its context preserved. It also means
// that if two files specify a "red-user", only values from the first file's red-user are used. Even
// non-conflicting entries from the second file's "red-user" are discarded.
// 2. Determine the context to use based on the first hit in this chain
// 1. command line argument - again, parsed from the command line, so it must be late bound
// 2. CurrentContext from the merged kubeconfig file
// 3. Empty is allowed at this stage
// 3. Determine the cluster info and auth info to use. At this point, we may or may not have a context. They
// are built based on the first hit in this chain. (run it twice, once for auth, once for cluster)
// 1. command line argument
// 2. If context is present, then use the context value
// 3. Empty is allowed
// 4. Determine the actual cluster info to use. At this point, we may or may not have a cluster info. Build
// each piece of the cluster info based on the chain:
// 1. command line argument
// 2. If cluster info is present and a value for the attribute is present, use it.
// 3. If you don't have a server location, bail.
// 5. Auth info is build using the same rules as cluster info, EXCEPT that you can only have one authentication
// technique per auth info. The following conditions result in an error:
// 1. If there are two conflicting techniques specified from the command line, fail.
// 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
DefaultClientConfig
(
flags
*
pflag
.
FlagSet
)
clientcmd
.
ClientConfig
{
loadingRules
:=
clientcmd
.
NewDefaultClientConfigLoadingRules
()
flags
.
StringVar
(
&
loadingRules
.
ExplicitPath
,
"kubeconfig"
,
""
,
"Path to the kubeconfig file to use for CLI requests."
)
overrides
:=
&
clientcmd
.
ConfigOverrides
{}
flagNames
:=
clientcmd
.
RecommendedConfigOverrideFlags
(
""
)
// short flagnames are disabled by default. These are here for compatibility with existing scripts
flagNames
.
AuthOverrideFlags
.
AuthPathShort
=
"a"
flagNames
.
ClusterOverrideFlags
.
APIServerShort
=
"s"
clientcmd
.
BindOverrideFlags
(
overrides
,
flags
,
flagNames
)
clientConfig
:=
clientcmd
.
NewInteractiveDeferredLoadingClientConfig
(
loadingRules
,
overrides
,
os
.
Stdin
)
return
clientConfig
}
func
runHelp
(
cmd
*
cobra
.
Command
,
args
[]
string
)
{
cmd
.
Help
()
}
type
clientSwaggerSchema
struct
{
c
*
client
.
Client
t
runtime
.
ObjectTyper
}
func
(
c
*
clientSwaggerSchema
)
ValidateBytes
(
data
[]
byte
)
error
{
version
,
_
,
err
:=
c
.
t
.
DataVersionAndKind
(
data
)
if
err
!=
nil
{
return
err
}
schemaData
,
err
:=
c
.
c
.
RESTClient
.
Get
()
.
AbsPath
(
"/swaggerapi/api"
,
version
)
.
Do
()
.
Raw
()
if
err
!=
nil
{
return
err
}
schema
,
err
:=
validation
.
NewSwaggerSchemaFromBytes
(
schemaData
)
if
err
!=
nil
{
return
err
}
return
schema
.
ValidateBytes
(
data
)
}
// 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: have a better config copy method
config
:=
*
c
.
defaultConfig
if
len
(
version
)
!=
0
{
config
.
Version
=
version
}
client
.
SetKubernetesDefaults
(
&
config
)
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
client
,
ok
:=
c
.
clients
[
config
.
Version
];
ok
{
return
client
,
nil
}
client
,
err
:=
client
.
New
(
config
)
if
err
!=
nil
{
return
nil
,
err
}
c
.
clients
[
config
.
Version
]
=
client
return
client
,
nil
}
func
printDeprecationWarning
(
command
,
alias
string
)
{
glog
.
Warningf
(
"%s is DEPRECATED and will be removed in a future version. Use %s instead."
,
alias
,
command
)
}
pkg/kubectl/cmd/cmd_test.go
View file @
bb137f0b
...
...
@@ -30,6 +30,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/validation"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl"
cmdutil
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/util"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/resource"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
)
...
...
@@ -109,14 +110,14 @@ type testFactory struct {
Err
error
}
func
NewTestFactory
()
(
*
Factory
,
*
testFactory
,
runtime
.
Codec
)
{
func
NewTestFactory
()
(
*
cmdutil
.
Factory
,
*
testFactory
,
runtime
.
Codec
)
{
scheme
,
mapper
,
codec
:=
newExternalScheme
()
t
:=
&
testFactory
{
Validator
:
validation
.
NullSchema
{},
Mapper
:
mapper
,
Typer
:
scheme
,
}
return
&
Factory
{
return
&
cmdutil
.
Factory
{
Object
:
func
()
(
meta
.
RESTMapper
,
runtime
.
ObjectTyper
)
{
return
t
.
Mapper
,
t
.
Typer
},
...
...
@@ -141,11 +142,11 @@ func NewTestFactory() (*Factory, *testFactory, runtime.Codec) {
},
t
,
codec
}
func
NewAPIFactory
()
(
*
Factory
,
*
testFactory
,
runtime
.
Codec
)
{
func
NewAPIFactory
()
(
*
cmdutil
.
Factory
,
*
testFactory
,
runtime
.
Codec
)
{
t
:=
&
testFactory
{
Validator
:
validation
.
NullSchema
{},
}
return
&
Factory
{
return
&
cmdutil
.
Factory
{
Object
:
func
()
(
meta
.
RESTMapper
,
runtime
.
ObjectTyper
)
{
return
latest
.
RESTMapper
,
api
.
Scheme
},
...
...
@@ -180,7 +181,7 @@ func stringBody(body string) io.ReadCloser {
// Verify that resource.RESTClients constructed from a factory respect mapping.APIVersion
func
TestClientVersions
(
t
*
testing
.
T
)
{
f
:=
NewFactory
(
nil
)
f
:=
cmdutil
.
NewFactory
(
nil
)
versions
:=
[]
string
{
"v1beta1"
,
...
...
@@ -209,7 +210,7 @@ func ExamplePrintReplicationController() {
Codec
:
codec
,
Client
:
nil
,
}
cmd
:=
f
.
NewCmdRunContainer
(
os
.
Stdout
)
cmd
:=
NewCmdRunContainer
(
f
,
os
.
Stdout
)
ctrl
:=
&
api
.
ReplicationController
{
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
"foo"
,
...
...
pkg/kubectl/cmd/config/config.go
View file @
bb137f0b
...
...
@@ -27,6 +27,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd"
clientcmdapi
"github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd/api"
cmdutil
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/util"
)
type
pathOptions
struct
{
...
...
@@ -36,7 +37,7 @@ type pathOptions struct {
specifiedFile
string
}
func
NewCmdConfig
(
out
io
.
Writer
)
*
cobra
.
Command
{
func
NewCmdConfig
(
f
*
cmdutil
.
Factory
,
out
io
.
Writer
)
*
cobra
.
Command
{
pathOptions
:=
&
pathOptions
{}
cmd
:=
&
cobra
.
Command
{
...
...
pkg/kubectl/cmd/config/config_test.go
View file @
bb137f0b
...
...
@@ -26,6 +26,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd"
clientcmdapi
"github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd/api"
cmdutil
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/util"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
)
...
...
@@ -618,8 +619,9 @@ func testConfigCommand(args []string, startingConfig clientcmdapi.Config) (strin
argsToUse
=
append
(
argsToUse
,
args
...
)
buf
:=
bytes
.
NewBuffer
([]
byte
{})
f
:=
cmdutil
.
NewFactory
(
nil
)
cmd
:=
NewCmdConfig
(
buf
)
cmd
:=
NewCmdConfig
(
f
,
buf
)
cmd
.
SetArgs
(
argsToUse
)
cmd
.
Execute
()
...
...
pkg/kubectl/cmd/create.go
View file @
bb137f0b
...
...
@@ -38,7 +38,7 @@ $ kubectl create -f pod.json
$ cat pod.json | kubectl create -f -`
)
func
(
f
*
Factory
)
NewCmdCreate
(
out
io
.
Writer
)
*
cobra
.
Command
{
func
NewCmdCreate
(
f
*
cmdutil
.
Factory
,
out
io
.
Writer
)
*
cobra
.
Command
{
var
filenames
util
.
StringList
cmd
:=
&
cobra
.
Command
{
Use
:
"create -f FILENAME"
,
...
...
@@ -61,7 +61,7 @@ func ValidateArgs(cmd *cobra.Command, args []string) error {
return
nil
}
func
RunCreate
(
f
*
Factory
,
out
io
.
Writer
,
filenames
util
.
StringList
)
error
{
func
RunCreate
(
f
*
cmdutil
.
Factory
,
out
io
.
Writer
,
filenames
util
.
StringList
)
error
{
schema
,
err
:=
f
.
Validator
()
if
err
!=
nil
{
return
err
...
...
pkg/kubectl/cmd/create_test.go
View file @
bb137f0b
...
...
@@ -28,7 +28,7 @@ func TestExtraArgsFail(t *testing.T) {
buf
:=
bytes
.
NewBuffer
([]
byte
{})
f
,
_
,
_
:=
NewAPIFactory
()
c
:=
f
.
NewCmdCreate
(
buf
)
c
:=
NewCmdCreate
(
f
,
buf
)
if
ValidateArgs
(
c
,
[]
string
{
"rc"
})
==
nil
{
t
.
Errorf
(
"unexpected non-error"
)
}
...
...
@@ -55,7 +55,7 @@ func TestCreateObject(t *testing.T) {
tf
.
Namespace
=
"test"
buf
:=
bytes
.
NewBuffer
([]
byte
{})
cmd
:=
f
.
NewCmdCreate
(
buf
)
cmd
:=
NewCmdCreate
(
f
,
buf
)
cmd
.
Flags
()
.
Set
(
"filename"
,
"../../../examples/guestbook/redis-master-controller.json"
)
cmd
.
Run
(
cmd
,
[]
string
{})
...
...
@@ -87,7 +87,7 @@ func TestCreateMultipleObject(t *testing.T) {
tf
.
Namespace
=
"test"
buf
:=
bytes
.
NewBuffer
([]
byte
{})
cmd
:=
f
.
NewCmdCreate
(
buf
)
cmd
:=
NewCmdCreate
(
f
,
buf
)
cmd
.
Flags
()
.
Set
(
"filename"
,
"../../../examples/guestbook/redis-master-controller.json"
)
cmd
.
Flags
()
.
Set
(
"filename"
,
"../../../examples/guestbook/frontend-service.json"
)
cmd
.
Run
(
cmd
,
[]
string
{})
...
...
@@ -121,7 +121,7 @@ func TestCreateDirectory(t *testing.T) {
tf
.
Namespace
=
"test"
buf
:=
bytes
.
NewBuffer
([]
byte
{})
cmd
:=
f
.
NewCmdCreate
(
buf
)
cmd
:=
NewCmdCreate
(
f
,
buf
)
cmd
.
Flags
()
.
Set
(
"filename"
,
"../../../examples/guestbook"
)
cmd
.
Run
(
cmd
,
[]
string
{})
...
...
pkg/kubectl/cmd/delete.go
View file @
bb137f0b
...
...
@@ -55,7 +55,7 @@ $ kubectl delete pod 1234-56-7890-234234-456456
$ kubectl delete pods --all`
)
func
(
f
*
Factory
)
NewCmdDelete
(
out
io
.
Writer
)
*
cobra
.
Command
{
func
NewCmdDelete
(
f
*
cmdutil
.
Factory
,
out
io
.
Writer
)
*
cobra
.
Command
{
var
filenames
util
.
StringList
cmd
:=
&
cobra
.
Command
{
Use
:
"delete ([-f FILENAME] | (RESOURCE [(ID | -l label | --all)]"
,
...
...
@@ -73,7 +73,7 @@ func (f *Factory) NewCmdDelete(out io.Writer) *cobra.Command {
return
cmd
}
func
RunDelete
(
f
*
Factory
,
out
io
.
Writer
,
cmd
*
cobra
.
Command
,
args
[]
string
,
filenames
util
.
StringList
)
error
{
func
RunDelete
(
f
*
cmdutil
.
Factory
,
out
io
.
Writer
,
cmd
*
cobra
.
Command
,
args
[]
string
,
filenames
util
.
StringList
)
error
{
cmdNamespace
,
err
:=
f
.
DefaultNamespace
()
if
err
!=
nil
{
return
err
...
...
pkg/kubectl/cmd/delete_test.go
View file @
bb137f0b
...
...
@@ -47,7 +47,7 @@ func TestDeleteObject(t *testing.T) {
tf
.
Namespace
=
"test"
buf
:=
bytes
.
NewBuffer
([]
byte
{})
cmd
:=
f
.
NewCmdDelete
(
buf
)
cmd
:=
NewCmdDelete
(
f
,
buf
)
cmd
.
Flags
()
.
Set
(
"filename"
,
"../../../examples/guestbook/redis-master-controller.json"
)
cmd
.
Run
(
cmd
,
[]
string
{})
...
...
@@ -75,7 +75,7 @@ func TestDeleteObjectIgnoreNotFound(t *testing.T) {
tf
.
Namespace
=
"test"
buf
:=
bytes
.
NewBuffer
([]
byte
{})
cmd
:=
f
.
NewCmdDelete
(
buf
)
cmd
:=
NewCmdDelete
(
f
,
buf
)
cmd
.
Flags
()
.
Set
(
"filename"
,
"../../../examples/guestbook/redis-master-controller.json"
)
cmd
.
Run
(
cmd
,
[]
string
{})
...
...
@@ -106,7 +106,7 @@ func TestDeleteMultipleObject(t *testing.T) {
tf
.
Namespace
=
"test"
buf
:=
bytes
.
NewBuffer
([]
byte
{})
cmd
:=
f
.
NewCmdDelete
(
buf
)
cmd
:=
NewCmdDelete
(
f
,
buf
)
cmd
.
Flags
()
.
Set
(
"filename"
,
"../../../examples/guestbook/redis-master-controller.json"
)
cmd
.
Flags
()
.
Set
(
"filename"
,
"../../../examples/guestbook/frontend-service.json"
)
cmd
.
Run
(
cmd
,
[]
string
{})
...
...
@@ -138,7 +138,7 @@ func TestDeleteMultipleObjectIgnoreMissing(t *testing.T) {
tf
.
Namespace
=
"test"
buf
:=
bytes
.
NewBuffer
([]
byte
{})
cmd
:=
f
.
NewCmdDelete
(
buf
)
cmd
:=
NewCmdDelete
(
f
,
buf
)
cmd
.
Flags
()
.
Set
(
"filename"
,
"../../../examples/guestbook/redis-master-controller.json"
)
cmd
.
Flags
()
.
Set
(
"filename"
,
"../../../examples/guestbook/frontend-service.json"
)
cmd
.
Run
(
cmd
,
[]
string
{})
...
...
@@ -170,7 +170,7 @@ func TestDeleteDirectory(t *testing.T) {
tf
.
Namespace
=
"test"
buf
:=
bytes
.
NewBuffer
([]
byte
{})
cmd
:=
f
.
NewCmdDelete
(
buf
)
cmd
:=
NewCmdDelete
(
f
,
buf
)
cmd
.
Flags
()
.
Set
(
"filename"
,
"../../../examples/guestbook"
)
cmd
.
Run
(
cmd
,
[]
string
{})
...
...
@@ -211,7 +211,7 @@ func TestDeleteMultipleSelector(t *testing.T) {
tf
.
Namespace
=
"test"
buf
:=
bytes
.
NewBuffer
([]
byte
{})
cmd
:=
f
.
NewCmdDelete
(
buf
)
cmd
:=
NewCmdDelete
(
f
,
buf
)
cmd
.
Flags
()
.
Set
(
"selector"
,
"a=b"
)
cmd
.
Run
(
cmd
,
[]
string
{
"pods,services"
})
...
...
pkg/kubectl/cmd/describe.go
View file @
bb137f0b
...
...
@@ -20,11 +20,11 @@ import (
"fmt"
"io"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/util"
cmdutil
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/util"
"github.com/spf13/cobra"
)
func
(
f
*
Factory
)
NewCmdDescribe
(
out
io
.
Writer
)
*
cobra
.
Command
{
func
NewCmdDescribe
(
f
*
cmdutil
.
Factory
,
out
io
.
Writer
)
*
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
Use
:
"describe RESOURCE ID"
,
Short
:
"Show details of a specific resource"
,
...
...
@@ -34,13 +34,13 @@ This command joins many API calls together to form a detailed description of a
given resource.`
,
Run
:
func
(
cmd
*
cobra
.
Command
,
args
[]
string
)
{
err
:=
RunDescribe
(
f
,
out
,
cmd
,
args
)
util
.
CheckErr
(
err
)
cmd
util
.
CheckErr
(
err
)
},
}
return
cmd
}
func
RunDescribe
(
f
*
Factory
,
out
io
.
Writer
,
cmd
*
cobra
.
Command
,
args
[]
string
)
error
{
func
RunDescribe
(
f
*
cmdutil
.
Factory
,
out
io
.
Writer
,
cmd
*
cobra
.
Command
,
args
[]
string
)
error
{
cmdNamespace
,
err
:=
f
.
DefaultNamespace
()
if
err
!=
nil
{
return
err
...
...
@@ -48,7 +48,7 @@ func RunDescribe(f *Factory, out io.Writer, cmd *cobra.Command, args []string) e
mapper
,
_
:=
f
.
Object
()
// TODO: use resource.Builder instead
mapping
,
namespace
,
name
,
err
:=
util
.
ResourceFromArgs
(
cmd
,
args
,
mapper
,
cmdNamespace
)
mapping
,
namespace
,
name
,
err
:=
cmd
util
.
ResourceFromArgs
(
cmd
,
args
,
mapper
,
cmdNamespace
)
if
err
!=
nil
{
return
err
}
...
...
pkg/kubectl/cmd/describe_test.go
View file @
bb137f0b
...
...
@@ -37,7 +37,7 @@ func TestDescribeUnknownSchemaObject(t *testing.T) {
tf
.
Namespace
=
"non-default"
buf
:=
bytes
.
NewBuffer
([]
byte
{})
cmd
:=
f
.
NewCmdDescribe
(
buf
)
cmd
:=
NewCmdDescribe
(
f
,
buf
)
cmd
.
Run
(
cmd
,
[]
string
{
"type"
,
"foo"
})
if
d
.
Name
!=
"foo"
||
d
.
Namespace
!=
"non-default"
{
...
...
pkg/kubectl/cmd/exec.go
View file @
bb137f0b
...
...
@@ -24,7 +24,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client/remotecommand"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/util"
cmdutil
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/util"
"github.com/docker/docker/pkg/term"
"github.com/golang/glog"
"github.com/spf13/cobra"
...
...
@@ -38,7 +38,7 @@ $ kubectl exec -p 123456-7890 -c ruby-container date
$ kubectl exec -p 123456-7890 -c ruby-container -i -t -- bash -il`
)
func
(
f
*
Factory
)
NewCmdExec
(
cmdIn
io
.
Reader
,
cmdOut
,
cmdErr
io
.
Writer
)
*
cobra
.
Command
{
func
NewCmdExec
(
f
*
cmdutil
.
Factory
,
cmdIn
io
.
Reader
,
cmdOut
,
cmdErr
io
.
Writer
)
*
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
Use
:
"exec -p POD -c CONTAINER -- COMMAND [args...]"
,
Short
:
"Execute a command in a container."
,
...
...
@@ -46,7 +46,7 @@ func (f *Factory) NewCmdExec(cmdIn io.Reader, cmdOut, cmdErr io.Writer) *cobra.C
Example
:
exec_example
,
Run
:
func
(
cmd
*
cobra
.
Command
,
args
[]
string
)
{
err
:=
RunExec
(
f
,
cmdIn
,
cmdOut
,
cmdErr
,
cmd
,
args
)
util
.
CheckErr
(
err
)
cmd
util
.
CheckErr
(
err
)
},
}
cmd
.
Flags
()
.
StringP
(
"pod"
,
"p"
,
""
,
"Pod name"
)
...
...
@@ -57,14 +57,14 @@ func (f *Factory) NewCmdExec(cmdIn io.Reader, cmdOut, cmdErr io.Writer) *cobra.C
return
cmd
}
func
RunExec
(
f
*
Factory
,
cmdIn
io
.
Reader
,
cmdOut
,
cmdErr
io
.
Writer
,
cmd
*
cobra
.
Command
,
args
[]
string
)
error
{
podName
:=
util
.
GetFlagString
(
cmd
,
"pod"
)
func
RunExec
(
f
*
cmdutil
.
Factory
,
cmdIn
io
.
Reader
,
cmdOut
,
cmdErr
io
.
Writer
,
cmd
*
cobra
.
Command
,
args
[]
string
)
error
{
podName
:=
cmd
util
.
GetFlagString
(
cmd
,
"pod"
)
if
len
(
podName
)
==
0
{
return
util
.
UsageError
(
cmd
,
"POD is required for exec"
)
return
cmd
util
.
UsageError
(
cmd
,
"POD is required for exec"
)
}
if
len
(
args
)
<
1
{
return
util
.
UsageError
(
cmd
,
"COMMAND is required for exec"
)
return
cmd
util
.
UsageError
(
cmd
,
"COMMAND is required for exec"
)
}
namespace
,
err
:=
f
.
DefaultNamespace
()
...
...
@@ -86,14 +86,14 @@ func RunExec(f *Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer, cmd *cobra.C
glog
.
Fatalf
(
"Unable to execute command because pod is not running. Current status=%v"
,
pod
.
Status
.
Phase
)
}
containerName
:=
util
.
GetFlagString
(
cmd
,
"container"
)
containerName
:=
cmd
util
.
GetFlagString
(
cmd
,
"container"
)
if
len
(
containerName
)
==
0
{
containerName
=
pod
.
Spec
.
Containers
[
0
]
.
Name
}
var
stdin
io
.
Reader
tty
:=
util
.
GetFlagBool
(
cmd
,
"tty"
)
if
util
.
GetFlagBool
(
cmd
,
"stdin"
)
{
tty
:=
cmd
util
.
GetFlagBool
(
cmd
,
"tty"
)
if
cmd
util
.
GetFlagBool
(
cmd
,
"stdin"
)
{
stdin
=
cmdIn
if
tty
{
if
file
,
ok
:=
cmdIn
.
(
*
os
.
File
);
ok
{
...
...
pkg/kubectl/cmd/expose.go
View file @
bb137f0b
...
...
@@ -22,7 +22,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/util"
cmdutil
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/util"
"github.com/spf13/cobra"
)
...
...
@@ -42,7 +42,7 @@ $ kubectl expose service nginx --port=443 --target-port=8443 --service-name=ngin
$ kubectl expose streamer --port=4100 --protocol=udp --service-name=video-stream`
)
func
(
f
*
Factory
)
NewCmdExposeService
(
out
io
.
Writer
)
*
cobra
.
Command
{
func
NewCmdExposeService
(
f
*
cmdutil
.
Factory
,
out
io
.
Writer
)
*
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
Use
:
"expose RESOURCE NAME --port=port [--protocol=TCP|UDP] [--target-port=number-or-name] [--service-name=name] [--public-ip=ip] [--create-external-load-balancer=bool]"
,
Short
:
"Take a replicated application and expose it as Kubernetes Service"
,
...
...
@@ -50,10 +50,10 @@ func (f *Factory) NewCmdExposeService(out io.Writer) *cobra.Command {
Example
:
expose_example
,
Run
:
func
(
cmd
*
cobra
.
Command
,
args
[]
string
)
{
err
:=
RunExpose
(
f
,
out
,
cmd
,
args
)
util
.
CheckErr
(
err
)
cmd
util
.
CheckErr
(
err
)
},
}
util
.
AddPrinterFlags
(
cmd
)
cmd
util
.
AddPrinterFlags
(
cmd
)
cmd
.
Flags
()
.
String
(
"generator"
,
"service/v1"
,
"The name of the API generator to use. Default is 'service/v1'."
)
cmd
.
Flags
()
.
String
(
"protocol"
,
"TCP"
,
"The network protocol for the service to be created. Default is 'tcp'."
)
cmd
.
Flags
()
.
Int
(
"port"
,
-
1
,
"The port that the service should serve on. Required."
)
...
...
@@ -69,13 +69,13 @@ func (f *Factory) NewCmdExposeService(out io.Writer) *cobra.Command {
return
cmd
}
func
RunExpose
(
f
*
Factory
,
out
io
.
Writer
,
cmd
*
cobra
.
Command
,
args
[]
string
)
error
{
func
RunExpose
(
f
*
cmdutil
.
Factory
,
out
io
.
Writer
,
cmd
*
cobra
.
Command
,
args
[]
string
)
error
{
var
name
,
resource
string
switch
l
:=
len
(
args
);
{
case
l
==
2
:
resource
,
name
=
args
[
0
],
args
[
1
]
default
:
return
util
.
UsageError
(
cmd
,
"the type and name of a resource to expose are required arguments"
)
return
cmd
util
.
UsageError
(
cmd
,
"the type and name of a resource to expose are required arguments"
)
}
namespace
,
err
:=
f
.
DefaultNamespace
()
...
...
@@ -87,20 +87,20 @@ func RunExpose(f *Factory, out io.Writer, cmd *cobra.Command, args []string) err
return
err
}
generatorName
:=
util
.
GetFlagString
(
cmd
,
"generator"
)
generatorName
:=
cmd
util
.
GetFlagString
(
cmd
,
"generator"
)
generator
,
found
:=
kubectl
.
Generators
[
generatorName
]
if
!
found
{
return
util
.
UsageError
(
cmd
,
fmt
.
Sprintf
(
"generator %q not found."
,
generator
))
return
cmd
util
.
UsageError
(
cmd
,
fmt
.
Sprintf
(
"generator %q not found."
,
generator
))
}
names
:=
generator
.
ParamNames
()
params
:=
kubectl
.
MakeParams
(
cmd
,
names
)
if
len
(
util
.
GetFlagString
(
cmd
,
"service-name"
))
==
0
{
if
len
(
cmd
util
.
GetFlagString
(
cmd
,
"service-name"
))
==
0
{
params
[
"name"
]
=
name
}
else
{
params
[
"name"
]
=
util
.
GetFlagString
(
cmd
,
"service-name"
)
params
[
"name"
]
=
cmd
util
.
GetFlagString
(
cmd
,
"service-name"
)
}
if
s
,
found
:=
params
[
"selector"
];
!
found
||
len
(
s
)
==
0
||
util
.
GetFlagInt
(
cmd
,
"port"
)
<
1
{
if
s
,
found
:=
params
[
"selector"
];
!
found
||
len
(
s
)
==
0
||
cmd
util
.
GetFlagInt
(
cmd
,
"port"
)
<
1
{
mapper
,
_
:=
f
.
Object
()
v
,
k
,
err
:=
mapper
.
VersionAndKindForResource
(
resource
)
if
err
!=
nil
{
...
...
@@ -117,21 +117,21 @@ func RunExpose(f *Factory, out io.Writer, cmd *cobra.Command, args []string) err
}
params
[
"selector"
]
=
s
}
if
util
.
GetFlagInt
(
cmd
,
"port"
)
<
0
{
if
cmd
util
.
GetFlagInt
(
cmd
,
"port"
)
<
0
{
ports
,
err
:=
f
.
PortsForResource
(
mapping
,
namespace
,
name
)
if
err
!=
nil
{
return
err
}
if
len
(
ports
)
==
0
{
return
util
.
UsageError
(
cmd
,
"couldn't find a suitable port via --port flag or introspection"
)
return
cmd
util
.
UsageError
(
cmd
,
"couldn't find a suitable port via --port flag or introspection"
)
}
if
len
(
ports
)
>
1
{
return
util
.
UsageError
(
cmd
,
"more than one port to choose from, please explicitly specify a port using the --port flag."
)
return
cmd
util
.
UsageError
(
cmd
,
"more than one port to choose from, please explicitly specify a port using the --port flag."
)
}
params
[
"port"
]
=
ports
[
0
]
}
}
if
util
.
GetFlagBool
(
cmd
,
"create-external-load-balancer"
)
{
if
cmd
util
.
GetFlagBool
(
cmd
,
"create-external-load-balancer"
)
{
params
[
"create-external-load-balancer"
]
=
"true"
}
...
...
@@ -145,16 +145,16 @@ func RunExpose(f *Factory, out io.Writer, cmd *cobra.Command, args []string) err
return
err
}
inline
:=
util
.
GetFlagString
(
cmd
,
"overrides"
)
inline
:=
cmd
util
.
GetFlagString
(
cmd
,
"overrides"
)
if
len
(
inline
)
>
0
{
service
,
err
=
util
.
Merge
(
service
,
inline
,
"Service"
)
service
,
err
=
cmd
util
.
Merge
(
service
,
inline
,
"Service"
)
if
err
!=
nil
{
return
err
}
}
// TODO: extract this flag to a central location, when such a location exists.
if
!
util
.
GetFlagBool
(
cmd
,
"dry-run"
)
{
if
!
cmd
util
.
GetFlagBool
(
cmd
,
"dry-run"
)
{
service
,
err
=
client
.
Services
(
namespace
)
.
Create
(
service
.
(
*
api
.
Service
))
if
err
!=
nil
{
return
err
...
...
pkg/kubectl/cmd/get.go
View file @
bb137f0b
...
...
@@ -23,7 +23,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/util"
cmdutil
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/util"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/resource"
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
...
...
@@ -59,7 +59,7 @@ $ kubectl get rc/web service/frontend pods/web-pod-13je7`
// NewCmdGet creates a command object for the generic "get" action, which
// retrieves one or more resources from a server.
func
(
f
*
Factory
)
NewCmdGet
(
out
io
.
Writer
)
*
cobra
.
Command
{
func
NewCmdGet
(
f
*
cmdutil
.
Factory
,
out
io
.
Writer
)
*
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
Use
:
"get [(-o|--output=)json|yaml|template|...] (RESOURCE [NAME] | RESOURCE/NAME ...)"
,
Short
:
"Display one or many resources"
,
...
...
@@ -67,10 +67,10 @@ func (f *Factory) NewCmdGet(out io.Writer) *cobra.Command {
Example
:
get_example
,
Run
:
func
(
cmd
*
cobra
.
Command
,
args
[]
string
)
{
err
:=
RunGet
(
f
,
out
,
cmd
,
args
)
util
.
CheckErr
(
err
)
cmd
util
.
CheckErr
(
err
)
},
}
util
.
AddPrinterFlags
(
cmd
)
cmd
util
.
AddPrinterFlags
(
cmd
)
cmd
.
Flags
()
.
StringP
(
"selector"
,
"l"
,
""
,
"Selector (label query) to filter on"
)
cmd
.
Flags
()
.
BoolP
(
"watch"
,
"w"
,
false
,
"After listing/getting the requested object, watch for changes."
)
cmd
.
Flags
()
.
Bool
(
"watch-only"
,
false
,
"Watch for changes to the requested object(s), without listing/getting first."
)
...
...
@@ -79,8 +79,8 @@ func (f *Factory) NewCmdGet(out io.Writer) *cobra.Command {
// RunGet implements the generic Get command
// TODO: convert all direct flag accessors to a struct and pass that instead of cmd
func
RunGet
(
f
*
Factory
,
out
io
.
Writer
,
cmd
*
cobra
.
Command
,
args
[]
string
)
error
{
selector
:=
util
.
GetFlagString
(
cmd
,
"selector"
)
func
RunGet
(
f
*
cmdutil
.
Factory
,
out
io
.
Writer
,
cmd
*
cobra
.
Command
,
args
[]
string
)
error
{
selector
:=
cmd
util
.
GetFlagString
(
cmd
,
"selector"
)
mapper
,
typer
:=
f
.
Object
()
cmdNamespace
,
err
:=
f
.
DefaultNamespace
()
...
...
@@ -89,7 +89,7 @@ func RunGet(f *Factory, out io.Writer, cmd *cobra.Command, args []string) error
}
// handle watch separately since we cannot watch multiple resource types
isWatch
,
isWatchOnly
:=
util
.
GetFlagBool
(
cmd
,
"watch"
),
util
.
GetFlagBool
(
cmd
,
"watch-only"
)
isWatch
,
isWatchOnly
:=
cmdutil
.
GetFlagBool
(
cmd
,
"watch"
),
cmd
util
.
GetFlagBool
(
cmd
,
"watch-only"
)
if
isWatch
||
isWatchOnly
{
r
:=
resource
.
NewBuilder
(
mapper
,
typer
,
f
.
ClientMapperForCommand
())
.
NamespaceParam
(
cmdNamespace
)
.
DefaultNamespace
()
.
...
...
@@ -146,7 +146,7 @@ func RunGet(f *Factory, out io.Writer, cmd *cobra.Command, args []string) error
ResourceTypeOrNameArgs
(
true
,
args
...
)
.
ContinueOnError
()
.
Latest
()
printer
,
generic
,
err
:=
util
.
PrinterForCommand
(
cmd
)
printer
,
generic
,
err
:=
cmd
util
.
PrinterForCommand
(
cmd
)
if
err
!=
nil
{
return
err
}
...
...
@@ -159,7 +159,7 @@ func RunGet(f *Factory, out io.Writer, cmd *cobra.Command, args []string) error
defaultVersion
:=
clientConfig
.
Version
// the outermost object will be converted to the output-version
version
:=
util
.
OutputVersion
(
cmd
,
defaultVersion
)
version
:=
cmd
util
.
OutputVersion
(
cmd
,
defaultVersion
)
r
:=
b
.
Flatten
()
.
Do
()
obj
,
err
:=
r
.
Object
()
...
...
pkg/kubectl/cmd/get_test.go
View file @
bb137f0b
...
...
@@ -99,7 +99,7 @@ func TestGetUnknownSchemaObject(t *testing.T) {
tf
.
ClientConfig
=
&
client
.
Config
{
Version
:
latest
.
Version
}
buf
:=
bytes
.
NewBuffer
([]
byte
{})
cmd
:=
f
.
NewCmdGet
(
buf
)
cmd
:=
NewCmdGet
(
f
,
buf
)
cmd
.
SetOutput
(
buf
)
cmd
.
Run
(
cmd
,
[]
string
{
"type"
,
"foo"
})
...
...
@@ -128,7 +128,7 @@ func TestGetSchemaObject(t *testing.T) {
tf
.
ClientConfig
=
&
client
.
Config
{
Version
:
"v1beta3"
}
buf
:=
bytes
.
NewBuffer
([]
byte
{})
cmd
:=
f
.
NewCmdGet
(
buf
)
cmd
:=
NewCmdGet
(
f
,
buf
)
cmd
.
Run
(
cmd
,
[]
string
{
"replicationcontrollers"
,
"foo"
})
if
!
strings
.
Contains
(
buf
.
String
(),
"
\"
foo
\"
"
)
{
...
...
@@ -148,7 +148,7 @@ func TestGetObjects(t *testing.T) {
tf
.
Namespace
=
"test"
buf
:=
bytes
.
NewBuffer
([]
byte
{})
cmd
:=
f
.
NewCmdGet
(
buf
)
cmd
:=
NewCmdGet
(
f
,
buf
)
cmd
.
SetOutput
(
buf
)
cmd
.
Run
(
cmd
,
[]
string
{
"pods"
,
"foo"
})
...
...
@@ -174,7 +174,7 @@ func TestGetListObjects(t *testing.T) {
tf
.
Namespace
=
"test"
buf
:=
bytes
.
NewBuffer
([]
byte
{})
cmd
:=
f
.
NewCmdGet
(
buf
)
cmd
:=
NewCmdGet
(
f
,
buf
)
cmd
.
SetOutput
(
buf
)
cmd
.
Run
(
cmd
,
[]
string
{
"pods"
})
...
...
@@ -210,7 +210,7 @@ func TestGetMultipleTypeObjects(t *testing.T) {
tf
.
Namespace
=
"test"
buf
:=
bytes
.
NewBuffer
([]
byte
{})
cmd
:=
f
.
NewCmdGet
(
buf
)
cmd
:=
NewCmdGet
(
f
,
buf
)
cmd
.
SetOutput
(
buf
)
cmd
.
Run
(
cmd
,
[]
string
{
"pods,services"
})
...
...
@@ -247,7 +247,7 @@ func TestGetMultipleTypeObjectsAsList(t *testing.T) {
tf
.
ClientConfig
=
&
client
.
Config
{
Version
:
"v1beta1"
}
buf
:=
bytes
.
NewBuffer
([]
byte
{})
cmd
:=
f
.
NewCmdGet
(
buf
)
cmd
:=
NewCmdGet
(
f
,
buf
)
cmd
.
SetOutput
(
buf
)
cmd
.
Flags
()
.
Set
(
"output"
,
"json"
)
...
...
@@ -298,7 +298,7 @@ func TestGetMultipleTypeObjectsWithSelector(t *testing.T) {
tf
.
Namespace
=
"test"
buf
:=
bytes
.
NewBuffer
([]
byte
{})
cmd
:=
f
.
NewCmdGet
(
buf
)
cmd
:=
NewCmdGet
(
f
,
buf
)
cmd
.
SetOutput
(
buf
)
cmd
.
Flags
()
.
Set
(
"selector"
,
"a=b"
)
...
...
@@ -344,7 +344,7 @@ func TestGetMultipleTypeObjectsWithDirectReference(t *testing.T) {
tf
.
Namespace
=
"test"
buf
:=
bytes
.
NewBuffer
([]
byte
{})
cmd
:=
f
.
NewCmdGet
(
buf
)
cmd
:=
NewCmdGet
(
f
,
buf
)
cmd
.
SetOutput
(
buf
)
cmd
.
Run
(
cmd
,
[]
string
{
"services/bar"
,
"node/foo"
})
...
...
@@ -430,7 +430,7 @@ func TestWatchSelector(t *testing.T) {
tf
.
Namespace
=
"test"
buf
:=
bytes
.
NewBuffer
([]
byte
{})
cmd
:=
f
.
NewCmdGet
(
buf
)
cmd
:=
NewCmdGet
(
f
,
buf
)
cmd
.
SetOutput
(
buf
)
cmd
.
Flags
()
.
Set
(
"watch"
,
"true"
)
...
...
@@ -469,7 +469,7 @@ func TestWatchResource(t *testing.T) {
tf
.
Namespace
=
"test"
buf
:=
bytes
.
NewBuffer
([]
byte
{})
cmd
:=
f
.
NewCmdGet
(
buf
)
cmd
:=
NewCmdGet
(
f
,
buf
)
cmd
.
SetOutput
(
buf
)
cmd
.
Flags
()
.
Set
(
"watch"
,
"true"
)
...
...
@@ -507,7 +507,7 @@ func TestWatchOnlyResource(t *testing.T) {
tf
.
Namespace
=
"test"
buf
:=
bytes
.
NewBuffer
([]
byte
{})
cmd
:=
f
.
NewCmdGet
(
buf
)
cmd
:=
NewCmdGet
(
f
,
buf
)
cmd
.
SetOutput
(
buf
)
cmd
.
Flags
()
.
Set
(
"watch-only"
,
"true"
)
...
...
pkg/kubectl/cmd/label.go
View file @
bb137f0b
...
...
@@ -22,7 +22,7 @@ import (
"strings"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/util"
cmdutil
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/util"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/resource"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/spf13/cobra"
...
...
@@ -50,7 +50,7 @@ $ kubectl label pods foo status=unhealthy --resource-version=1
$ kubectl label pods foo bar-`
)
func
(
f
*
Factory
)
NewCmdLabel
(
out
io
.
Writer
)
*
cobra
.
Command
{
func
NewCmdLabel
(
f
*
cmdutil
.
Factory
,
out
io
.
Writer
)
*
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
Use
:
"label [--overwrite] RESOURCE NAME KEY_1=VAL_1 ... KEY_N=VAL_N [--resource-version=version]"
,
Short
:
"Update the labels on a resource"
,
...
...
@@ -58,10 +58,10 @@ func (f *Factory) NewCmdLabel(out io.Writer) *cobra.Command {
Example
:
label_example
,
Run
:
func
(
cmd
*
cobra
.
Command
,
args
[]
string
)
{
err
:=
RunLabel
(
f
,
out
,
cmd
,
args
)
util
.
CheckErr
(
err
)
cmd
util
.
CheckErr
(
err
)
},
}
util
.
AddPrinterFlags
(
cmd
)
cmd
util
.
AddPrinterFlags
(
cmd
)
cmd
.
Flags
()
.
Bool
(
"overwrite"
,
false
,
"If true, allow labels to be overwritten, otherwise reject label updates that overwrite existing labels."
)
cmd
.
Flags
()
.
StringP
(
"selector"
,
"l"
,
""
,
"Selector (label query) to filter on"
)
cmd
.
Flags
()
.
Bool
(
"all"
,
false
,
"select all resources in the namespace of the specified resource types"
)
...
...
@@ -149,7 +149,7 @@ func labelFunc(obj runtime.Object, overwrite bool, resourceVersion string, label
return
obj
,
nil
}
func
RunLabel
(
f
*
Factory
,
out
io
.
Writer
,
cmd
*
cobra
.
Command
,
args
[]
string
)
error
{
func
RunLabel
(
f
*
cmdutil
.
Factory
,
out
io
.
Writer
,
cmd
*
cobra
.
Command
,
args
[]
string
)
error
{
resources
,
labelArgs
:=
[]
string
{},
[]
string
{}
first
:=
true
for
_
,
s
:=
range
args
{
...
...
@@ -163,20 +163,20 @@ func RunLabel(f *Factory, out io.Writer, cmd *cobra.Command, args []string) erro
case
first
&&
!
isLabel
:
resources
=
append
(
resources
,
s
)
case
!
first
&&
!
isLabel
:
return
util
.
UsageError
(
cmd
,
"all resources must be specified before label changes: %s"
,
s
)
return
cmd
util
.
UsageError
(
cmd
,
"all resources must be specified before label changes: %s"
,
s
)
}
}
if
len
(
resources
)
<
1
{
return
util
.
UsageError
(
cmd
,
"one or more resources must be specified as <resource> <name> or <resource>/<name>"
)
return
cmd
util
.
UsageError
(
cmd
,
"one or more resources must be specified as <resource> <name> or <resource>/<name>"
)
}
if
len
(
labelArgs
)
<
1
{
return
util
.
UsageError
(
cmd
,
"at least one label update is required"
)
return
cmd
util
.
UsageError
(
cmd
,
"at least one label update is required"
)
}
selector
:=
util
.
GetFlagString
(
cmd
,
"selector"
)
all
:=
util
.
GetFlagBool
(
cmd
,
"all"
)
overwrite
:=
util
.
GetFlagBool
(
cmd
,
"overwrite"
)
resourceVersion
:=
util
.
GetFlagString
(
cmd
,
"resource-version"
)
selector
:=
cmd
util
.
GetFlagString
(
cmd
,
"selector"
)
all
:=
cmd
util
.
GetFlagBool
(
cmd
,
"all"
)
overwrite
:=
cmd
util
.
GetFlagBool
(
cmd
,
"overwrite"
)
resourceVersion
:=
cmd
util
.
GetFlagString
(
cmd
,
"resource-version"
)
cmdNamespace
,
err
:=
f
.
DefaultNamespace
()
if
err
!=
nil
{
...
...
@@ -204,7 +204,7 @@ func RunLabel(f *Factory, out io.Writer, cmd *cobra.Command, args []string) erro
}
// only apply resource version locking on a single resource
if
!
one
&&
len
(
resourceVersion
)
>
0
{
return
util
.
UsageError
(
cmd
,
"--resource-version may only be used with a single resource"
)
return
cmd
util
.
UsageError
(
cmd
,
"--resource-version may only be used with a single resource"
)
}
// TODO: support bulk generic output a la Get
...
...
pkg/kubectl/cmd/label_test.go
View file @
bb137f0b
...
...
@@ -294,7 +294,7 @@ func TestLabelErrors(t *testing.T) {
tf
.
ClientConfig
=
&
client
.
Config
{
Version
:
"v1beta1"
}
buf
:=
bytes
.
NewBuffer
([]
byte
{})
cmd
:=
f
.
NewCmdLabel
(
buf
)
cmd
:=
NewCmdLabel
(
f
,
buf
)
cmd
.
SetOutput
(
buf
)
for
k
,
v
:=
range
testCase
.
flags
{
...
...
@@ -351,7 +351,7 @@ func TestLabelMultipleObjects(t *testing.T) {
tf
.
ClientConfig
=
&
client
.
Config
{
Version
:
"v1beta1"
}
buf
:=
bytes
.
NewBuffer
([]
byte
{})
cmd
:=
f
.
NewCmdLabel
(
buf
)
cmd
:=
NewCmdLabel
(
f
,
buf
)
cmd
.
Flags
()
.
Set
(
"all"
,
"true"
)
if
err
:=
RunLabel
(
f
,
buf
,
cmd
,
[]
string
{
"pods"
,
"a=b"
});
err
!=
nil
{
...
...
pkg/kubectl/cmd/log.go
View file @
bb137f0b
...
...
@@ -22,7 +22,7 @@ import (
"strconv"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/util"
cmdutil
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/util"
libutil
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/spf13/cobra"
)
...
...
@@ -57,7 +57,7 @@ func selectContainer(pod *api.Pod, in io.Reader, out io.Writer) string {
}
}
func
(
f
*
Factory
)
NewCmdLog
(
out
io
.
Writer
)
*
cobra
.
Command
{
func
NewCmdLog
(
f
*
cmdutil
.
Factory
,
out
io
.
Writer
)
*
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
Use
:
"log [-f] POD [CONTAINER]"
,
Short
:
"Print the logs for a container in a pod."
,
...
...
@@ -65,7 +65,7 @@ func (f *Factory) NewCmdLog(out io.Writer) *cobra.Command {
Example
:
log_example
,
Run
:
func
(
cmd
*
cobra
.
Command
,
args
[]
string
)
{
err
:=
RunLog
(
f
,
out
,
cmd
,
args
)
util
.
CheckErr
(
err
)
cmd
util
.
CheckErr
(
err
)
},
}
cmd
.
Flags
()
.
BoolP
(
"follow"
,
"f"
,
false
,
"Specify if the logs should be streamed."
)
...
...
@@ -73,13 +73,13 @@ func (f *Factory) NewCmdLog(out io.Writer) *cobra.Command {
return
cmd
}
func
RunLog
(
f
*
Factory
,
out
io
.
Writer
,
cmd
*
cobra
.
Command
,
args
[]
string
)
error
{
func
RunLog
(
f
*
cmdutil
.
Factory
,
out
io
.
Writer
,
cmd
*
cobra
.
Command
,
args
[]
string
)
error
{
if
len
(
args
)
==
0
{
return
util
.
UsageError
(
cmd
,
"POD is required for log"
)
return
cmd
util
.
UsageError
(
cmd
,
"POD is required for log"
)
}
if
len
(
args
)
>
2
{
return
util
.
UsageError
(
cmd
,
"log POD [CONTAINER]"
)
return
cmd
util
.
UsageError
(
cmd
,
"log POD [CONTAINER]"
)
}
namespace
,
err
:=
f
.
DefaultNamespace
()
...
...
@@ -109,7 +109,7 @@ func RunLog(f *Factory, out io.Writer, cmd *cobra.Command, args []string) error
}
follow
:=
false
if
util
.
GetFlagBool
(
cmd
,
"follow"
)
{
if
cmd
util
.
GetFlagBool
(
cmd
,
"follow"
)
{
follow
=
true
}
...
...
pkg/kubectl/cmd/portforward.go
View file @
bb137f0b
...
...
@@ -22,7 +22,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client/portforward"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/util"
cmdutil
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/util"
"github.com/golang/glog"
"github.com/spf13/cobra"
)
...
...
@@ -42,7 +42,7 @@ $ kubectl port-forward -p mypod :5000
$ kubectl port-forward -p mypod 0:5000`
)
func
(
f
*
Factory
)
NewCmdPortForward
(
)
*
cobra
.
Command
{
func
NewCmdPortForward
(
f
*
cmdutil
.
Factory
)
*
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
Use
:
"port-forward -p POD [LOCAL_PORT:]REMOTE_PORT [...[LOCAL_PORT_N:]REMOTE_PORT_N]"
,
Short
:
"Forward one or more local ports to a pod."
,
...
...
@@ -50,7 +50,7 @@ func (f *Factory) NewCmdPortForward() *cobra.Command {
Example
:
portforward_example
,
Run
:
func
(
cmd
*
cobra
.
Command
,
args
[]
string
)
{
err
:=
RunPortForward
(
f
,
cmd
,
args
)
util
.
CheckErr
(
err
)
cmd
util
.
CheckErr
(
err
)
},
}
cmd
.
Flags
()
.
StringP
(
"pod"
,
"p"
,
""
,
"Pod name"
)
...
...
@@ -58,14 +58,14 @@ func (f *Factory) NewCmdPortForward() *cobra.Command {
return
cmd
}
func
RunPortForward
(
f
*
Factory
,
cmd
*
cobra
.
Command
,
args
[]
string
)
error
{
podName
:=
util
.
GetFlagString
(
cmd
,
"pod"
)
func
RunPortForward
(
f
*
cmdutil
.
Factory
,
cmd
*
cobra
.
Command
,
args
[]
string
)
error
{
podName
:=
cmd
util
.
GetFlagString
(
cmd
,
"pod"
)
if
len
(
podName
)
==
0
{
return
util
.
UsageError
(
cmd
,
"POD is required for exec"
)
return
cmd
util
.
UsageError
(
cmd
,
"POD is required for exec"
)
}
if
len
(
args
)
<
1
{
return
util
.
UsageError
(
cmd
,
"at least 1 PORT is required for port-forward"
)
return
cmd
util
.
UsageError
(
cmd
,
"at least 1 PORT is required for port-forward"
)
}
namespace
,
err
:=
f
.
DefaultNamespace
()
...
...
pkg/kubectl/cmd/proxy.go
View file @
bb137f0b
...
...
@@ -22,7 +22,7 @@ import (
"strings"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/util"
cmdutil
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/util"
"github.com/golang/glog"
"github.com/spf13/cobra"
)
...
...
@@ -36,7 +36,7 @@ $ kubectl proxy --port=8011 --www=./local/www/
$ kubectl proxy --api-prefix=k8s-api`
)
func
(
f
*
Factory
)
NewCmdProxy
(
out
io
.
Writer
)
*
cobra
.
Command
{
func
NewCmdProxy
(
f
*
cmdutil
.
Factory
,
out
io
.
Writer
)
*
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
Use
:
"proxy [--port=PORT] [--www=static-dir] [--www-prefix=prefix] [--api-prefix=prefix]"
,
Short
:
"Run a proxy to the Kubernetes API server"
,
...
...
@@ -44,7 +44,7 @@ func (f *Factory) NewCmdProxy(out io.Writer) *cobra.Command {
Example
:
proxy_example
,
Run
:
func
(
cmd
*
cobra
.
Command
,
args
[]
string
)
{
err
:=
RunProxy
(
f
,
out
,
cmd
)
util
.
CheckErr
(
err
)
cmd
util
.
CheckErr
(
err
)
},
}
cmd
.
Flags
()
.
StringP
(
"www"
,
"w"
,
""
,
"Also serve static files from the given directory under the specified prefix."
)
...
...
@@ -54,8 +54,8 @@ func (f *Factory) NewCmdProxy(out io.Writer) *cobra.Command {
return
cmd
}
func
RunProxy
(
f
*
Factory
,
out
io
.
Writer
,
cmd
*
cobra
.
Command
)
error
{
port
:=
util
.
GetFlagInt
(
cmd
,
"port"
)
func
RunProxy
(
f
*
cmdutil
.
Factory
,
out
io
.
Writer
,
cmd
*
cobra
.
Command
)
error
{
port
:=
cmd
util
.
GetFlagInt
(
cmd
,
"port"
)
fmt
.
Fprintf
(
out
,
"Starting to serve on localhost:%d"
,
port
)
clientConfig
,
err
:=
f
.
ClientConfig
()
...
...
@@ -63,16 +63,16 @@ func RunProxy(f *Factory, out io.Writer, cmd *cobra.Command) error {
return
err
}
staticPrefix
:=
util
.
GetFlagString
(
cmd
,
"www-prefix"
)
staticPrefix
:=
cmd
util
.
GetFlagString
(
cmd
,
"www-prefix"
)
if
!
strings
.
HasSuffix
(
staticPrefix
,
"/"
)
{
staticPrefix
+=
"/"
}
apiProxyPrefix
:=
util
.
GetFlagString
(
cmd
,
"api-prefix"
)
apiProxyPrefix
:=
cmd
util
.
GetFlagString
(
cmd
,
"api-prefix"
)
if
!
strings
.
HasSuffix
(
apiProxyPrefix
,
"/"
)
{
apiProxyPrefix
+=
"/"
}
server
,
err
:=
kubectl
.
NewProxyServer
(
util
.
GetFlagString
(
cmd
,
"www"
),
apiProxyPrefix
,
staticPrefix
,
clientConfig
)
server
,
err
:=
kubectl
.
NewProxyServer
(
cmd
util
.
GetFlagString
(
cmd
,
"www"
),
apiProxyPrefix
,
staticPrefix
,
clientConfig
)
if
err
!=
nil
{
return
err
}
...
...
pkg/kubectl/cmd/resize.go
View file @
bb137f0b
...
...
@@ -23,7 +23,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/controller"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/util"
cmdutil
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/util"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util/wait"
"github.com/spf13/cobra"
)
...
...
@@ -45,7 +45,7 @@ $ kubectl resize --current-replicas=2 --replicas=3 replicationcontrollers foo`
retryTimeout
=
10
*
time
.
Second
)
func
(
f
*
Factory
)
NewCmdResize
(
out
io
.
Writer
)
*
cobra
.
Command
{
func
NewCmdResize
(
f
*
cmdutil
.
Factory
,
out
io
.
Writer
)
*
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
Use
:
"resize [--resource-version=version] [--current-replicas=count] --replicas=COUNT RESOURCE ID"
,
Short
:
"Set a new size for a Replication Controller."
,
...
...
@@ -53,7 +53,7 @@ func (f *Factory) NewCmdResize(out io.Writer) *cobra.Command {
Example
:
resize_example
,
Run
:
func
(
cmd
*
cobra
.
Command
,
args
[]
string
)
{
err
:=
RunResize
(
f
,
out
,
cmd
,
args
)
util
.
CheckErr
(
err
)
cmd
util
.
CheckErr
(
err
)
},
}
cmd
.
Flags
()
.
String
(
"resource-version"
,
""
,
"Precondition for resource version. Requires that the current resource version match this value in order to resize."
)
...
...
@@ -62,10 +62,10 @@ func (f *Factory) NewCmdResize(out io.Writer) *cobra.Command {
return
cmd
}
func
RunResize
(
f
*
Factory
,
out
io
.
Writer
,
cmd
*
cobra
.
Command
,
args
[]
string
)
error
{
count
:=
util
.
GetFlagInt
(
cmd
,
"replicas"
)
func
RunResize
(
f
*
cmdutil
.
Factory
,
out
io
.
Writer
,
cmd
*
cobra
.
Command
,
args
[]
string
)
error
{
count
:=
cmd
util
.
GetFlagInt
(
cmd
,
"replicas"
)
if
len
(
args
)
!=
2
||
count
<
0
{
return
util
.
UsageError
(
cmd
,
"--replicas=COUNT RESOURCE ID"
)
return
cmd
util
.
UsageError
(
cmd
,
"--replicas=COUNT RESOURCE ID"
)
}
cmdNamespace
,
err
:=
f
.
DefaultNamespace
()
...
...
@@ -75,7 +75,7 @@ func RunResize(f *Factory, out io.Writer, cmd *cobra.Command, args []string) err
mapper
,
_
:=
f
.
Object
()
// TODO: use resource.Builder instead
mapping
,
namespace
,
name
,
err
:=
util
.
ResourceFromArgs
(
cmd
,
args
,
mapper
,
cmdNamespace
)
mapping
,
namespace
,
name
,
err
:=
cmd
util
.
ResourceFromArgs
(
cmd
,
args
,
mapper
,
cmdNamespace
)
if
err
!=
nil
{
return
err
}
...
...
@@ -85,8 +85,8 @@ func RunResize(f *Factory, out io.Writer, cmd *cobra.Command, args []string) err
return
err
}
resourceVersion
:=
util
.
GetFlagString
(
cmd
,
"resource-version"
)
currentSize
:=
util
.
GetFlagInt
(
cmd
,
"current-replicas"
)
resourceVersion
:=
cmd
util
.
GetFlagString
(
cmd
,
"resource-version"
)
currentSize
:=
cmd
util
.
GetFlagInt
(
cmd
,
"current-replicas"
)
precondition
:=
&
kubectl
.
ResizePrecondition
{
currentSize
,
resourceVersion
}
cond
:=
kubectl
.
ResizeCondition
(
resizer
,
precondition
,
namespace
,
name
,
uint
(
count
))
...
...
pkg/kubectl/cmd/rollingupdate.go
View file @
bb137f0b
...
...
@@ -23,7 +23,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/util"
cmdutil
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/util"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/resource"
"github.com/spf13/cobra"
)
...
...
@@ -44,7 +44,7 @@ $ kubectl rolling-update frontend-v1 -f frontend-v2.json
$ cat frontend-v2.json | kubectl rolling-update frontend-v1 -f -`
)
func
(
f
*
Factory
)
NewCmdRollingUpdate
(
out
io
.
Writer
)
*
cobra
.
Command
{
func
NewCmdRollingUpdate
(
f
*
cmdutil
.
Factory
,
out
io
.
Writer
)
*
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
Use
:
"rolling-update OLD_CONTROLLER_NAME -f NEW_CONTROLLER_SPEC"
,
// rollingupdate is deprecated.
...
...
@@ -54,7 +54,7 @@ func (f *Factory) NewCmdRollingUpdate(out io.Writer) *cobra.Command {
Example
:
rollingUpdate_example
,
Run
:
func
(
cmd
*
cobra
.
Command
,
args
[]
string
)
{
err
:=
RunRollingUpdate
(
f
,
out
,
cmd
,
args
)
util
.
CheckErr
(
err
)
cmd
util
.
CheckErr
(
err
)
},
}
cmd
.
Flags
()
.
String
(
"update-period"
,
updatePeriod
,
`Time to wait between updating pods. Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".`
)
...
...
@@ -64,20 +64,20 @@ func (f *Factory) NewCmdRollingUpdate(out io.Writer) *cobra.Command {
return
cmd
}
func
RunRollingUpdate
(
f
*
Factory
,
out
io
.
Writer
,
cmd
*
cobra
.
Command
,
args
[]
string
)
error
{
func
RunRollingUpdate
(
f
*
cmdutil
.
Factory
,
out
io
.
Writer
,
cmd
*
cobra
.
Command
,
args
[]
string
)
error
{
if
os
.
Args
[
1
]
==
"rollingupdate"
{
printDeprecationWarning
(
"rolling-update"
,
"rollingupdate"
)
}
filename
:=
util
.
GetFlagString
(
cmd
,
"filename"
)
filename
:=
cmd
util
.
GetFlagString
(
cmd
,
"filename"
)
if
len
(
filename
)
==
0
{
return
util
.
UsageError
(
cmd
,
"Must specify filename for new controller"
)
return
cmd
util
.
UsageError
(
cmd
,
"Must specify filename for new controller"
)
}
period
:=
util
.
GetFlagDuration
(
cmd
,
"update-period"
)
interval
:=
util
.
GetFlagDuration
(
cmd
,
"poll-interval"
)
timeout
:=
util
.
GetFlagDuration
(
cmd
,
"timeout"
)
period
:=
cmd
util
.
GetFlagDuration
(
cmd
,
"update-period"
)
interval
:=
cmd
util
.
GetFlagDuration
(
cmd
,
"poll-interval"
)
timeout
:=
cmd
util
.
GetFlagDuration
(
cmd
,
"timeout"
)
if
len
(
args
)
!=
1
{
return
util
.
UsageError
(
cmd
,
"Must specify the controller to update"
)
return
cmd
util
.
UsageError
(
cmd
,
"Must specify the controller to update"
)
}
oldName
:=
args
[
0
]
...
...
@@ -98,11 +98,11 @@ func RunRollingUpdate(f *Factory, out io.Writer, cmd *cobra.Command, args []stri
}
newRc
,
ok
:=
obj
.
(
*
api
.
ReplicationController
)
if
!
ok
{
return
util
.
UsageError
(
cmd
,
"%s does not specify a valid ReplicationController"
,
filename
)
return
cmd
util
.
UsageError
(
cmd
,
"%s does not specify a valid ReplicationController"
,
filename
)
}
newName
:=
newRc
.
Name
if
oldName
==
newName
{
return
util
.
UsageError
(
cmd
,
"%s cannot have the same name as the existing ReplicationController %s"
,
return
cmd
util
.
UsageError
(
cmd
,
"%s cannot have the same name as the existing ReplicationController %s"
,
filename
,
oldName
)
}
...
...
@@ -127,7 +127,7 @@ func RunRollingUpdate(f *Factory, out io.Writer, cmd *cobra.Command, args []stri
}
}
if
!
hasLabel
{
return
util
.
UsageError
(
cmd
,
"%s must specify a matching key with non-equal value in Selector for %s"
,
return
cmd
util
.
UsageError
(
cmd
,
"%s must specify a matching key with non-equal value in Selector for %s"
,
filename
,
oldName
)
}
// TODO: handle resizes during rolling update
...
...
pkg/kubectl/cmd/run.go
View file @
bb137f0b
...
...
@@ -22,7 +22,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/util"
cmdutil
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/util"
"github.com/spf13/cobra"
)
...
...
@@ -42,7 +42,7 @@ $ kubectl run-container nginx --image=dockerfile/nginx --dry-run
$ kubectl run-container nginx --image=dockerfile/nginx --overrides='{ "apiVersion": "v1beta1", "desiredState": { ... } }'`
)
func
(
f
*
Factory
)
NewCmdRunContainer
(
out
io
.
Writer
)
*
cobra
.
Command
{
func
NewCmdRunContainer
(
f
*
cmdutil
.
Factory
,
out
io
.
Writer
)
*
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
Use
:
"run-container NAME --image=image [--port=port] [--replicas=replicas] [--dry-run=bool] [--overrides=inline-json]"
,
Short
:
"Run a particular image on the cluster."
,
...
...
@@ -50,10 +50,10 @@ func (f *Factory) NewCmdRunContainer(out io.Writer) *cobra.Command {
Example
:
run_example
,
Run
:
func
(
cmd
*
cobra
.
Command
,
args
[]
string
)
{
err
:=
RunRunContainer
(
f
,
out
,
cmd
,
args
)
util
.
CheckErr
(
err
)
cmd
util
.
CheckErr
(
err
)
},
}
util
.
AddPrinterFlags
(
cmd
)
cmd
util
.
AddPrinterFlags
(
cmd
)
cmd
.
Flags
()
.
String
(
"generator"
,
"run-container/v1"
,
"The name of the API generator to use. Default is 'run-container-controller/v1'."
)
cmd
.
Flags
()
.
String
(
"image"
,
""
,
"The image for the container to run."
)
cmd
.
Flags
()
.
IntP
(
"replicas"
,
"r"
,
1
,
"Number of replicas to create for this container. Default is 1."
)
...
...
@@ -64,9 +64,9 @@ func (f *Factory) NewCmdRunContainer(out io.Writer) *cobra.Command {
return
cmd
}
func
RunRunContainer
(
f
*
Factory
,
out
io
.
Writer
,
cmd
*
cobra
.
Command
,
args
[]
string
)
error
{
func
RunRunContainer
(
f
*
cmdutil
.
Factory
,
out
io
.
Writer
,
cmd
*
cobra
.
Command
,
args
[]
string
)
error
{
if
len
(
args
)
!=
1
{
return
util
.
UsageError
(
cmd
,
"NAME is required for run-container"
)
return
cmd
util
.
UsageError
(
cmd
,
"NAME is required for run-container"
)
}
namespace
,
err
:=
f
.
DefaultNamespace
()
...
...
@@ -79,10 +79,10 @@ func RunRunContainer(f *Factory, out io.Writer, cmd *cobra.Command, args []strin
return
err
}
generatorName
:=
util
.
GetFlagString
(
cmd
,
"generator"
)
generatorName
:=
cmd
util
.
GetFlagString
(
cmd
,
"generator"
)
generator
,
found
:=
kubectl
.
Generators
[
generatorName
]
if
!
found
{
return
util
.
UsageError
(
cmd
,
fmt
.
Sprintf
(
"Generator: %s not found."
,
generator
))
return
cmd
util
.
UsageError
(
cmd
,
fmt
.
Sprintf
(
"Generator: %s not found."
,
generator
))
}
names
:=
generator
.
ParamNames
()
params
:=
kubectl
.
MakeParams
(
cmd
,
names
)
...
...
@@ -98,16 +98,16 @@ func RunRunContainer(f *Factory, out io.Writer, cmd *cobra.Command, args []strin
return
err
}
inline
:=
util
.
GetFlagString
(
cmd
,
"overrides"
)
inline
:=
cmd
util
.
GetFlagString
(
cmd
,
"overrides"
)
if
len
(
inline
)
>
0
{
controller
,
err
=
util
.
Merge
(
controller
,
inline
,
"ReplicationController"
)
controller
,
err
=
cmd
util
.
Merge
(
controller
,
inline
,
"ReplicationController"
)
if
err
!=
nil
{
return
err
}
}
// TODO: extract this flag to a central location, when such a location exists.
if
!
util
.
GetFlagBool
(
cmd
,
"dry-run"
)
{
if
!
cmd
util
.
GetFlagBool
(
cmd
,
"dry-run"
)
{
controller
,
err
=
client
.
ReplicationControllers
(
namespace
)
.
Create
(
controller
.
(
*
api
.
ReplicationController
))
if
err
!=
nil
{
return
err
...
...
pkg/kubectl/cmd/stop.go
View file @
bb137f0b
...
...
@@ -44,7 +44,7 @@ $ kubectl stop -f service.json
$ kubectl stop -f path/to/resources`
)
func
(
f
*
Factory
)
NewCmdStop
(
out
io
.
Writer
)
*
cobra
.
Command
{
func
NewCmdStop
(
f
*
cmdutil
.
Factory
,
out
io
.
Writer
)
*
cobra
.
Command
{
flags
:=
&
struct
{
Filenames
util
.
StringList
}{}
...
...
pkg/kubectl/cmd/update.go
View file @
bb137f0b
...
...
@@ -40,7 +40,7 @@ $ cat pod.json | kubectl update -f -
$ kubectl update pods my-pod --patch='{ "apiVersion": "v1beta1", "desiredState": { "manifest": [{ "cpu": 100 }]}}'`
)
func
(
f
*
Factory
)
NewCmdUpdate
(
out
io
.
Writer
)
*
cobra
.
Command
{
func
NewCmdUpdate
(
f
*
cmdutil
.
Factory
,
out
io
.
Writer
)
*
cobra
.
Command
{
var
filenames
util
.
StringList
cmd
:=
&
cobra
.
Command
{
Use
:
"update -f FILENAME"
,
...
...
@@ -57,7 +57,7 @@ func (f *Factory) NewCmdUpdate(out io.Writer) *cobra.Command {
return
cmd
}
func
RunUpdate
(
f
*
Factory
,
out
io
.
Writer
,
cmd
*
cobra
.
Command
,
args
[]
string
,
filenames
util
.
StringList
)
error
{
func
RunUpdate
(
f
*
cmdutil
.
Factory
,
out
io
.
Writer
,
cmd
*
cobra
.
Command
,
args
[]
string
,
filenames
util
.
StringList
)
error
{
schema
,
err
:=
f
.
Validator
()
if
err
!=
nil
{
return
err
...
...
@@ -117,7 +117,7 @@ func RunUpdate(f *Factory, out io.Writer, cmd *cobra.Command, args []string, fil
}
func
updateWithPatch
(
cmd
*
cobra
.
Command
,
args
[]
string
,
f
*
Factory
,
patch
string
)
(
string
,
error
)
{
func
updateWithPatch
(
cmd
*
cobra
.
Command
,
args
[]
string
,
f
*
cmdutil
.
Factory
,
patch
string
)
(
string
,
error
)
{
cmdNamespace
,
err
:=
f
.
DefaultNamespace
()
if
err
!=
nil
{
return
""
,
err
...
...
pkg/kubectl/cmd/update_test.go
View file @
bb137f0b
...
...
@@ -47,7 +47,7 @@ func TestUpdateObject(t *testing.T) {
tf
.
Namespace
=
"test"
buf
:=
bytes
.
NewBuffer
([]
byte
{})
cmd
:=
f
.
NewCmdUpdate
(
buf
)
cmd
:=
NewCmdUpdate
(
f
,
buf
)
cmd
.
Flags
()
.
Set
(
"filename"
,
"../../../examples/guestbook/redis-master-controller.json"
)
cmd
.
Run
(
cmd
,
[]
string
{})
...
...
@@ -83,7 +83,7 @@ func TestUpdateMultipleObject(t *testing.T) {
tf
.
Namespace
=
"test"
buf
:=
bytes
.
NewBuffer
([]
byte
{})
cmd
:=
f
.
NewCmdUpdate
(
buf
)
cmd
:=
NewCmdUpdate
(
f
,
buf
)
cmd
.
Flags
()
.
Set
(
"filename"
,
"../../../examples/guestbook/redis-master-controller.json"
)
cmd
.
Flags
()
.
Set
(
"filename"
,
"../../../examples/guestbook/frontend-service.json"
)
cmd
.
Run
(
cmd
,
[]
string
{})
...
...
@@ -115,7 +115,7 @@ func TestUpdateDirectory(t *testing.T) {
tf
.
Namespace
=
"test"
buf
:=
bytes
.
NewBuffer
([]
byte
{})
cmd
:=
f
.
NewCmdUpdate
(
buf
)
cmd
:=
NewCmdUpdate
(
f
,
buf
)
cmd
.
Flags
()
.
Set
(
"filename"
,
"../../../examples/guestbook"
)
cmd
.
Flags
()
.
Set
(
"namespace"
,
"test"
)
cmd
.
Run
(
cmd
,
[]
string
{})
...
...
pkg/kubectl/cmd/util/clientcache.go
0 → 100644
View file @
bb137f0b
/*
Copyright 2014 Google Inc. All rights reserved.
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
(
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd"
)
// 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: have a better config copy method
config
:=
*
c
.
defaultConfig
if
len
(
version
)
!=
0
{
config
.
Version
=
version
}
client
.
SetKubernetesDefaults
(
&
config
)
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
client
,
ok
:=
c
.
clients
[
config
.
Version
];
ok
{
return
client
,
nil
}
client
,
err
:=
client
.
New
(
config
)
if
err
!=
nil
{
return
nil
,
err
}
c
.
clients
[
config
.
Version
]
=
client
return
client
,
nil
}
pkg/kubectl/cmd/util/factory.go
0 → 100644
View file @
bb137f0b
/*
Copyright 2014 Google Inc. All rights reserved.
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
(
"fmt"
"io"
"os"
"strconv"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/meta"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/validation"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/resource"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
)
const
(
FlagMatchBinaryVersion
=
"match-server-version"
)
// Factory provides abstractions that allow the Kubectl command to be extended across multiple types
// of resources and different API sets.
// TODO: make the functions interfaces
// TODO: pass the various interfaces on the factory directly into the command constructors (so the
// commands are decoupled from the factory).
type
Factory
struct
{
clients
*
clientCache
flags
*
pflag
.
FlagSet
// Returns interfaces for dealing with arbitrary runtime.Objects.
Object
func
()
(
meta
.
RESTMapper
,
runtime
.
ObjectTyper
)
// Returns a client for accessing Kubernetes resources or an error.
Client
func
()
(
*
client
.
Client
,
error
)
// Returns a client.Config for accessing the Kubernetes server.
ClientConfig
func
()
(
*
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
(
mapping
*
meta
.
RESTMapping
)
(
resource
.
RESTClient
,
error
)
// Returns a Describer for displaying the specified RESTMapping type or an error.
Describer
func
(
mapping
*
meta
.
RESTMapping
)
(
kubectl
.
Describer
,
error
)
// Returns a Printer for formatting objects of the given type or an error.
Printer
func
(
mapping
*
meta
.
RESTMapping
,
noHeaders
bool
)
(
kubectl
.
ResourcePrinter
,
error
)
// Returns a Resizer for changing the size of the specified RESTMapping type or an error
Resizer
func
(
mapping
*
meta
.
RESTMapping
)
(
kubectl
.
Resizer
,
error
)
// Returns a Reaper for gracefully shutting down resources.
Reaper
func
(
mapping
*
meta
.
RESTMapping
)
(
kubectl
.
Reaper
,
error
)
// PodSelectorForResource returns the pod selector associated with the provided resource name
// or an error.
PodSelectorForResource
func
(
mapping
*
meta
.
RESTMapping
,
namespace
,
name
string
)
(
string
,
error
)
// PortForResource returns the ports associated with the provided resource name or an error
PortsForResource
func
(
mapping
*
meta
.
RESTMapping
,
namespace
,
name
string
)
([]
string
,
error
)
// Returns a schema that can validate objects stored on disk.
Validator
func
()
(
validation
.
Schema
,
error
)
// Returns the default namespace to use in cases where no other namespace is specified
DefaultNamespace
func
()
(
string
,
error
)
}
// NewFactory creates a factory with the default Kubernetes resources defined
// if optionalClientConfig is nil, then flags will be bound to a new clientcmd.ClientConfig.
// if optionalClientConfig is not nil, then this factory will make use of it.
func
NewFactory
(
optionalClientConfig
clientcmd
.
ClientConfig
)
*
Factory
{
mapper
:=
kubectl
.
ShortcutExpander
{
latest
.
RESTMapper
}
flags
:=
pflag
.
NewFlagSet
(
""
,
pflag
.
ContinueOnError
)
clientConfig
:=
optionalClientConfig
if
optionalClientConfig
==
nil
{
clientConfig
=
DefaultClientConfig
(
flags
)
}
clients
:=
&
clientCache
{
clients
:
make
(
map
[
string
]
*
client
.
Client
),
loader
:
clientConfig
,
}
return
&
Factory
{
clients
:
clients
,
flags
:
flags
,
Object
:
func
()
(
meta
.
RESTMapper
,
runtime
.
ObjectTyper
)
{
cfg
,
err
:=
clientConfig
.
ClientConfig
()
CheckErr
(
err
)
cmdApiVersion
:=
cfg
.
Version
return
kubectl
.
OutputVersionMapper
{
mapper
,
cmdApiVersion
},
api
.
Scheme
},
Client
:
func
()
(
*
client
.
Client
,
error
)
{
return
clients
.
ClientForVersion
(
""
)
},
ClientConfig
:
func
()
(
*
client
.
Config
,
error
)
{
return
clients
.
ClientConfigForVersion
(
""
)
},
RESTClient
:
func
(
mapping
*
meta
.
RESTMapping
)
(
resource
.
RESTClient
,
error
)
{
client
,
err
:=
clients
.
ClientForVersion
(
mapping
.
APIVersion
)
if
err
!=
nil
{
return
nil
,
err
}
return
client
.
RESTClient
,
nil
},
Describer
:
func
(
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
(
mapping
*
meta
.
RESTMapping
,
noHeaders
bool
)
(
kubectl
.
ResourcePrinter
,
error
)
{
return
kubectl
.
NewHumanReadablePrinter
(
noHeaders
),
nil
},
PodSelectorForResource
:
func
(
mapping
*
meta
.
RESTMapping
,
namespace
,
name
string
)
(
string
,
error
)
{
// TODO: replace with a swagger schema based approach (identify pod selector via schema introspection)
client
,
err
:=
clients
.
ClientForVersion
(
""
)
if
err
!=
nil
{
return
""
,
err
}
switch
mapping
.
Kind
{
case
"ReplicationController"
:
rc
,
err
:=
client
.
ReplicationControllers
(
namespace
)
.
Get
(
name
)
if
err
!=
nil
{
return
""
,
err
}
return
kubectl
.
MakeLabels
(
rc
.
Spec
.
Selector
),
nil
case
"Pod"
:
rc
,
err
:=
client
.
Pods
(
namespace
)
.
Get
(
name
)
if
err
!=
nil
{
return
""
,
err
}
if
len
(
rc
.
Labels
)
==
0
{
return
""
,
fmt
.
Errorf
(
"the pod has no labels and cannot be exposed"
)
}
return
kubectl
.
MakeLabels
(
rc
.
Labels
),
nil
case
"Service"
:
rc
,
err
:=
client
.
ReplicationControllers
(
namespace
)
.
Get
(
name
)
if
err
!=
nil
{
return
""
,
err
}
if
rc
.
Spec
.
Selector
==
nil
{
return
""
,
fmt
.
Errorf
(
"the service has no pod selector set"
)
}
return
kubectl
.
MakeLabels
(
rc
.
Spec
.
Selector
),
nil
default
:
return
""
,
fmt
.
Errorf
(
"it is not possible to get a pod selector from %s"
,
mapping
.
Kind
)
}
},
PortsForResource
:
func
(
mapping
*
meta
.
RESTMapping
,
namespace
,
name
string
)
([]
string
,
error
)
{
// TODO: replace with a swagger schema based approach (identify pod selector via schema introspection)
client
,
err
:=
clients
.
ClientForVersion
(
""
)
if
err
!=
nil
{
return
nil
,
err
}
switch
mapping
.
Kind
{
case
"ReplicationController"
:
rc
,
err
:=
client
.
ReplicationControllers
(
namespace
)
.
Get
(
name
)
if
err
!=
nil
{
return
nil
,
err
}
return
getPorts
(
rc
.
Spec
.
Template
.
Spec
),
nil
case
"Pod"
:
pod
,
err
:=
client
.
Pods
(
namespace
)
.
Get
(
name
)
if
err
!=
nil
{
return
nil
,
err
}
return
getPorts
(
pod
.
Spec
),
nil
default
:
return
nil
,
fmt
.
Errorf
(
"it is not possible to get ports from %s"
,
mapping
.
Kind
)
}
},
Resizer
:
func
(
mapping
*
meta
.
RESTMapping
)
(
kubectl
.
Resizer
,
error
)
{
client
,
err
:=
clients
.
ClientForVersion
(
mapping
.
APIVersion
)
if
err
!=
nil
{
return
nil
,
err
}
return
kubectl
.
ResizerFor
(
mapping
.
Kind
,
client
)
},
Reaper
:
func
(
mapping
*
meta
.
RESTMapping
)
(
kubectl
.
Reaper
,
error
)
{
client
,
err
:=
clients
.
ClientForVersion
(
mapping
.
APIVersion
)
if
err
!=
nil
{
return
nil
,
err
}
return
kubectl
.
ReaperFor
(
mapping
.
Kind
,
client
)
},
Validator
:
func
()
(
validation
.
Schema
,
error
)
{
if
flags
.
Lookup
(
"validate"
)
.
Value
.
String
()
==
"true"
{
client
,
err
:=
clients
.
ClientForVersion
(
""
)
if
err
!=
nil
{
return
nil
,
err
}
return
&
clientSwaggerSchema
{
client
,
api
.
Scheme
},
nil
}
return
validation
.
NullSchema
{},
nil
},
DefaultNamespace
:
func
()
(
string
,
error
)
{
return
clientConfig
.
Namespace
()
},
}
}
// 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
)
// This is necessary as github.com/spf13/cobra doesn't support "global"
// pflags currently. See https://github.com/spf13/cobra/issues/44.
util
.
AddPFlagSetToPFlagSet
(
pflag
.
CommandLine
,
flags
)
// Hack for global access to validation flag.
// TODO: Refactor out after configuration flag overhaul.
if
f
.
flags
.
Lookup
(
"validate"
)
==
nil
{
f
.
flags
.
Bool
(
"validate"
,
false
,
"If true, use a schema to validate the input before sending it"
)
}
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"
)
}
func
getPorts
(
spec
api
.
PodSpec
)
[]
string
{
result
:=
[]
string
{}
for
_
,
container
:=
range
spec
.
Containers
{
for
_
,
port
:=
range
container
.
Ports
{
result
=
append
(
result
,
strconv
.
Itoa
(
port
.
ContainerPort
))
}
}
return
result
}
type
clientSwaggerSchema
struct
{
c
*
client
.
Client
t
runtime
.
ObjectTyper
}
func
(
c
*
clientSwaggerSchema
)
ValidateBytes
(
data
[]
byte
)
error
{
version
,
_
,
err
:=
c
.
t
.
DataVersionAndKind
(
data
)
if
err
!=
nil
{
return
err
}
schemaData
,
err
:=
c
.
c
.
RESTClient
.
Get
()
.
AbsPath
(
"/swaggerapi/api"
,
version
)
.
Do
()
.
Raw
()
if
err
!=
nil
{
return
err
}
schema
,
err
:=
validation
.
NewSwaggerSchemaFromBytes
(
schemaData
)
if
err
!=
nil
{
return
err
}
return
schema
.
ValidateBytes
(
data
)
}
// 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
// 2. EnvVarLocation
// 3. CurrentDirectoryLocation
// 4. HomeDirectoryLocation
// Empty filenames are ignored. Files with non-deserializable content produced errors.
// The first file to set a particular value or map key wins and the value or map key is never changed.
// This means that the first file to set CurrentContext will have its context preserved. It also means
// that if two files specify a "red-user", only values from the first file's red-user are used. Even
// non-conflicting entries from the second file's "red-user" are discarded.
// 2. Determine the context to use based on the first hit in this chain
// 1. command line argument - again, parsed from the command line, so it must be late bound
// 2. CurrentContext from the merged kubeconfig file
// 3. Empty is allowed at this stage
// 3. Determine the cluster info and auth info to use. At this point, we may or may not have a context. They
// are built based on the first hit in this chain. (run it twice, once for auth, once for cluster)
// 1. command line argument
// 2. If context is present, then use the context value
// 3. Empty is allowed
// 4. Determine the actual cluster info to use. At this point, we may or may not have a cluster info. Build
// each piece of the cluster info based on the chain:
// 1. command line argument
// 2. If cluster info is present and a value for the attribute is present, use it.
// 3. If you don't have a server location, bail.
// 5. Auth info is build using the same rules as cluster info, EXCEPT that you can only have one authentication
// technique per auth info. The following conditions result in an error:
// 1. If there are two conflicting techniques specified from the command line, fail.
// 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
DefaultClientConfig
(
flags
*
pflag
.
FlagSet
)
clientcmd
.
ClientConfig
{
loadingRules
:=
clientcmd
.
NewDefaultClientConfigLoadingRules
()
flags
.
StringVar
(
&
loadingRules
.
ExplicitPath
,
"kubeconfig"
,
""
,
"Path to the kubeconfig file to use for CLI requests."
)
overrides
:=
&
clientcmd
.
ConfigOverrides
{}
flagNames
:=
clientcmd
.
RecommendedConfigOverrideFlags
(
""
)
// short flagnames are disabled by default. These are here for compatibility with existing scripts
flagNames
.
AuthOverrideFlags
.
AuthPathShort
=
"a"
flagNames
.
ClusterOverrideFlags
.
APIServerShort
=
"s"
clientcmd
.
BindOverrideFlags
(
overrides
,
flags
,
flagNames
)
clientConfig
:=
clientcmd
.
NewInteractiveDeferredLoadingClientConfig
(
loadingRules
,
overrides
,
os
.
Stdin
)
return
clientConfig
}
// PrintObject prints an api object given command line flags to modify the output format
func
(
f
*
Factory
)
PrintObject
(
cmd
*
cobra
.
Command
,
obj
runtime
.
Object
,
out
io
.
Writer
)
error
{
mapper
,
_
:=
f
.
Object
()
_
,
kind
,
err
:=
api
.
Scheme
.
ObjectVersionAndKind
(
obj
)
if
err
!=
nil
{
return
err
}
mapping
,
err
:=
mapper
.
RESTMapping
(
kind
)
if
err
!=
nil
{
return
err
}
printer
,
err
:=
f
.
PrinterForMapping
(
cmd
,
mapping
)
if
err
!=
nil
{
return
err
}
return
printer
.
PrintObj
(
obj
,
out
)
}
// PrinterForMapping returns a printer suitable for displaying the provided resource type.
// Requires that printer flags have been added to cmd (see AddPrinterFlags).
func
(
f
*
Factory
)
PrinterForMapping
(
cmd
*
cobra
.
Command
,
mapping
*
meta
.
RESTMapping
)
(
kubectl
.
ResourcePrinter
,
error
)
{
printer
,
ok
,
err
:=
PrinterForCommand
(
cmd
)
if
err
!=
nil
{
return
nil
,
err
}
if
ok
{
clientConfig
,
err
:=
f
.
ClientConfig
()
if
err
!=
nil
{
return
nil
,
err
}
defaultVersion
:=
clientConfig
.
Version
version
:=
OutputVersion
(
cmd
,
defaultVersion
)
if
len
(
version
)
==
0
{
version
=
mapping
.
APIVersion
}
if
len
(
version
)
==
0
{
return
nil
,
fmt
.
Errorf
(
"you must specify an output-version when using this output format"
)
}
printer
=
kubectl
.
NewVersionedPrinter
(
printer
,
mapping
.
ObjectConvertor
,
version
)
}
else
{
printer
,
err
=
f
.
Printer
(
mapping
,
GetFlagBool
(
cmd
,
"no-headers"
))
if
err
!=
nil
{
return
nil
,
err
}
}
return
printer
,
nil
}
// ClientMapperForCommand returns a ClientMapper for the factory.
func
(
f
*
Factory
)
ClientMapperForCommand
()
resource
.
ClientMapper
{
return
resource
.
ClientMapperFunc
(
func
(
mapping
*
meta
.
RESTMapping
)
(
resource
.
RESTClient
,
error
)
{
return
f
.
RESTClient
(
mapping
)
})
}
pkg/kubectl/cmd/factory_test.go
→
pkg/kubectl/cmd/
util/
factory_test.go
View file @
bb137f0b
...
...
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package
cmd
package
util
import
(
"testing"
...
...
pkg/kubectl/cmd/version.go
View file @
bb137f0b
...
...
@@ -22,24 +22,24 @@ import (
"github.com/spf13/cobra"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/util"
cmdutil
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/util"
)
func
(
f
*
Factory
)
NewCmdVersion
(
out
io
.
Writer
)
*
cobra
.
Command
{
func
NewCmdVersion
(
f
*
cmdutil
.
Factory
,
out
io
.
Writer
)
*
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
Use
:
"version"
,
Short
:
"Print the client and server version information."
,
Run
:
func
(
cmd
*
cobra
.
Command
,
args
[]
string
)
{
err
:=
RunVersion
(
f
,
out
,
cmd
)
util
.
CheckErr
(
err
)
cmd
util
.
CheckErr
(
err
)
},
}
cmd
.
Flags
()
.
BoolP
(
"client"
,
"c"
,
false
,
"Client version only (no server required)."
)
return
cmd
}
func
RunVersion
(
f
*
Factory
,
out
io
.
Writer
,
cmd
*
cobra
.
Command
)
error
{
if
util
.
GetFlagBool
(
cmd
,
"client"
)
{
func
RunVersion
(
f
*
cmdutil
.
Factory
,
out
io
.
Writer
,
cmd
*
cobra
.
Command
)
error
{
if
cmd
util
.
GetFlagBool
(
cmd
,
"client"
)
{
kubectl
.
GetClientVersion
(
out
)
return
nil
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment