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
59da05ef
Commit
59da05ef
authored
Aug 12, 2015
by
CJ Cullen
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #12405 from uluyol/kubectlexp
Add experimental api support to kubectl
parents
ead7b376
93b14c9a
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
210 additions
and
70 deletions
+210
-70
latest.go
pkg/api/latest/latest.go
+1
-1
mapper.go
pkg/api/mapper.go
+5
-4
interfaces.go
pkg/api/meta/interfaces.go
+10
-0
restmapper.go
pkg/api/meta/restmapper.go
+24
-3
restmapper_test.go
pkg/api/meta/restmapper_test.go
+32
-5
apiserver_test.go
pkg/apiserver/apiserver_test.go
+1
-1
latest.go
pkg/expapi/latest/latest.go
+1
-1
apiversions.go
pkg/kubectl/cmd/apiversions.go
+22
-3
cmd_test.go
pkg/kubectl/cmd/cmd_test.go
+1
-1
clientcache.go
pkg/kubectl/cmd/util/clientcache.go
+6
-6
factory.go
pkg/kubectl/cmd/util/factory.go
+91
-26
describe.go
pkg/kubectl/describe.go
+12
-5
stop.go
pkg/kubectl/stop.go
+1
-1
stop_test.go
pkg/kubectl/stop_test.go
+1
-1
version.go
pkg/kubectl/version.go
+0
-10
rc.go
test/e2e/rc.go
+1
-1
master_utils.go
test/integration/framework/master_utils.go
+1
-1
No files found.
pkg/api/latest/latest.go
View file @
59da05ef
...
...
@@ -97,7 +97,7 @@ func init() {
"PodProxyOptions"
,
"Daemon"
)
mapper
:=
api
.
NewDefaultRESTMapper
(
versions
,
InterfacesFor
,
importPrefix
,
ignoredKinds
,
rootScoped
)
mapper
:=
api
.
NewDefaultRESTMapper
(
"api"
,
versions
,
InterfacesFor
,
importPrefix
,
ignoredKinds
,
rootScoped
)
// setup aliases for groups of resources
mapper
.
AddResourceAlias
(
"all"
,
userResources
...
)
RESTMapper
=
mapper
...
...
pkg/api/mapper.go
View file @
59da05ef
...
...
@@ -33,11 +33,12 @@ func RegisterRESTMapper(m meta.RESTMapper) {
RESTMapper
=
append
(
RESTMapper
.
(
meta
.
MultiRESTMapper
),
m
)
}
func
NewDefaultRESTMapper
(
versions
[]
string
,
interfacesFunc
meta
.
VersionInterfacesFunc
,
importPathPrefix
string
,
ignoredKinds
,
rootScoped
util
.
StringSet
)
*
meta
.
DefaultRESTMapper
{
func
NewDefaultRESTMapper
(
group
string
,
versions
[]
string
,
interfacesFunc
meta
.
VersionInterfacesFunc
,
i
mportPathPrefix
string
,
i
gnoredKinds
,
rootScoped
util
.
StringSet
)
*
meta
.
DefaultRESTMapper
{
mapper
:=
meta
.
NewDefaultRESTMapper
(
versions
,
interfacesFunc
)
// enumerate all supported versions, get the kinds, and register with the mapper how to address our resources.
mapper
:=
meta
.
NewDefaultRESTMapper
(
group
,
versions
,
interfacesFunc
)
// enumerate all supported versions, get the kinds, and register with the mapper how to address
// our resources.
for
_
,
version
:=
range
versions
{
for
kind
,
oType
:=
range
Scheme
.
KnownTypes
(
version
)
{
// TODO: Remove import path prefix check.
...
...
pkg/api/meta/interfaces.go
View file @
59da05ef
...
...
@@ -142,8 +142,18 @@ type RESTMapping struct {
// RESTMapper allows clients to map resources to kind, and map kind and version
// to interfaces for manipulating those objects. It is primarily intended for
// consumers of Kubernetes compatible REST APIs as defined in docs/api-conventions.md.
//
// The Kubernetes API provides versioned resources and object kinds which are scoped
// to API groups. In other words, kinds and resources should not be assumed to be
// unique across groups.
//
// TODO(caesarxuchao): Add proper multi-group support so that kinds & resources are
// scoped to groups. See http://issues.k8s.io/12413 and http://issues.k8s.io/10009.
type
RESTMapper
interface
{
VersionAndKindForResource
(
resource
string
)
(
defaultVersion
,
kind
string
,
err
error
)
// TODO(caesarxuchao): Remove GroupForResource when multi-group support is in (since
// group will be part of the version).
GroupForResource
(
resource
string
)
(
string
,
error
)
RESTMapping
(
kind
string
,
versions
...
string
)
(
*
RESTMapping
,
error
)
AliasesForResource
(
resource
string
)
([]
string
,
bool
)
ResourceSingularizer
(
resource
string
)
(
singular
string
,
err
error
)
...
...
pkg/api/meta/restmapper.go
View file @
59da05ef
...
...
@@ -76,6 +76,7 @@ type DefaultRESTMapper struct {
mapping
map
[
string
]
typeMeta
reverse
map
[
typeMeta
]
string
scopes
map
[
typeMeta
]
RESTScope
group
string
versions
[]
string
plurals
map
[
string
]
string
singulars
map
[
string
]
string
...
...
@@ -88,10 +89,10 @@ type VersionInterfacesFunc func(apiVersion string) (*VersionInterfaces, error)
// NewDefaultRESTMapper initializes a mapping between Kind and APIVersion
// to a resource name and back based on the objects in a runtime.Scheme
// and the Kubernetes API conventions. Takes a
priority list of the versions to
//
search when an object has no default version (set empty to return an error)
// and the Kubernetes API conventions. Takes a
group name, a priority list of the versions
//
to search when an object has no default version (set empty to return an error),
// and a function that retrieves the correct codec and metadata for a given version.
func
NewDefaultRESTMapper
(
versions
[]
string
,
f
VersionInterfacesFunc
)
*
DefaultRESTMapper
{
func
NewDefaultRESTMapper
(
group
string
,
versions
[]
string
,
f
VersionInterfacesFunc
)
*
DefaultRESTMapper
{
mapping
:=
make
(
map
[
string
]
typeMeta
)
reverse
:=
make
(
map
[
typeMeta
]
string
)
scopes
:=
make
(
map
[
typeMeta
]
RESTScope
)
...
...
@@ -103,6 +104,7 @@ func NewDefaultRESTMapper(versions []string, f VersionInterfacesFunc) *DefaultRE
mapping
:
mapping
,
reverse
:
reverse
,
scopes
:
scopes
,
group
:
group
,
versions
:
versions
,
plurals
:
plurals
,
singulars
:
singulars
,
...
...
@@ -174,6 +176,13 @@ func (m *DefaultRESTMapper) VersionAndKindForResource(resource string) (defaultV
return
meta
.
APIVersion
,
meta
.
Kind
,
nil
}
func
(
m
*
DefaultRESTMapper
)
GroupForResource
(
resource
string
)
(
string
,
error
)
{
if
_
,
ok
:=
m
.
mapping
[
strings
.
ToLower
(
resource
)];
!
ok
{
return
""
,
fmt
.
Errorf
(
"no resource %q has been defined"
,
resource
)
}
return
m
.
group
,
nil
}
// RESTMapping returns a struct representing the resource path and conversion interfaces a
// RESTClient should use to operate on the provided kind in order of versions. If a version search
// order is not provided, the search order provided to DefaultRESTMapper will be used to resolve which
...
...
@@ -292,6 +301,18 @@ func (m MultiRESTMapper) VersionAndKindForResource(resource string) (defaultVers
return
}
// GroupForResource provides the Group mappings for the REST resources. This
// implementation supports multiple REST schemas and returns the first match.
func
(
m
MultiRESTMapper
)
GroupForResource
(
resource
string
)
(
group
string
,
err
error
)
{
for
_
,
t
:=
range
m
{
group
,
err
=
t
.
GroupForResource
(
resource
)
if
err
==
nil
{
return
}
}
return
}
// RESTMapping provides the REST mapping for the resource based on the resource
// kind and version. This implementation supports multiple REST schemas and
// return the first match.
...
...
pkg/api/meta/restmapper_test.go
View file @
59da05ef
...
...
@@ -93,7 +93,7 @@ func TestRESTMapperVersionAndKindForResource(t *testing.T) {
{
Resource
:
"internalObjects"
,
MixedCase
:
true
,
Kind
:
"InternalObject"
,
APIVersion
:
"test"
},
}
for
i
,
testCase
:=
range
testCases
{
mapper
:=
NewDefaultRESTMapper
([]
string
{
"test"
},
fakeInterfaces
)
mapper
:=
NewDefaultRESTMapper
(
"tgroup"
,
[]
string
{
"test"
},
fakeInterfaces
)
mapper
.
Add
(
RESTScopeNamespace
,
testCase
.
Kind
,
testCase
.
APIVersion
,
testCase
.
MixedCase
)
v
,
k
,
err
:=
mapper
.
VersionAndKindForResource
(
testCase
.
Resource
)
hasErr
:=
err
!=
nil
...
...
@@ -107,6 +107,33 @@ func TestRESTMapperVersionAndKindForResource(t *testing.T) {
}
}
func
TestRESTMapperGroupForResource
(
t
*
testing
.
T
)
{
testCases
:=
[]
struct
{
Resource
string
Kind
,
APIVersion
,
Group
string
Err
bool
}{
{
Resource
:
"myObject"
,
Kind
:
"MyObject"
,
APIVersion
:
"test"
,
Group
:
"testapi"
},
{
Resource
:
"myobject"
,
Kind
:
"MyObject"
,
APIVersion
:
"test"
,
Group
:
"testapi2"
},
{
Resource
:
"myObje"
,
Err
:
true
,
Kind
:
"MyObject"
,
APIVersion
:
"test"
,
Group
:
"testapi"
},
{
Resource
:
"myobje"
,
Err
:
true
,
Kind
:
"MyObject"
,
APIVersion
:
"test"
,
Group
:
"testapi"
},
}
for
i
,
testCase
:=
range
testCases
{
mapper
:=
NewDefaultRESTMapper
(
testCase
.
Group
,
[]
string
{
"test"
},
fakeInterfaces
)
mapper
.
Add
(
RESTScopeNamespace
,
testCase
.
Kind
,
testCase
.
APIVersion
,
false
)
g
,
err
:=
mapper
.
GroupForResource
(
testCase
.
Resource
)
if
testCase
.
Err
{
if
err
==
nil
{
t
.
Errorf
(
"%d: expected error"
,
i
)
}
}
else
if
err
!=
nil
{
t
.
Errorf
(
"%d: unexpected error: %v"
,
i
,
err
)
}
else
if
g
!=
testCase
.
Group
{
t
.
Errorf
(
"%d: expected group %q, got %q"
,
i
,
testCase
.
Group
,
g
)
}
}
}
func
TestKindToResource
(
t
*
testing
.
T
)
{
testCases
:=
[]
struct
{
Kind
string
...
...
@@ -159,7 +186,7 @@ func TestRESTMapperResourceSingularizer(t *testing.T) {
{
Kind
:
"lowercases"
,
APIVersion
:
"test"
,
MixedCase
:
false
,
Plural
:
"lowercases"
,
Singular
:
"lowercases"
},
}
for
i
,
testCase
:=
range
testCases
{
mapper
:=
NewDefaultRESTMapper
([]
string
{
"test"
},
fakeInterfaces
)
mapper
:=
NewDefaultRESTMapper
(
"tgroup"
,
[]
string
{
"test"
},
fakeInterfaces
)
// create singular/plural mapping
mapper
.
Add
(
RESTScopeNamespace
,
testCase
.
Kind
,
testCase
.
APIVersion
,
testCase
.
MixedCase
)
singular
,
_
:=
mapper
.
ResourceSingularizer
(
testCase
.
Plural
)
...
...
@@ -198,7 +225,7 @@ func TestRESTMapperRESTMapping(t *testing.T) {
// TODO: add test for a resource that exists in one version but not another
}
for
i
,
testCase
:=
range
testCases
{
mapper
:=
NewDefaultRESTMapper
(
testCase
.
DefaultVersions
,
fakeInterfaces
)
mapper
:=
NewDefaultRESTMapper
(
"tgroup"
,
testCase
.
DefaultVersions
,
fakeInterfaces
)
mapper
.
Add
(
RESTScopeNamespace
,
"InternalObject"
,
"test"
,
testCase
.
MixedCase
)
mapping
,
err
:=
mapper
.
RESTMapping
(
testCase
.
Kind
,
testCase
.
APIVersions
...
)
hasErr
:=
err
!=
nil
...
...
@@ -225,7 +252,7 @@ func TestRESTMapperRESTMapping(t *testing.T) {
}
func
TestRESTMapperRESTMappingSelectsVersion
(
t
*
testing
.
T
)
{
mapper
:=
NewDefaultRESTMapper
([]
string
{
"test1"
,
"test2"
},
fakeInterfaces
)
mapper
:=
NewDefaultRESTMapper
(
"tgroup"
,
[]
string
{
"test1"
,
"test2"
},
fakeInterfaces
)
mapper
.
Add
(
RESTScopeNamespace
,
"InternalObject"
,
"test1"
,
false
)
mapper
.
Add
(
RESTScopeNamespace
,
"OtherObject"
,
"test2"
,
false
)
...
...
@@ -278,7 +305,7 @@ func TestRESTMapperRESTMappingSelectsVersion(t *testing.T) {
}
func
TestRESTMapperReportsErrorOnBadVersion
(
t
*
testing
.
T
)
{
mapper
:=
NewDefaultRESTMapper
([]
string
{
"test1"
,
"test2"
},
unmatchedVersionInterfaces
)
mapper
:=
NewDefaultRESTMapper
(
"tgroup"
,
[]
string
{
"test1"
,
"test2"
},
unmatchedVersionInterfaces
)
mapper
.
Add
(
RESTScopeNamespace
,
"InternalObject"
,
"test1"
,
false
)
_
,
err
:=
mapper
.
RESTMapping
(
"InternalObject"
,
"test1"
)
if
err
==
nil
{
...
...
pkg/apiserver/apiserver_test.go
View file @
59da05ef
...
...
@@ -88,7 +88,7 @@ func interfacesFor(version string) (*meta.VersionInterfaces, error) {
}
func
newMapper
()
*
meta
.
DefaultRESTMapper
{
return
meta
.
NewDefaultRESTMapper
(
versions
,
interfacesFor
)
return
meta
.
NewDefaultRESTMapper
(
"testgroup"
,
versions
,
interfacesFor
)
}
func
addTestTypes
()
{
...
...
pkg/expapi/latest/latest.go
View file @
59da05ef
...
...
@@ -55,7 +55,7 @@ func init() {
ignoredKinds
:=
util
.
NewStringSet
()
RESTMapper
=
api
.
NewDefaultRESTMapper
(
Versions
,
InterfacesFor
,
importPrefix
,
ignoredKinds
,
rootScoped
)
RESTMapper
=
api
.
NewDefaultRESTMapper
(
"experimental"
,
Versions
,
InterfacesFor
,
importPrefix
,
ignoredKinds
,
rootScoped
)
api
.
RegisterRESTMapper
(
RESTMapper
)
}
...
...
pkg/kubectl/cmd/apiversions.go
View file @
59da05ef
...
...
@@ -17,12 +17,13 @@ limitations under the License.
package
cmd
import
(
"fmt"
"io"
"os"
"github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/
kubectl
"
"k8s.io/kubernetes/pkg/
api
"
cmdutil
"k8s.io/kubernetes/pkg/kubectl/cmd/util"
)
...
...
@@ -40,7 +41,7 @@ func NewCmdApiVersions(f *cmdutil.Factory, out io.Writer) *cobra.Command {
return
cmd
}
func
RunApiVersions
(
f
*
cmdutil
.
Factory
,
out
io
.
Writer
)
error
{
func
RunApiVersions
(
f
*
cmdutil
.
Factory
,
w
io
.
Writer
)
error
{
if
len
(
os
.
Args
)
>
1
&&
os
.
Args
[
1
]
==
"apiversions"
{
printDeprecationWarning
(
"api-versions"
,
"apiversions"
)
}
...
...
@@ -50,6 +51,24 @@ func RunApiVersions(f *cmdutil.Factory, out io.Writer) error {
return
err
}
kubectl
.
GetApiVersions
(
out
,
client
)
apiVersions
,
err
:=
client
.
ServerAPIVersions
()
if
err
!=
nil
{
fmt
.
Printf
(
"Couldn't get available api versions from server: %v
\n
"
,
err
)
os
.
Exit
(
1
)
}
var
expAPIVersions
*
api
.
APIVersions
showExpVersions
:=
false
expClient
,
err
:=
f
.
ExperimentalClient
()
if
err
==
nil
{
expAPIVersions
,
err
=
expClient
.
ServerAPIVersions
()
showExpVersions
=
err
==
nil
}
fmt
.
Fprintf
(
w
,
"Available Server Api Versions: %#v
\n
"
,
*
apiVersions
)
if
showExpVersions
{
fmt
.
Fprintf
(
w
,
"Available Server Experimental Api Versions: %#v
\n
"
,
*
expAPIVersions
)
}
return
nil
}
pkg/kubectl/cmd/cmd_test.go
View file @
59da05ef
...
...
@@ -83,7 +83,7 @@ func newExternalScheme() (*runtime.Scheme, meta.RESTMapper, runtime.Codec) {
codec
:=
runtime
.
CodecFor
(
scheme
,
"unlikelyversion"
)
validVersion
:=
testapi
.
Version
()
mapper
:=
meta
.
NewDefaultRESTMapper
([]
string
{
"unlikelyversion"
,
validVersion
},
func
(
version
string
)
(
*
meta
.
VersionInterfaces
,
error
)
{
mapper
:=
meta
.
NewDefaultRESTMapper
(
"apitest"
,
[]
string
{
"unlikelyversion"
,
validVersion
},
func
(
version
string
)
(
*
meta
.
VersionInterfaces
,
error
)
{
return
&
meta
.
VersionInterfaces
{
Codec
:
runtime
.
CodecFor
(
scheme
,
version
),
ObjectConvertor
:
scheme
,
...
...
pkg/kubectl/cmd/util/clientcache.go
View file @
59da05ef
...
...
@@ -22,17 +22,17 @@ import (
"k8s.io/kubernetes/pkg/client/clientcmd"
)
func
NewClientCache
(
loader
clientcmd
.
ClientConfig
)
*
c
lientCache
{
return
&
c
lientCache
{
func
NewClientCache
(
loader
clientcmd
.
ClientConfig
)
*
C
lientCache
{
return
&
C
lientCache
{
clients
:
make
(
map
[
string
]
*
client
.
Client
),
configs
:
make
(
map
[
string
]
*
client
.
Config
),
loader
:
loader
,
}
}
//
c
lientCache caches previously loaded clients for reuse, and ensures MatchServerVersion
//
C
lientCache caches previously loaded clients for reuse, and ensures MatchServerVersion
// is invoked only once
type
c
lientCache
struct
{
type
C
lientCache
struct
{
loader
clientcmd
.
ClientConfig
clients
map
[
string
]
*
client
.
Client
configs
map
[
string
]
*
client
.
Config
...
...
@@ -42,7 +42,7 @@ type clientCache struct {
}
// ClientConfigForVersion returns the correct config for a server
func
(
c
*
c
lientCache
)
ClientConfigForVersion
(
version
string
)
(
*
client
.
Config
,
error
)
{
func
(
c
*
C
lientCache
)
ClientConfigForVersion
(
version
string
)
(
*
client
.
Config
,
error
)
{
if
c
.
defaultConfig
==
nil
{
config
,
err
:=
c
.
loader
.
ClientConfig
()
if
err
!=
nil
{
...
...
@@ -73,7 +73,7 @@ func (c *clientCache) ClientConfigForVersion(version string) (*client.Config, er
// ClientForVersion initializes or reuses a client for the specified version, or returns an
// error if that is not possible
func
(
c
*
c
lientCache
)
ClientForVersion
(
version
string
)
(
*
client
.
Client
,
error
)
{
func
(
c
*
C
lientCache
)
ClientForVersion
(
version
string
)
(
*
client
.
Client
,
error
)
{
if
client
,
ok
:=
c
.
clients
[
version
];
ok
{
return
client
,
nil
}
...
...
pkg/kubectl/cmd/util/factory.go
View file @
59da05ef
...
...
@@ -17,6 +17,7 @@ limitations under the License.
package
util
import
(
"errors"
"flag"
"fmt"
"io"
...
...
@@ -27,7 +28,6 @@ import (
"github.com/spf13/pflag"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/latest"
"k8s.io/kubernetes/pkg/api/meta"
"k8s.io/kubernetes/pkg/api/registered"
"k8s.io/kubernetes/pkg/api/validation"
...
...
@@ -49,7 +49,7 @@ const (
// 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
*
c
lientCache
clients
*
C
lientCache
flags
*
pflag
.
FlagSet
generators
map
[
string
]
kubectl
.
Generator
...
...
@@ -57,6 +57,8 @@ type Factory struct {
Object
func
()
(
meta
.
RESTMapper
,
runtime
.
ObjectTyper
)
// Returns a client for accessing Kubernetes resources or an error.
Client
func
()
(
*
client
.
Client
,
error
)
// Returns a client for accessing experimental Kubernetes resources or an error.
ExperimentalClient
func
()
(
*
client
.
ExperimentalClient
,
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
...
...
@@ -90,7 +92,7 @@ type Factory struct {
// 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
{
RESTMapper
:
latest
.
RESTMapper
}
mapper
:=
kubectl
.
ShortcutExpander
{
RESTMapper
:
api
.
RESTMapper
}
flags
:=
pflag
.
NewFlagSet
(
""
,
pflag
.
ContinueOnError
)
flags
.
SetNormalizeFunc
(
util
.
WarnWordSepNormalizeFunc
)
// Warn for "_" flags
...
...
@@ -109,6 +111,25 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
clients
:=
NewClientCache
(
clientConfig
)
// Initialize the experimental client (if possible). Failing here is non-fatal, errors
// will be returned when an experimental client is explicitly requested.
var
experimentalClient
*
client
.
ExperimentalClient
cfg
,
experimentalClientErr
:=
clientConfig
.
ClientConfig
()
if
experimentalClientErr
==
nil
{
experimentalClient
,
experimentalClientErr
=
client
.
NewExperimental
(
cfg
)
}
noClientErr
:=
errors
.
New
(
"could not get client"
)
getBothClients
:=
func
(
group
string
,
version
string
)
(
client
*
client
.
Client
,
expClient
*
client
.
ExperimentalClient
,
err
error
)
{
err
=
noClientErr
switch
group
{
case
"api"
:
client
,
err
=
clients
.
ClientForVersion
(
version
)
case
"experimental"
:
expClient
,
err
=
experimentalClient
,
experimentalClientErr
}
return
}
return
&
Factory
{
clients
:
clients
,
flags
:
flags
,
...
...
@@ -124,26 +145,46 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
Client
:
func
()
(
*
client
.
Client
,
error
)
{
return
clients
.
ClientForVersion
(
""
)
},
ExperimentalClient
:
func
()
(
*
client
.
ExperimentalClient
,
error
)
{
return
experimentalClient
,
experimentalClientErr
},
ClientConfig
:
func
()
(
*
client
.
Config
,
error
)
{
return
clients
.
ClientConfigForVersion
(
""
)
},
RESTClient
:
func
(
mapping
*
meta
.
RESTMapping
)
(
resource
.
RESTClient
,
error
)
{
client
,
err
:=
clients
.
ClientForVersion
(
mapping
.
APIVersion
)
group
,
err
:=
api
.
RESTMapper
.
GroupForResource
(
mapping
.
Resource
)
if
err
!=
nil
{
return
nil
,
err
}
return
client
.
RESTClient
,
nil
switch
group
{
case
"api"
:
client
,
err
:=
clients
.
ClientForVersion
(
mapping
.
APIVersion
)
if
err
!=
nil
{
return
nil
,
err
}
return
client
.
RESTClient
,
nil
case
"experimental"
:
client
,
err
:=
experimentalClient
,
experimentalClientErr
if
err
!=
nil
{
return
nil
,
err
}
return
client
.
RESTClient
,
nil
}
return
nil
,
fmt
.
Errorf
(
"unable to get RESTClient for resource '%s'"
,
mapping
.
Resource
)
},
Describer
:
func
(
mapping
*
meta
.
RESTMapping
)
(
kubectl
.
Describer
,
error
)
{
client
,
err
:=
clients
.
ClientForVersion
(
mapping
.
APIVersion
)
group
,
err
:=
api
.
RESTMapper
.
GroupForResource
(
mapping
.
Resource
)
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
)
client
,
expClient
,
err
:=
getBothClients
(
group
,
mapping
.
APIVersion
)
if
err
!=
nil
{
return
nil
,
err
}
return
describer
,
nil
if
describer
,
ok
:=
kubectl
.
DescriberFor
(
mapping
.
Kind
,
client
,
expClient
);
ok
{
return
describer
,
nil
}
return
nil
,
fmt
.
Errorf
(
"no description has been implemented for %q"
,
mapping
.
Kind
)
},
Printer
:
func
(
mapping
*
meta
.
RESTMapping
,
noHeaders
,
withNamespace
bool
,
wide
bool
,
columnLabels
[]
string
)
(
kubectl
.
ResourcePrinter
,
error
)
{
return
kubectl
.
NewHumanReadablePrinter
(
noHeaders
,
withNamespace
,
wide
,
columnLabels
),
nil
...
...
@@ -192,18 +233,26 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
return
meta
.
NewAccessor
()
.
Labels
(
object
)
},
Scaler
:
func
(
mapping
*
meta
.
RESTMapping
)
(
kubectl
.
Scaler
,
error
)
{
client
,
err
:=
clients
.
ClientForVersion
(
mapping
.
APIVersion
)
group
,
err
:=
api
.
RESTMapper
.
GroupForResource
(
mapping
.
Resource
)
if
err
!=
nil
{
return
nil
,
err
}
client
,
_
,
err
:=
getBothClients
(
group
,
mapping
.
APIVersion
)
if
err
!=
nil
{
return
nil
,
err
}
return
kubectl
.
ScalerFor
(
mapping
.
Kind
,
kubectl
.
NewScalerClient
(
client
))
},
Reaper
:
func
(
mapping
*
meta
.
RESTMapping
)
(
kubectl
.
Reaper
,
error
)
{
client
,
err
:=
clients
.
ClientForVersion
(
mapping
.
APIVersion
)
group
,
err
:=
api
.
RESTMapper
.
GroupForResource
(
mapping
.
Resource
)
if
err
!=
nil
{
return
nil
,
err
}
client
,
expClient
,
err
:=
getBothClients
(
group
,
mapping
.
APIVersion
)
if
err
!=
nil
{
return
nil
,
err
}
return
kubectl
.
ReaperFor
(
mapping
.
Kind
,
client
)
return
kubectl
.
ReaperFor
(
mapping
.
Kind
,
client
,
expClient
)
},
Validator
:
func
()
(
validation
.
Schema
,
error
)
{
if
flags
.
Lookup
(
"validate"
)
.
Value
.
String
()
==
"true"
{
...
...
@@ -211,7 +260,7 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
if
err
!=
nil
{
return
nil
,
err
}
return
&
clientSwaggerSchema
{
client
,
api
.
Scheme
},
nil
return
&
clientSwaggerSchema
{
client
,
experimentalClient
,
api
.
Scheme
},
nil
}
return
validation
.
NullSchema
{},
nil
},
...
...
@@ -274,20 +323,14 @@ func getServicePorts(spec api.ServiceSpec) []string {
}
type
clientSwaggerSchema
struct
{
c
*
client
.
Client
t
runtime
.
ObjectTyper
c
*
client
.
Client
ec
*
client
.
ExperimentalClient
t
runtime
.
ObjectTyper
}
func
(
c
*
clientSwaggerSchema
)
ValidateBytes
(
data
[]
byte
)
error
{
version
,
_
,
err
:=
runtime
.
UnstructuredJSONScheme
.
DataVersionAndKind
(
data
)
if
err
!=
nil
{
return
err
}
if
ok
:=
registered
.
IsRegisteredAPIVersion
(
version
);
!
ok
{
return
fmt
.
Errorf
(
"API version %q isn't supported, only supports API versions %q"
,
version
,
registered
.
RegisteredVersions
)
}
schemaData
,
err
:=
c
.
c
.
RESTClient
.
Get
()
.
AbsPath
(
"/swaggerapi/api"
,
version
)
.
func
getSchemaAndValidate
(
c
*
client
.
RESTClient
,
data
[]
byte
,
group
,
version
string
)
error
{
schemaData
,
err
:=
c
.
Get
()
.
AbsPath
(
"/swaggerapi"
,
group
,
version
)
.
Do
()
.
Raw
()
if
err
!=
nil
{
...
...
@@ -300,6 +343,28 @@ func (c *clientSwaggerSchema) ValidateBytes(data []byte) error {
return
schema
.
ValidateBytes
(
data
)
}
func
(
c
*
clientSwaggerSchema
)
ValidateBytes
(
data
[]
byte
)
error
{
version
,
_
,
err
:=
runtime
.
UnstructuredJSONScheme
.
DataVersionAndKind
(
data
)
if
err
!=
nil
{
return
err
}
if
ok
:=
registered
.
IsRegisteredAPIVersion
(
version
);
!
ok
{
return
fmt
.
Errorf
(
"API version %q isn't supported, only supports API versions %q"
,
version
,
registered
.
RegisteredVersions
)
}
// First try stable api, if we can't validate using that, try experimental.
// If experimental fails, return error from stable api.
// TODO: Figure out which group to try once multiple group support is merged
// instead of trying everything.
err
=
getSchemaAndValidate
(
c
.
c
.
RESTClient
,
data
,
"api"
,
version
)
if
err
!=
nil
&&
c
.
ec
!=
nil
{
errExp
:=
getSchemaAndValidate
(
c
.
ec
.
RESTClient
,
data
,
"experimental"
,
version
)
if
errExp
==
nil
{
return
nil
}
}
return
err
}
// 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 rules:
...
...
pkg/kubectl/describe.go
View file @
59da05ef
...
...
@@ -82,6 +82,10 @@ func describerMap(c *client.Client) map[string]Describer {
return
m
}
func
expDescriberMap
(
c
*
client
.
ExperimentalClient
)
map
[
string
]
Describer
{
return
map
[
string
]
Describer
{}
}
// List of all resource types we can describe
func
DescribableResources
()
[]
string
{
keys
:=
make
([]
string
,
0
)
...
...
@@ -95,12 +99,15 @@ func DescribableResources() []string {
// Describer returns the default describe functions for each of the standard
// Kubernetes types.
func
DescriberFor
(
kind
string
,
c
*
client
.
Client
)
(
Describer
,
bool
)
{
f
,
ok
:=
describerMap
(
c
)[
kind
]
if
ok
{
return
f
,
true
func
DescriberFor
(
kind
string
,
c
*
client
.
Client
,
ec
*
client
.
ExperimentalClient
)
(
Describer
,
bool
)
{
var
f
Describer
var
ok
bool
if
c
!=
nil
{
f
,
ok
=
describerMap
(
c
)[
kind
]
}
else
if
ec
!=
nil
{
f
,
ok
=
expDescriberMap
(
ec
)[
kind
]
}
return
nil
,
false
return
f
,
ok
}
// DefaultObjectDescriber can describe the default Kubernetes objects.
...
...
pkg/kubectl/stop.go
View file @
59da05ef
...
...
@@ -52,7 +52,7 @@ func IsNoSuchReaperError(err error) bool {
return
ok
}
func
ReaperFor
(
kind
string
,
c
client
.
Interface
)
(
Reaper
,
error
)
{
func
ReaperFor
(
kind
string
,
c
client
.
Interface
,
ec
*
client
.
ExperimentalClient
)
(
Reaper
,
error
)
{
switch
kind
{
case
"ReplicationController"
:
return
&
ReplicationControllerReaper
{
c
,
Interval
,
Timeout
},
nil
...
...
pkg/kubectl/stop_test.go
View file @
59da05ef
...
...
@@ -156,7 +156,7 @@ func TestSimpleStop(t *testing.T) {
}
for
_
,
test
:=
range
tests
{
fake
:=
test
.
fake
reaper
,
err
:=
ReaperFor
(
test
.
kind
,
fake
)
reaper
,
err
:=
ReaperFor
(
test
.
kind
,
fake
,
nil
)
if
err
!=
nil
{
t
.
Errorf
(
"unexpected error: %v (%s)"
,
err
,
test
.
test
)
}
...
...
pkg/kubectl/version.go
View file @
59da05ef
...
...
@@ -40,13 +40,3 @@ func GetVersion(w io.Writer, kubeClient client.Interface) {
func
GetClientVersion
(
w
io
.
Writer
)
{
fmt
.
Fprintf
(
w
,
"Client Version: %#v
\n
"
,
version
.
Get
())
}
func
GetApiVersions
(
w
io
.
Writer
,
kubeClient
client
.
Interface
)
{
apiVersions
,
err
:=
kubeClient
.
ServerAPIVersions
()
if
err
!=
nil
{
fmt
.
Printf
(
"Couldn't get available api versions from server: %v
\n
"
,
err
)
os
.
Exit
(
1
)
}
fmt
.
Fprintf
(
w
,
"Available Server Api Versions: %#v
\n
"
,
*
apiVersions
)
}
test/e2e/rc.go
View file @
59da05ef
...
...
@@ -89,7 +89,7 @@ func ServeImageOrFail(f *Framework, test string, image string) {
defer
func
()
{
// Resize the replication controller to zero to get rid of pods.
By
(
"Cleaning up the replication controller"
)
rcReaper
,
err
:=
kubectl
.
ReaperFor
(
"ReplicationController"
,
f
.
Client
)
rcReaper
,
err
:=
kubectl
.
ReaperFor
(
"ReplicationController"
,
f
.
Client
,
nil
)
if
err
!=
nil
{
Logf
(
"Failed to cleanup replication controller %v: %v."
,
controller
.
Name
,
err
)
}
...
...
test/integration/framework/master_utils.go
View file @
59da05ef
...
...
@@ -190,7 +190,7 @@ func RCFromManifest(fileName string) *api.ReplicationController {
// StopRC stops the rc via kubectl's stop library
func
StopRC
(
rc
*
api
.
ReplicationController
,
restClient
*
client
.
Client
)
error
{
reaper
,
err
:=
kubectl
.
ReaperFor
(
"ReplicationController"
,
restClient
)
reaper
,
err
:=
kubectl
.
ReaperFor
(
"ReplicationController"
,
restClient
,
nil
)
if
err
!=
nil
||
reaper
==
nil
{
return
err
}
...
...
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