mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-29 14:37:00 +00:00
Merge pull request #15808 from caesarxuchao/fix-kubectl-explain
Auto commit by PR queue bot
This commit is contained in:
commit
071d21257f
@ -26,7 +26,6 @@ import (
|
||||
"github.com/emicklei/go-restful/swagger"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/latest"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
"k8s.io/kubernetes/pkg/version"
|
||||
)
|
||||
@ -184,26 +183,32 @@ func (c *Client) ValidateComponents() (*api.ComponentStatusList, error) {
|
||||
// SwaggerSchemaInterface has a method to retrieve the swagger schema. Used in
|
||||
// client.Interface
|
||||
type SwaggerSchemaInterface interface {
|
||||
SwaggerSchema(version string) (*swagger.ApiDeclaration, error)
|
||||
SwaggerSchema(groupVersion string) (*swagger.ApiDeclaration, error)
|
||||
}
|
||||
|
||||
// SwaggerSchema retrieves and parses the swagger API schema the server supports.
|
||||
func (c *Client) SwaggerSchema(version string) (*swagger.ApiDeclaration, error) {
|
||||
if version == "" {
|
||||
version = latest.GroupOrDie("").Version
|
||||
func (c *Client) SwaggerSchema(groupVersion string) (*swagger.ApiDeclaration, error) {
|
||||
if groupVersion == "" {
|
||||
return nil, fmt.Errorf("groupVersion cannot be empty")
|
||||
}
|
||||
|
||||
vers, err := c.ServerAPIVersions()
|
||||
groupList, err := c.Discovery().ServerGroups()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
groupVersions := extractGroupVersions(groupList)
|
||||
// This check also takes care the case that kubectl is newer than the running endpoint
|
||||
if stringDoesntExistIn(version, vers.Versions) {
|
||||
return nil, fmt.Errorf("API version: %s is not supported by the server. Use one of: %v", version, vers.Versions)
|
||||
if stringDoesntExistIn(groupVersion, groupVersions) {
|
||||
return nil, fmt.Errorf("API version: %s is not supported by the server. Use one of: %v", groupVersion, groupVersions)
|
||||
}
|
||||
var path string
|
||||
if groupVersion == "v1" {
|
||||
path = "/swaggerapi/api/" + groupVersion
|
||||
} else {
|
||||
path = "/swaggerapi/apis/" + groupVersion
|
||||
}
|
||||
|
||||
body, err := c.Get().AbsPath("/swaggerapi/api/" + version).Do().Raw()
|
||||
body, err := c.Get().AbsPath(path).Do().Raw()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ import (
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api/latest"
|
||||
"k8s.io/kubernetes/pkg/kubectl"
|
||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||
)
|
||||
@ -70,13 +71,28 @@ func RunExplain(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []st
|
||||
recursive := cmdutil.GetFlagBool(cmd, "recursive")
|
||||
apiV := cmdutil.GetFlagString(cmd, "api-version")
|
||||
|
||||
swagSchema, err := kubectl.GetSwaggerSchema(apiV, client)
|
||||
mapper, _ := f.Object()
|
||||
group, inModel, fieldsPath, err := kubectl.SplitAndParseResourceRequest(args[0], mapper)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
mapper, _ := f.Object()
|
||||
inModel, fieldsPath, err := kubectl.SplitAndParseResourceRequest(args[0], mapper)
|
||||
if len(group) == 0 {
|
||||
// TODO: We should deduce the group for a resource by discovering the supported resources at server.
|
||||
group, err = mapper.GroupForResource(inModel)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if len(apiV) == 0 {
|
||||
groupMeta, err := latest.Group(group)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
apiV = groupMeta.GroupVersion
|
||||
}
|
||||
swagSchema, err := kubectl.GetSwaggerSchema(apiV, client)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ import (
|
||||
"github.com/emicklei/go-restful/swagger"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api/meta"
|
||||
apiutil "k8s.io/kubernetes/pkg/api/util"
|
||||
client "k8s.io/kubernetes/pkg/client/unversioned"
|
||||
)
|
||||
|
||||
@ -40,16 +41,17 @@ func GetSwaggerSchema(apiVer string, kubeClient client.Interface) (*swagger.ApiD
|
||||
}
|
||||
|
||||
// SplitAndParseResourceRequest separates the users input into a model and fields
|
||||
func SplitAndParseResourceRequest(inResource string, mapper meta.RESTMapper) (string, []string, error) {
|
||||
func SplitAndParseResourceRequest(inResource string, mapper meta.RESTMapper) (string, string, []string, error) {
|
||||
inResource, fieldsPath := splitDotNotation(inResource)
|
||||
group, inResource := splitGroupFromResource(inResource)
|
||||
inResource, _ = mapper.ResourceSingularizer(expandResourceShortcut(inResource))
|
||||
return inResource, fieldsPath, nil
|
||||
return group, inResource, fieldsPath, nil
|
||||
}
|
||||
|
||||
// PrintModelDescription prints the description of a specific model or dot path
|
||||
func PrintModelDescription(inModel string, fieldsPath []string, w io.Writer, swaggerSchema *swagger.ApiDeclaration, r bool) error {
|
||||
recursive = r // this is global for convenience
|
||||
apiVer := swaggerSchema.ApiVersion + "."
|
||||
apiVer := apiutil.GetVersion(swaggerSchema.ApiVersion) + "."
|
||||
|
||||
var pointedModel *swagger.NamedModel
|
||||
for i := range swaggerSchema.Models.List {
|
||||
@ -61,7 +63,7 @@ func PrintModelDescription(inModel string, fieldsPath []string, w io.Writer, swa
|
||||
}
|
||||
}
|
||||
if pointedModel == nil {
|
||||
return fmt.Errorf("Requested resourse: %s doesn't exit", inModel)
|
||||
return fmt.Errorf("Requested resource: %s doesn't exist", inModel)
|
||||
}
|
||||
|
||||
if len(fieldsPath) == 0 {
|
||||
@ -84,6 +86,15 @@ func PrintModelDescription(inModel string, fieldsPath []string, w io.Writer, swa
|
||||
return printModelInfo(w, pointedModel, pointedModelAsProp)
|
||||
}
|
||||
|
||||
func splitGroupFromResource(resource string) (string, string) {
|
||||
seg := strings.SplitN(resource, "/", 2)
|
||||
if len(seg) == 1 {
|
||||
return "", seg[0]
|
||||
} else {
|
||||
return seg[0], seg[1]
|
||||
}
|
||||
}
|
||||
|
||||
func splitDotNotation(model string) (string, []string) {
|
||||
var fieldsPath []string
|
||||
dotModel := strings.Split(model, ".")
|
||||
|
Loading…
Reference in New Issue
Block a user