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
fab36723
Commit
fab36723
authored
Aug 10, 2015
by
Muhammed Uluyol
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add experimental API support to kubectl
parent
01807c1f
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
194 additions
and
63 deletions
+194
-63
latest.go
pkg/api/latest/latest.go
+1
-1
mapper.go
pkg/api/mapper.go
+5
-4
interfaces.go
pkg/api/meta/interfaces.go
+1
-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
factory.go
pkg/kubectl/cmd/util/factory.go
+90
-25
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 @
fab36723
...
...
@@ -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 @
fab36723
...
...
@@ -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 @
fab36723
...
...
@@ -144,6 +144,7 @@ type RESTMapping struct {
// consumers of Kubernetes compatible REST APIs as defined in docs/api-conventions.md.
type
RESTMapper
interface
{
VersionAndKindForResource
(
resource
string
)
(
defaultVersion
,
kind
string
,
err
error
)
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 @
fab36723
...
...
@@ -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 @
fab36723
...
...
@@ -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 @
fab36723
...
...
@@ -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 @
fab36723
...
...
@@ -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 @
fab36723
...
...
@@ -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 @
fab36723
...
...
@@ -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/factory.go
View file @
fab36723
...
...
@@ -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"
...
...
@@ -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 @
fab36723
...
...
@@ -81,6 +81,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
)
...
...
@@ -94,12 +98,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 @
fab36723
...
...
@@ -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 @
fab36723
...
...
@@ -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 @
fab36723
...
...
@@ -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 @
fab36723
...
...
@@ -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 @
fab36723
...
...
@@ -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