mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 03:41:45 +00:00
add KUBECTL_EXPLAIN_OPENAPIV3
envar to gate new explain implementation
update
This commit is contained in:
parent
a9c093b165
commit
2f16cd4aea
@ -18,14 +18,17 @@ package explain
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/cli-runtime/pkg/genericclioptions"
|
||||
"k8s.io/client-go/discovery"
|
||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||
"k8s.io/kubectl/pkg/explain"
|
||||
explainv2 "k8s.io/kubectl/pkg/explain/v2"
|
||||
"k8s.io/kubectl/pkg/util/i18n"
|
||||
"k8s.io/kubectl/pkg/util/openapi"
|
||||
"k8s.io/kubectl/pkg/util/templates"
|
||||
@ -62,12 +65,25 @@ type ExplainOptions struct {
|
||||
|
||||
Mapper meta.RESTMapper
|
||||
Schema openapi.Resources
|
||||
|
||||
// Toggles whether the OpenAPI v3 template-based renderer should be used to show
|
||||
// output.
|
||||
EnableOpenAPIV3 bool
|
||||
|
||||
// Name of the template to use with the openapiv3 template renderer. If
|
||||
// `EnableOpenAPIV3` is disabled, this does nothing
|
||||
OutputFormat string
|
||||
|
||||
// Client capable of fetching openapi documents from the user's cluster
|
||||
DiscoveryClient discovery.DiscoveryInterface
|
||||
}
|
||||
|
||||
func NewExplainOptions(parent string, streams genericclioptions.IOStreams) *ExplainOptions {
|
||||
return &ExplainOptions{
|
||||
IOStreams: streams,
|
||||
CmdParent: parent,
|
||||
IOStreams: streams,
|
||||
CmdParent: parent,
|
||||
EnableOpenAPIV3: os.Getenv("KUBECTL_EXPLAIN_OPENAPIV3") == "true",
|
||||
OutputFormat: "plaintext",
|
||||
}
|
||||
}
|
||||
|
||||
@ -89,6 +105,12 @@ func NewCmdExplain(parent string, f cmdutil.Factory, streams genericclioptions.I
|
||||
}
|
||||
cmd.Flags().BoolVar(&o.Recursive, "recursive", o.Recursive, "Print the fields of fields (Currently only 1 level deep)")
|
||||
cmd.Flags().StringVar(&o.APIVersion, "api-version", o.APIVersion, "Get different explanations for particular API version (API group/version)")
|
||||
|
||||
// Only enable --output as a valid flag if the feature is enabled
|
||||
if o.EnableOpenAPIV3 {
|
||||
cmd.Flags().StringVar(&o.OutputFormat, "output", o.OutputFormat, "Format in which to render the schema")
|
||||
}
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
@ -104,6 +126,15 @@ func (o *ExplainOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []
|
||||
return err
|
||||
}
|
||||
|
||||
// Only openapi v3 needs the discovery client.
|
||||
if o.EnableOpenAPIV3 {
|
||||
clientset, err := f.KubernetesClientSet()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
o.DiscoveryClient = clientset.DiscoveryClient
|
||||
}
|
||||
|
||||
o.args = args
|
||||
return nil
|
||||
}
|
||||
@ -142,6 +173,17 @@ func (o *ExplainOptions) Run() error {
|
||||
}
|
||||
}
|
||||
|
||||
if o.EnableOpenAPIV3 {
|
||||
return explainv2.PrintModelDescription(
|
||||
fieldsPath,
|
||||
o.Out,
|
||||
o.DiscoveryClient.OpenAPIV3(),
|
||||
fullySpecifiedGVR,
|
||||
recursive,
|
||||
o.OutputFormat,
|
||||
)
|
||||
}
|
||||
|
||||
gvk, _ := o.Mapper.KindFor(fullySpecifiedGVR)
|
||||
if gvk.Empty() {
|
||||
gvk, err = o.Mapper.KindFor(fullySpecifiedGVR.GroupResource().WithVersion(""))
|
||||
|
84
staging/src/k8s.io/kubectl/pkg/explain/v2/explain.go
Normal file
84
staging/src/k8s.io/kubectl/pkg/explain/v2/explain.go
Normal file
@ -0,0 +1,84 @@
|
||||
/*
|
||||
Copyright 2022 The Kubernetes Authors.
|
||||
|
||||
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 v2
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/client-go/openapi"
|
||||
)
|
||||
|
||||
// PrintModelDescription prints the description of a specific model or dot path.
|
||||
// If recursive, all components nested within the fields of the schema will be
|
||||
// printed.
|
||||
func PrintModelDescription(
|
||||
fieldsPath []string,
|
||||
w io.Writer,
|
||||
client openapi.Client,
|
||||
gvr schema.GroupVersionResource,
|
||||
recursive bool,
|
||||
outputFormat string,
|
||||
) error {
|
||||
return printModelDescriptionWithGenerator(
|
||||
NewGenerator(), fieldsPath, w, client, gvr, recursive, outputFormat)
|
||||
}
|
||||
|
||||
// Factored out for testability
|
||||
func printModelDescriptionWithGenerator(
|
||||
generator *generator,
|
||||
fieldsPath []string,
|
||||
w io.Writer,
|
||||
client openapi.Client,
|
||||
gvr schema.GroupVersionResource,
|
||||
recursive bool,
|
||||
outputFormat string,
|
||||
) error {
|
||||
paths, err := client.Paths()
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to fetch list of groupVersions: %w", err)
|
||||
}
|
||||
|
||||
var resourcePath string
|
||||
if len(gvr.Group) == 0 {
|
||||
resourcePath = fmt.Sprintf("api/%s", gvr.Version)
|
||||
} else {
|
||||
resourcePath = fmt.Sprintf("apis/%s/%s", gvr.Group, gvr.Version)
|
||||
}
|
||||
|
||||
gv, exists := paths[resourcePath]
|
||||
|
||||
if !exists {
|
||||
return fmt.Errorf("could not locate schema for %s", resourcePath)
|
||||
}
|
||||
|
||||
openAPISchemaBytes, err := gv.Schema(runtime.ContentTypeJSON)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to fetch openapi schema for %s: %w", resourcePath, err)
|
||||
}
|
||||
|
||||
var parsedV3Schema map[string]interface{}
|
||||
if err := json.Unmarshal(openAPISchemaBytes, &parsedV3Schema); err != nil {
|
||||
return fmt.Errorf("failed to parse openapi schema for %s: %w", resourcePath, err)
|
||||
}
|
||||
|
||||
return generator.Render(outputFormat, parsedV3Schema, gvr, fieldsPath, recursive, w)
|
||||
}
|
Loading…
Reference in New Issue
Block a user