Commit ed539fb7 authored by Kubernetes Submit Queue's avatar Kubernetes Submit Queue Committed by GitHub

Merge pull request #39404 from adohe/refactor_edit

Automatic merge from submit-queue add EditOptions to make edit reusable FYI. Added `EditOptions` to decouple edit implementation from cobra command, thus make edit reusable. Once this get merged, we can refactor `create` commands to put them in their own package. @kubernetes/sig-cli-misc please give a quick review, and I would like to get this merged asap.
parents 6236dfb5 5ed1ab66
......@@ -97,7 +97,6 @@ go_library(
"//pkg/kubelet/types:go_default_library",
"//pkg/printers:go_default_library",
"//pkg/printers/internalversion:go_default_library",
"//pkg/util/crlf:go_default_library",
"//pkg/util/exec:go_default_library",
"//pkg/util/i18n:go_default_library",
"//pkg/util/interrupt:go_default_library",
......@@ -132,7 +131,6 @@ go_library(
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/strategicpatch:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/validation:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/yaml:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/version:go_default_library",
......
......@@ -160,7 +160,7 @@ func (o *SetLastAppliedOptions) Validate(f cmdutil.Factory, cmd *cobra.Command)
}
//only add to PatchBufferList when changed
if !bytes.Equal(stripComments(oringalBuf), stripComments(diffBuf)) {
if !bytes.Equal(cmdutil.StripComments(oringalBuf), cmdutil.StripComments(diffBuf)) {
o.PatchBufferList = append(o.PatchBufferList, patchBuf)
o.InfoList = append(o.InfoList, info)
} else {
......
......@@ -28,6 +28,7 @@ import (
"k8s.io/kubernetes/pkg/kubectl"
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/cmd/util/editor"
"k8s.io/kubernetes/pkg/kubectl/resource"
"k8s.io/kubernetes/pkg/util/i18n"
)
......@@ -188,7 +189,25 @@ func RunCreate(f cmdutil.Factory, cmd *cobra.Command, out, errOut io.Writer, opt
}
func RunEditOnCreate(f cmdutil.Factory, out, errOut io.Writer, cmd *cobra.Command, options *resource.FilenameOptions) error {
return runEdit(f, out, errOut, cmd, []string{}, options, EditBeforeCreateMode)
editOptions := &editor.EditOptions{
EditMode: editor.EditBeforeCreateMode,
FilenameOptions: *options,
ValidateOptions: cmdutil.ValidateOptions{
EnableValidation: cmdutil.GetFlagBool(cmd, "validate"),
SchemaCacheDir: cmdutil.GetFlagString(cmd, "schema-cache-dir"),
},
Output: cmdutil.GetFlagString(cmd, "output"),
WindowsLineEndings: cmdutil.GetFlagBool(cmd, "windows-line-endings"),
ApplyAnnotation: cmdutil.GetFlagBool(cmd, cmdutil.ApplyAnnotationsFlag),
Record: cmdutil.GetFlagBool(cmd, "record"),
ChangeCause: f.Command(cmd, false),
Include3rdParty: cmdutil.GetFlagBool(cmd, "include-extended-apis"),
}
err := editOptions.Complete(f, out, errOut, []string{})
if err != nil {
return err
}
return editOptions.Run()
}
// createAndRefresh creates an object from input info and refreshes info with that object
......
......@@ -60,6 +60,7 @@ go_library(
"//vendor/k8s.io/apimachinery/pkg/util/json:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/strategicpatch:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/yaml:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/version:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/watch:go_default_library",
"//vendor/k8s.io/apiserver/pkg/util/flag:go_default_library",
......
......@@ -10,11 +10,31 @@ load(
go_library(
name = "go_default_library",
srcs = ["editor.go"],
srcs = [
"editoptions.go",
"editor.go",
],
tags = ["automanaged"],
deps = [
"//pkg/api:go_default_library",
"//pkg/kubectl:go_default_library",
"//pkg/kubectl/cmd/util:go_default_library",
"//pkg/kubectl/resource:go_default_library",
"//pkg/printers:go_default_library",
"//pkg/util/crlf:go_default_library",
"//pkg/util/term:go_default_library",
"//vendor/github.com/evanphx/json-patch:go_default_library",
"//vendor/github.com/golang/glog:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/mergepatch:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/strategicpatch:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/yaml:go_default_library",
],
)
......
......@@ -42,6 +42,7 @@ import (
"k8s.io/apimachinery/pkg/util/json"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apimachinery/pkg/util/strategicpatch"
"k8s.io/apimachinery/pkg/util/yaml"
"k8s.io/client-go/tools/clientcmd"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/apis/extensions"
......@@ -401,6 +402,12 @@ func AddValidateFlags(cmd *cobra.Command) {
cmd.MarkFlagFilename("schema-cache-dir")
}
func AddValidateOptionFlags(cmd *cobra.Command, options *ValidateOptions) {
cmd.Flags().BoolVar(&options.EnableValidation, "validate", true, "If true, use a schema to validate the input before sending it")
cmd.Flags().StringVar(&options.SchemaCacheDir, "schema-cache-dir", fmt.Sprintf("~/%s/%s", clientcmd.RecommendedHomeDir, clientcmd.RecommendedSchemaName), fmt.Sprintf("If non-empty, load/store cached API schemas in this directory, default is '$HOME/%s/%s'", clientcmd.RecommendedHomeDir, clientcmd.RecommendedSchemaName))
cmd.MarkFlagFilename("schema-cache-dir")
}
func AddFilenameOptionFlags(cmd *cobra.Command, options *resource.FilenameOptions, usage string) {
kubectl.AddJsonFilenameFlag(cmd, &options.Filenames, "Filename, directory, or URL to files "+usage)
cmd.Flags().BoolVarP(&options.Recursive, "recursive", "R", options.Recursive, "Process the directory used in -f, --filename recursively. Useful when you want to manage related manifests organized within the same directory.")
......@@ -419,6 +426,10 @@ func AddApplyAnnotationFlags(cmd *cobra.Command) {
cmd.Flags().Bool(ApplyAnnotationsFlag, false, "If true, the configuration of current object will be saved in its annotation. Otherwise, the annotation will be unchanged. This flag is useful when you want to perform kubectl apply on this object in the future.")
}
func AddApplyAnnotationVarFlags(cmd *cobra.Command, applyAnnotation *bool) {
cmd.Flags().BoolVar(applyAnnotation, ApplyAnnotationsFlag, false, "If true, the configuration of current object will be saved in its annotation. This is useful when you want to perform kubectl apply on this object in the future.")
}
// AddGeneratorFlags adds flags common to resource generation commands
// TODO: need to take a pass at other generator commands to use this set of flags
func AddGeneratorFlags(cmd *cobra.Command, defaultGenerator string) {
......@@ -426,6 +437,11 @@ func AddGeneratorFlags(cmd *cobra.Command, defaultGenerator string) {
AddDryRunFlag(cmd)
}
type ValidateOptions struct {
EnableValidation bool
SchemaCacheDir string
}
func ReadConfigDataFromReader(reader io.Reader, source string) ([]byte, error) {
data, err := ioutil.ReadAll(reader)
if err != nil {
......@@ -509,6 +525,10 @@ func AddRecordFlag(cmd *cobra.Command) {
cmd.Flags().Bool("record", false, "Record current kubectl command in the resource annotation. If set to false, do not record the command. If set to true, record the command. If not set, default to updating the existing annotation value only if one already exists.")
}
func AddRecordVarFlag(cmd *cobra.Command, record *bool) {
cmd.Flags().BoolVar(record, "record", false, "Record current kubectl command in the resource annotation. If set to false, do not record the command. If set to true, record the command. If not set, default to updating the existing annotation value only if one already exists.")
}
func GetRecordFlag(cmd *cobra.Command) bool {
return GetFlagBool(cmd, "record")
}
......@@ -577,13 +597,13 @@ func ShouldRecord(cmd *cobra.Command, info *resource.Info) bool {
return GetRecordFlag(cmd) || (ContainsChangeCause(info) && !cmd.Flags().Changed("record"))
}
func AddInclude3rdPartyVarFlags(cmd *cobra.Command, include3rdParty *bool) {
cmd.Flags().BoolVar(include3rdParty, "include-extended-apis", true, "If true, include definitions of new APIs via calls to the API server. [default true]")
func AddInclude3rdPartyFlags(cmd *cobra.Command) {
cmd.Flags().Bool("include-extended-apis", true, "If true, include definitions of new APIs via calls to the API server. [default true]")
cmd.Flags().MarkDeprecated("include-extended-apis", "No longer required.")
}
func AddInclude3rdPartyFlags(cmd *cobra.Command) {
cmd.Flags().Bool("include-extended-apis", true, "If true, include definitions of new APIs via calls to the API server. [default true]")
func AddInclude3rdPartyVarFlags(cmd *cobra.Command, include3rdParty *bool) {
cmd.Flags().BoolVar(include3rdParty, "include-extended-apis", true, "If true, include definitions of new APIs via calls to the API server. [default true]")
cmd.Flags().MarkDeprecated("include-extended-apis", "No longer required.")
}
......@@ -788,3 +808,31 @@ func OutputsRawFormat(cmd *cobra.Command) bool {
return false
}
// StripComments will transform a YAML file into JSON, thus dropping any comments
// in it. Note that if the given file has a syntax error, the transformation will
// fail and we will manually drop all comments from the file.
func StripComments(file []byte) []byte {
stripped := file
stripped, err := yaml.ToJSON(stripped)
if err != nil {
stripped = ManualStrip(file)
}
return stripped
}
// ManualStrip is used for dropping comments from a YAML file
func ManualStrip(file []byte) []byte {
stripped := []byte{}
lines := bytes.Split(file, []byte("\n"))
for i, line := range lines {
if bytes.HasPrefix(bytes.TrimSpace(line), []byte("#")) {
continue
}
stripped = append(stripped, line...)
if i < len(lines)-1 {
stripped = append(stripped, '\n')
}
}
return stripped
}
......@@ -648,6 +648,16 @@ func RetrieveLazy(info *Info, err error) error {
return nil
}
// CreateAndRefresh creates an object from input info and refreshes info with that object
func CreateAndRefresh(info *Info) error {
obj, err := NewHelper(info.Client, info.Mapping).Create(info.Namespace, true, info.Object)
if err != nil {
return err
}
info.Refresh(obj, true)
return nil
}
type FilterFunc func(info *Info, err error) (bool, error)
type FilteredVisitor struct {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment