Skip to content
This repository was archived by the owner on Feb 8, 2021. It is now read-only.

Commit 6f0f87b

Browse files
author
Chao Xu
committed
make kubectl explain work for extensions API
1 parent cadb6c0 commit 6f0f87b

File tree

3 files changed

+49
-17
lines changed

3 files changed

+49
-17
lines changed

pkg/client/unversioned/client.go

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ import (
2626
"github.com/emicklei/go-restful/swagger"
2727

2828
"k8s.io/kubernetes/pkg/api"
29-
"k8s.io/kubernetes/pkg/api/latest"
3029
"k8s.io/kubernetes/pkg/api/unversioned"
3130
"k8s.io/kubernetes/pkg/version"
3231
)
@@ -184,26 +183,32 @@ func (c *Client) ValidateComponents() (*api.ComponentStatusList, error) {
184183
// SwaggerSchemaInterface has a method to retrieve the swagger schema. Used in
185184
// client.Interface
186185
type SwaggerSchemaInterface interface {
187-
SwaggerSchema(version string) (*swagger.ApiDeclaration, error)
186+
SwaggerSchema(groupVersion string) (*swagger.ApiDeclaration, error)
188187
}
189188

190189
// SwaggerSchema retrieves and parses the swagger API schema the server supports.
191-
func (c *Client) SwaggerSchema(version string) (*swagger.ApiDeclaration, error) {
192-
if version == "" {
193-
version = latest.GroupOrDie("").Version
190+
func (c *Client) SwaggerSchema(groupVersion string) (*swagger.ApiDeclaration, error) {
191+
if groupVersion == "" {
192+
return nil, fmt.Errorf("groupVersion cannot be empty")
194193
}
195194

196-
vers, err := c.ServerAPIVersions()
195+
groupList, err := c.Discovery().ServerGroups()
197196
if err != nil {
198197
return nil, err
199198
}
200-
199+
groupVersions := extractGroupVersions(groupList)
201200
// This check also takes care the case that kubectl is newer than the running endpoint
202-
if stringDoesntExistIn(version, vers.Versions) {
203-
return nil, fmt.Errorf("API version: %s is not supported by the server. Use one of: %v", version, vers.Versions)
201+
if stringDoesntExistIn(groupVersion, groupVersions) {
202+
return nil, fmt.Errorf("API version: %s is not supported by the server. Use one of: %v", groupVersion, groupVersions)
203+
}
204+
var path string
205+
if groupVersion == "v1" {
206+
path = "/swaggerapi/api/" + groupVersion
207+
} else {
208+
path = "/swaggerapi/apis/" + groupVersion
204209
}
205210

206-
body, err := c.Get().AbsPath("/swaggerapi/api/" + version).Do().Raw()
211+
body, err := c.Get().AbsPath(path).Do().Raw()
207212
if err != nil {
208213
return nil, err
209214
}

pkg/kubectl/cmd/explain.go

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121

2222
"github.com/spf13/cobra"
2323

24+
"k8s.io/kubernetes/pkg/api/latest"
2425
"k8s.io/kubernetes/pkg/kubectl"
2526
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
2627
)
@@ -70,13 +71,28 @@ func RunExplain(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []st
7071
recursive := cmdutil.GetFlagBool(cmd, "recursive")
7172
apiV := cmdutil.GetFlagString(cmd, "api-version")
7273

73-
swagSchema, err := kubectl.GetSwaggerSchema(apiV, client)
74+
mapper, _ := f.Object()
75+
group, inModel, fieldsPath, err := kubectl.SplitAndParseResourceRequest(args[0], mapper)
7476
if err != nil {
7577
return err
7678
}
7779

78-
mapper, _ := f.Object()
79-
inModel, fieldsPath, err := kubectl.SplitAndParseResourceRequest(args[0], mapper)
80+
if len(group) == 0 {
81+
// TODO: We should deduce the group for a resource by discovering the supported resources at server.
82+
group, err = mapper.GroupForResource(inModel)
83+
if err != nil {
84+
return err
85+
}
86+
}
87+
88+
if len(apiV) == 0 {
89+
groupMeta, err := latest.Group(group)
90+
if err != nil {
91+
return err
92+
}
93+
apiV = groupMeta.GroupVersion
94+
}
95+
swagSchema, err := kubectl.GetSwaggerSchema(apiV, client)
8096
if err != nil {
8197
return err
8298
}

pkg/kubectl/explain.go

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"github.com/emicklei/go-restful/swagger"
2525

2626
"k8s.io/kubernetes/pkg/api/meta"
27+
apiutil "k8s.io/kubernetes/pkg/api/util"
2728
client "k8s.io/kubernetes/pkg/client/unversioned"
2829
)
2930

@@ -40,16 +41,17 @@ func GetSwaggerSchema(apiVer string, kubeClient client.Interface) (*swagger.ApiD
4041
}
4142

4243
// SplitAndParseResourceRequest separates the users input into a model and fields
43-
func SplitAndParseResourceRequest(inResource string, mapper meta.RESTMapper) (string, []string, error) {
44+
func SplitAndParseResourceRequest(inResource string, mapper meta.RESTMapper) (string, string, []string, error) {
4445
inResource, fieldsPath := splitDotNotation(inResource)
46+
group, inResource := splitGroupFromResource(inResource)
4547
inResource, _ = mapper.ResourceSingularizer(expandResourceShortcut(inResource))
46-
return inResource, fieldsPath, nil
48+
return group, inResource, fieldsPath, nil
4749
}
4850

4951
// PrintModelDescription prints the description of a specific model or dot path
5052
func PrintModelDescription(inModel string, fieldsPath []string, w io.Writer, swaggerSchema *swagger.ApiDeclaration, r bool) error {
5153
recursive = r // this is global for convenience
52-
apiVer := swaggerSchema.ApiVersion + "."
54+
apiVer := apiutil.GetVersion(swaggerSchema.ApiVersion) + "."
5355

5456
var pointedModel *swagger.NamedModel
5557
for i := range swaggerSchema.Models.List {
@@ -61,7 +63,7 @@ func PrintModelDescription(inModel string, fieldsPath []string, w io.Writer, swa
6163
}
6264
}
6365
if pointedModel == nil {
64-
return fmt.Errorf("Requested resourse: %s doesn't exit", inModel)
66+
return fmt.Errorf("Requested resource: %s doesn't exist", inModel)
6567
}
6668

6769
if len(fieldsPath) == 0 {
@@ -84,6 +86,15 @@ func PrintModelDescription(inModel string, fieldsPath []string, w io.Writer, swa
8486
return printModelInfo(w, pointedModel, pointedModelAsProp)
8587
}
8688

89+
func splitGroupFromResource(resource string) (string, string) {
90+
seg := strings.SplitN(resource, "/", 2)
91+
if len(seg) == 1 {
92+
return "", seg[0]
93+
} else {
94+
return seg[0], seg[1]
95+
}
96+
}
97+
8798
func splitDotNotation(model string) (string, []string) {
8899
var fieldsPath []string
89100
dotModel := strings.Split(model, ".")

0 commit comments

Comments
 (0)