mirror of https://github.com/k3s-io/k3s
Merge pull request #74140 from Liujingfang1/kflag
add -k flag in cli-runtime and kubectl to process kustomization directoriespull/564/head
commit
81e6407393
|
@ -0,0 +1,7 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: the-map
|
||||||
|
data:
|
||||||
|
altGreeting: "Good Morning!"
|
||||||
|
enableRisky: "false"
|
|
@ -0,0 +1,35 @@
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: the-deployment
|
||||||
|
labels:
|
||||||
|
deployment: hello
|
||||||
|
spec:
|
||||||
|
replicas: 3
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
deployment: hello
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
deployment: hello
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: the-container
|
||||||
|
image: monopole/hello:1
|
||||||
|
command: ["/hello",
|
||||||
|
"--port=8080",
|
||||||
|
"--enableRiskyFeature=$(ENABLE_RISKY)"]
|
||||||
|
ports:
|
||||||
|
- containerPort: 8080
|
||||||
|
env:
|
||||||
|
- name: ALT_GREETING
|
||||||
|
valueFrom:
|
||||||
|
configMapKeyRef:
|
||||||
|
name: the-map
|
||||||
|
key: altGreeting
|
||||||
|
- name: ENABLE_RISKY
|
||||||
|
valueFrom:
|
||||||
|
configMapKeyRef:
|
||||||
|
name: the-map
|
||||||
|
key: enableRisky
|
|
@ -0,0 +1,5 @@
|
||||||
|
nameprefix: test-
|
||||||
|
resources:
|
||||||
|
- deployment.yaml
|
||||||
|
- service.yaml
|
||||||
|
- configmap.yaml
|
|
@ -0,0 +1,12 @@
|
||||||
|
kind: Service
|
||||||
|
apiVersion: v1
|
||||||
|
metadata:
|
||||||
|
name: the-service
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
deployment: hello
|
||||||
|
type: LoadBalancer
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: 8666
|
||||||
|
targetPort: 8080
|
|
@ -208,7 +208,7 @@ func (o AnnotateOptions) Validate() error {
|
||||||
if o.all && len(o.fieldSelector) > 0 {
|
if o.all && len(o.fieldSelector) > 0 {
|
||||||
return fmt.Errorf("cannot set --all and --field-selector at the same time")
|
return fmt.Errorf("cannot set --all and --field-selector at the same time")
|
||||||
}
|
}
|
||||||
if len(o.resources) < 1 && cmdutil.IsFilenameSliceEmpty(o.Filenames) {
|
if len(o.resources) < 1 && cmdutil.IsFilenameSliceEmpty(o.Filenames, o.Kustomize) {
|
||||||
return fmt.Errorf("one or more resources must be specified as <resource> <name> or <resource>/<name>")
|
return fmt.Errorf("one or more resources must be specified as <resource> <name> or <resource>/<name>")
|
||||||
}
|
}
|
||||||
if len(o.newAnnotations) < 1 && len(o.removeAnnotations) < 1 {
|
if len(o.newAnnotations) < 1 && len(o.removeAnnotations) < 1 {
|
||||||
|
|
|
@ -115,6 +115,9 @@ var (
|
||||||
# Apply the configuration in pod.json to a pod.
|
# Apply the configuration in pod.json to a pod.
|
||||||
kubectl apply -f ./pod.json
|
kubectl apply -f ./pod.json
|
||||||
|
|
||||||
|
# Apply resources from a directory containing kustomization.yaml - e.g. dir/kustomization.yaml.
|
||||||
|
kubectl apply -k dir/
|
||||||
|
|
||||||
# Apply the JSON passed into stdin to a pod.
|
# Apply the JSON passed into stdin to a pod.
|
||||||
cat pod.json | kubectl apply -f -
|
cat pod.json | kubectl apply -f -
|
||||||
|
|
||||||
|
@ -152,7 +155,7 @@ func NewCmdApply(baseName string, f cmdutil.Factory, ioStreams genericclioptions
|
||||||
o.cmdBaseName = baseName
|
o.cmdBaseName = baseName
|
||||||
|
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "apply -f FILENAME",
|
Use: "apply (-f FILENAME | -k DIRECTORY)",
|
||||||
DisableFlagsInUseLine: true,
|
DisableFlagsInUseLine: true,
|
||||||
Short: i18n.T("Apply a configuration to a resource by filename or stdin"),
|
Short: i18n.T("Apply a configuration to a resource by filename or stdin"),
|
||||||
Long: applyLong,
|
Long: applyLong,
|
||||||
|
@ -170,7 +173,6 @@ func NewCmdApply(baseName string, f cmdutil.Factory, ioStreams genericclioptions
|
||||||
o.RecordFlags.AddFlags(cmd)
|
o.RecordFlags.AddFlags(cmd)
|
||||||
o.PrintFlags.AddFlags(cmd)
|
o.PrintFlags.AddFlags(cmd)
|
||||||
|
|
||||||
cmd.MarkFlagRequired("filename")
|
|
||||||
cmd.Flags().BoolVar(&o.Overwrite, "overwrite", o.Overwrite, "Automatically resolve conflicts between the modified and live configuration by using values from the modified configuration")
|
cmd.Flags().BoolVar(&o.Overwrite, "overwrite", o.Overwrite, "Automatically resolve conflicts between the modified and live configuration by using values from the modified configuration")
|
||||||
cmd.Flags().BoolVar(&o.Prune, "prune", o.Prune, "Automatically delete resource objects, including the uninitialized ones, that do not appear in the configs and are created by either apply or create --save-config. Should be used with either -l or --all.")
|
cmd.Flags().BoolVar(&o.Prune, "prune", o.Prune, "Automatically delete resource objects, including the uninitialized ones, that do not appear in the configs and are created by either apply or create --save-config. Should be used with either -l or --all.")
|
||||||
cmdutil.AddValidateFlags(cmd)
|
cmdutil.AddValidateFlags(cmd)
|
||||||
|
@ -237,6 +239,10 @@ func (o *ApplyOptions) Complete(f cmdutil.Factory, cmd *cobra.Command) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
o.DeleteOptions = o.DeleteFlags.ToOptions(dynamicClient, o.IOStreams)
|
o.DeleteOptions = o.DeleteFlags.ToOptions(dynamicClient, o.IOStreams)
|
||||||
|
err = o.DeleteOptions.FilenameOptions.RequireFilenameOrKustomize()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
o.OpenAPISchema, _ = f.OpenAPISchema()
|
o.OpenAPISchema, _ = f.OpenAPISchema()
|
||||||
o.Validator, err = f.Validator(cmdutil.GetFlagBool(cmd, "validate"))
|
o.Validator, err = f.Validator(cmdutil.GetFlagBool(cmd, "validate"))
|
||||||
|
|
|
@ -107,13 +107,16 @@ func NewCmdReconcile(f cmdutil.Factory, streams genericclioptions.IOStreams) *co
|
||||||
cmd.Flags().BoolVar(&o.DryRun, "dry-run", o.DryRun, "If true, display results but do not submit changes")
|
cmd.Flags().BoolVar(&o.DryRun, "dry-run", o.DryRun, "If true, display results but do not submit changes")
|
||||||
cmd.Flags().BoolVar(&o.RemoveExtraPermissions, "remove-extra-permissions", o.RemoveExtraPermissions, "If true, removes extra permissions added to roles")
|
cmd.Flags().BoolVar(&o.RemoveExtraPermissions, "remove-extra-permissions", o.RemoveExtraPermissions, "If true, removes extra permissions added to roles")
|
||||||
cmd.Flags().BoolVar(&o.RemoveExtraSubjects, "remove-extra-subjects", o.RemoveExtraSubjects, "If true, removes extra subjects added to rolebindings")
|
cmd.Flags().BoolVar(&o.RemoveExtraSubjects, "remove-extra-subjects", o.RemoveExtraSubjects, "If true, removes extra subjects added to rolebindings")
|
||||||
cmd.MarkFlagRequired("filename")
|
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
// Complete completes all the required options
|
// Complete completes all the required options
|
||||||
func (o *ReconcileOptions) Complete(cmd *cobra.Command, f cmdutil.Factory, args []string) error {
|
func (o *ReconcileOptions) Complete(cmd *cobra.Command, f cmdutil.Factory, args []string) error {
|
||||||
|
if err := o.FilenameOptions.RequireFilenameOrKustomize(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
if len(args) > 0 {
|
if len(args) > 0 {
|
||||||
return errors.New("no arguments are allowed")
|
return errors.New("no arguments are allowed")
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,7 +104,7 @@ func (o *CertificateOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, arg
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *CertificateOptions) Validate() error {
|
func (o *CertificateOptions) Validate() error {
|
||||||
if len(o.csrNames) < 1 && cmdutil.IsFilenameSliceEmpty(o.Filenames) {
|
if len(o.csrNames) < 1 && cmdutil.IsFilenameSliceEmpty(o.Filenames, o.Kustomize) {
|
||||||
return fmt.Errorf("one or more CSRs must be specified as <name> or -f <filename>")
|
return fmt.Errorf("one or more CSRs must be specified as <name> or -f <filename>")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -107,12 +107,15 @@ func NewCmdConvert(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *co
|
||||||
|
|
||||||
cmdutil.AddValidateFlags(cmd)
|
cmdutil.AddValidateFlags(cmd)
|
||||||
cmdutil.AddFilenameOptionFlags(cmd, &o.FilenameOptions, "to need to get converted.")
|
cmdutil.AddFilenameOptionFlags(cmd, &o.FilenameOptions, "to need to get converted.")
|
||||||
cmd.MarkFlagRequired("filename")
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
// Complete collects information required to run Convert command from command line.
|
// Complete collects information required to run Convert command from command line.
|
||||||
func (o *ConvertOptions) Complete(f cmdutil.Factory, cmd *cobra.Command) (err error) {
|
func (o *ConvertOptions) Complete(f cmdutil.Factory, cmd *cobra.Command) (err error) {
|
||||||
|
err = o.FilenameOptions.RequireFilenameOrKustomize()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
o.builder = f.NewBuilder
|
o.builder = f.NewBuilder
|
||||||
|
|
||||||
o.Namespace, _, err = f.ToRawKubeConfigLoader().Namespace()
|
o.Namespace, _, err = f.ToRawKubeConfigLoader().Namespace()
|
||||||
|
|
|
@ -103,7 +103,8 @@ func NewCmdCreate(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cob
|
||||||
Long: createLong,
|
Long: createLong,
|
||||||
Example: createExample,
|
Example: createExample,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
if cmdutil.IsFilenameSliceEmpty(o.FilenameOptions.Filenames) {
|
if cmdutil.IsFilenameSliceEmpty(o.FilenameOptions.Filenames, o.FilenameOptions.Kustomize) {
|
||||||
|
ioStreams.ErrOut.Write([]byte("Error: must specify one of -f and -k\n\n"))
|
||||||
defaultRunFunc := cmdutil.DefaultSubCommandRun(ioStreams.ErrOut)
|
defaultRunFunc := cmdutil.DefaultSubCommandRun(ioStreams.ErrOut)
|
||||||
defaultRunFunc(cmd, args)
|
defaultRunFunc(cmd, args)
|
||||||
return
|
return
|
||||||
|
@ -119,7 +120,6 @@ func NewCmdCreate(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cob
|
||||||
|
|
||||||
usage := "to use to create the resource"
|
usage := "to use to create the resource"
|
||||||
cmdutil.AddFilenameOptionFlags(cmd, &o.FilenameOptions, usage)
|
cmdutil.AddFilenameOptionFlags(cmd, &o.FilenameOptions, usage)
|
||||||
cmd.MarkFlagRequired("filename")
|
|
||||||
cmdutil.AddValidateFlags(cmd)
|
cmdutil.AddValidateFlags(cmd)
|
||||||
cmd.Flags().BoolVar(&o.EditBeforeCreate, "edit", o.EditBeforeCreate, "Edit the API resource before creating")
|
cmd.Flags().BoolVar(&o.EditBeforeCreate, "edit", o.EditBeforeCreate, "Edit the API resource before creating")
|
||||||
cmd.Flags().Bool("windows-line-endings", runtime.GOOS == "windows",
|
cmd.Flags().Bool("windows-line-endings", runtime.GOOS == "windows",
|
||||||
|
@ -184,7 +184,6 @@ func (o *CreateOptions) ValidateArgs(cmd *cobra.Command, args []string) error {
|
||||||
// Complete completes all the required options
|
// Complete completes all the required options
|
||||||
func (o *CreateOptions) Complete(f cmdutil.Factory, cmd *cobra.Command) error {
|
func (o *CreateOptions) Complete(f cmdutil.Factory, cmd *cobra.Command) error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
o.RecordFlags.Complete(cmd)
|
o.RecordFlags.Complete(cmd)
|
||||||
o.Recorder, err = o.RecordFlags.ToRecorder()
|
o.Recorder, err = o.RecordFlags.ToRecorder()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -71,6 +71,9 @@ var (
|
||||||
# Delete a pod using the type and name specified in pod.json.
|
# Delete a pod using the type and name specified in pod.json.
|
||||||
kubectl delete -f ./pod.json
|
kubectl delete -f ./pod.json
|
||||||
|
|
||||||
|
# Delete resources from a directory containing kustomization.yaml - e.g. dir/kustomization.yaml.
|
||||||
|
kubectl delete -k dir
|
||||||
|
|
||||||
# Delete a pod based on the type and name in the JSON passed into stdin.
|
# Delete a pod based on the type and name in the JSON passed into stdin.
|
||||||
cat pod.json | kubectl delete -f -
|
cat pod.json | kubectl delete -f -
|
||||||
|
|
||||||
|
@ -120,7 +123,7 @@ func NewCmdDelete(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra
|
||||||
deleteFlags := NewDeleteCommandFlags("containing the resource to delete.")
|
deleteFlags := NewDeleteCommandFlags("containing the resource to delete.")
|
||||||
|
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "delete ([-f FILENAME] | TYPE [(NAME | -l label | --all)])",
|
Use: "delete ([-f FILENAME] | [-k DIRECTORY] | TYPE [(NAME | -l label | --all)])",
|
||||||
DisableFlagsInUseLine: true,
|
DisableFlagsInUseLine: true,
|
||||||
Short: i18n.T("Delete resources by filenames, stdin, resources and names, or by resources and label selector"),
|
Short: i18n.T("Delete resources by filenames, stdin, resources and names, or by resources and label selector"),
|
||||||
Long: deleteLong,
|
Long: deleteLong,
|
||||||
|
|
|
@ -156,9 +156,11 @@ func NewDeleteCommandFlags(usage string) *DeleteFlags {
|
||||||
|
|
||||||
filenames := []string{}
|
filenames := []string{}
|
||||||
recursive := false
|
recursive := false
|
||||||
|
kustomize := ""
|
||||||
|
|
||||||
return &DeleteFlags{
|
return &DeleteFlags{
|
||||||
FileNameFlags: &genericclioptions.FileNameFlags{Usage: usage, Filenames: &filenames, Recursive: &recursive},
|
// Not using helpers.go since it provides function to add '-k' for FileNameOptions, but not FileNameFlags
|
||||||
|
FileNameFlags: &genericclioptions.FileNameFlags{Usage: usage, Filenames: &filenames, Kustomize: &kustomize, Recursive: &recursive},
|
||||||
LabelSelector: &labelSelector,
|
LabelSelector: &labelSelector,
|
||||||
FieldSelector: &fieldSelector,
|
FieldSelector: &fieldSelector,
|
||||||
|
|
||||||
|
@ -186,10 +188,11 @@ func NewDeleteFlags(usage string) *DeleteFlags {
|
||||||
wait := false
|
wait := false
|
||||||
|
|
||||||
filenames := []string{}
|
filenames := []string{}
|
||||||
|
kustomize := ""
|
||||||
recursive := false
|
recursive := false
|
||||||
|
|
||||||
return &DeleteFlags{
|
return &DeleteFlags{
|
||||||
FileNameFlags: &genericclioptions.FileNameFlags{Usage: usage, Filenames: &filenames, Recursive: &recursive},
|
FileNameFlags: &genericclioptions.FileNameFlags{Usage: usage, Filenames: &filenames, Kustomize: &kustomize, Recursive: &recursive},
|
||||||
|
|
||||||
Cascade: &cascade,
|
Cascade: &cascade,
|
||||||
GracePeriod: &gracePeriod,
|
GracePeriod: &gracePeriod,
|
||||||
|
|
|
@ -131,7 +131,7 @@ func (o *DescribeOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args [
|
||||||
o.EnforceNamespace = false
|
o.EnforceNamespace = false
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(args) == 0 && cmdutil.IsFilenameSliceEmpty(o.FilenameOptions.Filenames) {
|
if len(args) == 0 && cmdutil.IsFilenameSliceEmpty(o.FilenameOptions.Filenames, o.FilenameOptions.Kustomize) {
|
||||||
return fmt.Errorf("You must specify the type of resource to describe. %s\n", cmdutil.SuggestAPIResources(o.CmdParent))
|
return fmt.Errorf("You must specify the type of resource to describe. %s\n", cmdutil.SuggestAPIResources(o.CmdParent))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -118,7 +118,6 @@ func NewCmdDiff(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.C
|
||||||
usage := "contains the configuration to diff"
|
usage := "contains the configuration to diff"
|
||||||
cmdutil.AddFilenameOptionFlags(cmd, &options.FilenameOptions, usage)
|
cmdutil.AddFilenameOptionFlags(cmd, &options.FilenameOptions, usage)
|
||||||
cmdutil.AddServerSideApplyFlags(cmd)
|
cmdutil.AddServerSideApplyFlags(cmd)
|
||||||
cmd.MarkFlagRequired("filename")
|
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
@ -395,6 +394,11 @@ func isConflict(err error) bool {
|
||||||
func (o *DiffOptions) Complete(f cmdutil.Factory, cmd *cobra.Command) error {
|
func (o *DiffOptions) Complete(f cmdutil.Factory, cmd *cobra.Command) error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
|
err = o.FilenameOptions.RequireFilenameOrKustomize()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
o.ServerSideApply = cmdutil.GetServerSideApplyFlag(cmd)
|
o.ServerSideApply = cmdutil.GetServerSideApplyFlag(cmd)
|
||||||
o.ForceConflicts = cmdutil.GetForceConflictsFlag(cmd)
|
o.ForceConflicts = cmdutil.GetForceConflictsFlag(cmd)
|
||||||
if o.ForceConflicts && !o.ServerSideApply {
|
if o.ForceConflicts && !o.ServerSideApply {
|
||||||
|
|
|
@ -115,6 +115,9 @@ var (
|
||||||
# List a pod identified by type and name specified in "pod.yaml" in JSON output format.
|
# List a pod identified by type and name specified in "pod.yaml" in JSON output format.
|
||||||
kubectl get -f pod.yaml -o json
|
kubectl get -f pod.yaml -o json
|
||||||
|
|
||||||
|
# List resources from a directory with kustomization.yaml - e.g. dir/kustomization.yaml.
|
||||||
|
kubectl get -k dir/
|
||||||
|
|
||||||
# Return only the phase value of the specified pod.
|
# Return only the phase value of the specified pod.
|
||||||
kubectl get -o template pod/web-pod-13je7 --template={{.status.phase}}
|
kubectl get -o template pod/web-pod-13je7 --template={{.status.phase}}
|
||||||
|
|
||||||
|
@ -257,7 +260,7 @@ func (o *GetOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []stri
|
||||||
switch {
|
switch {
|
||||||
case o.Watch || o.WatchOnly:
|
case o.Watch || o.WatchOnly:
|
||||||
default:
|
default:
|
||||||
if len(args) == 0 && cmdutil.IsFilenameSliceEmpty(o.Filenames) {
|
if len(args) == 0 && cmdutil.IsFilenameSliceEmpty(o.Filenames, o.Kustomize) {
|
||||||
fmt.Fprintf(o.ErrOut, "You must specify the type of resource to get. %s\n\n", cmdutil.SuggestAPIResources(o.CmdParent))
|
fmt.Fprintf(o.ErrOut, "You must specify the type of resource to get. %s\n\n", cmdutil.SuggestAPIResources(o.CmdParent))
|
||||||
fullCmdName := cmd.Parent().CommandPath()
|
fullCmdName := cmd.Parent().CommandPath()
|
||||||
usageString := "Required resource not specified."
|
usageString := "Required resource not specified."
|
||||||
|
|
|
@ -205,7 +205,7 @@ func (o *LabelOptions) Validate() error {
|
||||||
if o.all && len(o.fieldSelector) > 0 {
|
if o.all && len(o.fieldSelector) > 0 {
|
||||||
return fmt.Errorf("cannot set --all and --field-selector at the same time")
|
return fmt.Errorf("cannot set --all and --field-selector at the same time")
|
||||||
}
|
}
|
||||||
if len(o.resources) < 1 && cmdutil.IsFilenameSliceEmpty(o.FilenameOptions.Filenames) {
|
if len(o.resources) < 1 && cmdutil.IsFilenameSliceEmpty(o.FilenameOptions.Filenames, o.FilenameOptions.Kustomize) {
|
||||||
return fmt.Errorf("one or more resources must be specified as <resource> <name> or <resource>/<name>")
|
return fmt.Errorf("one or more resources must be specified as <resource> <name> or <resource>/<name>")
|
||||||
}
|
}
|
||||||
if len(o.newLabels) < 1 && len(o.removeLabels) < 1 && !o.list {
|
if len(o.newLabels) < 1 && len(o.removeLabels) < 1 && !o.list {
|
||||||
|
|
|
@ -117,7 +117,6 @@ func NewCmdReplace(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobr
|
||||||
o.DeleteFlags.AddFlags(cmd)
|
o.DeleteFlags.AddFlags(cmd)
|
||||||
o.RecordFlags.AddFlags(cmd)
|
o.RecordFlags.AddFlags(cmd)
|
||||||
|
|
||||||
cmd.MarkFlagRequired("filename")
|
|
||||||
cmdutil.AddValidateFlags(cmd)
|
cmdutil.AddValidateFlags(cmd)
|
||||||
cmdutil.AddApplyAnnotationFlags(cmd)
|
cmdutil.AddApplyAnnotationFlags(cmd)
|
||||||
|
|
||||||
|
@ -163,6 +162,11 @@ func (o *ReplaceOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []
|
||||||
}
|
}
|
||||||
o.DeleteOptions = deleteOpts
|
o.DeleteOptions = deleteOpts
|
||||||
|
|
||||||
|
err = o.DeleteOptions.FilenameOptions.RequireFilenameOrKustomize()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
schema, err := f.Validator(o.validate)
|
schema, err := f.Validator(o.validate)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -189,7 +193,7 @@ func (o *ReplaceOptions) Validate(cmd *cobra.Command) error {
|
||||||
return fmt.Errorf("--timeout must have --force specified")
|
return fmt.Errorf("--timeout must have --force specified")
|
||||||
}
|
}
|
||||||
|
|
||||||
if cmdutil.IsFilenameSliceEmpty(o.DeleteOptions.FilenameOptions.Filenames) {
|
if cmdutil.IsFilenameSliceEmpty(o.DeleteOptions.FilenameOptions.Filenames, o.DeleteOptions.FilenameOptions.Kustomize) {
|
||||||
return cmdutil.UsageErrorf(cmd, "Must specify --filename to replace")
|
return cmdutil.UsageErrorf(cmd, "Must specify --filename to replace")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -123,7 +123,7 @@ func (o *RolloutHistoryOptions) Complete(f cmdutil.Factory, cmd *cobra.Command,
|
||||||
|
|
||||||
// Validate makes sure all the provided values for command-line options are valid
|
// Validate makes sure all the provided values for command-line options are valid
|
||||||
func (o *RolloutHistoryOptions) Validate() error {
|
func (o *RolloutHistoryOptions) Validate() error {
|
||||||
if len(o.Resources) == 0 && cmdutil.IsFilenameSliceEmpty(o.Filenames) {
|
if len(o.Resources) == 0 && cmdutil.IsFilenameSliceEmpty(o.Filenames, o.Kustomize) {
|
||||||
return fmt.Errorf("required resource not specified")
|
return fmt.Errorf("required resource not specified")
|
||||||
}
|
}
|
||||||
if o.Revision < 0 {
|
if o.Revision < 0 {
|
||||||
|
|
|
@ -117,7 +117,7 @@ func (o *PauseOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []st
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *PauseOptions) Validate() error {
|
func (o *PauseOptions) Validate() error {
|
||||||
if len(o.Resources) == 0 && cmdutil.IsFilenameSliceEmpty(o.Filenames) {
|
if len(o.Resources) == 0 && cmdutil.IsFilenameSliceEmpty(o.Filenames, o.Kustomize) {
|
||||||
return fmt.Errorf("required resource not specified")
|
return fmt.Errorf("required resource not specified")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -121,7 +121,7 @@ func (o *ResumeOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []s
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *ResumeOptions) Validate() error {
|
func (o *ResumeOptions) Validate() error {
|
||||||
if len(o.Resources) == 0 && cmdutil.IsFilenameSliceEmpty(o.Filenames) {
|
if len(o.Resources) == 0 && cmdutil.IsFilenameSliceEmpty(o.Filenames, o.Kustomize) {
|
||||||
return fmt.Errorf("required resource not specified")
|
return fmt.Errorf("required resource not specified")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -148,7 +148,7 @@ func (o *RolloutStatusOptions) Complete(f cmdutil.Factory, args []string) error
|
||||||
|
|
||||||
// Validate makes sure all the provided values for command-line options are valid
|
// Validate makes sure all the provided values for command-line options are valid
|
||||||
func (o *RolloutStatusOptions) Validate() error {
|
func (o *RolloutStatusOptions) Validate() error {
|
||||||
if len(o.BuilderArgs) == 0 && cmdutil.IsFilenameSliceEmpty(o.FilenameOptions.Filenames) {
|
if len(o.BuilderArgs) == 0 && cmdutil.IsFilenameSliceEmpty(o.FilenameOptions.Filenames, o.FilenameOptions.Kustomize) {
|
||||||
return fmt.Errorf("required resource not specified")
|
return fmt.Errorf("required resource not specified")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -126,7 +126,7 @@ func (o *UndoOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []str
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *UndoOptions) Validate() error {
|
func (o *UndoOptions) Validate() error {
|
||||||
if len(o.Resources) == 0 && cmdutil.IsFilenameSliceEmpty(o.Filenames) {
|
if len(o.Resources) == 0 && cmdutil.IsFilenameSliceEmpty(o.Filenames, o.Kustomize) {
|
||||||
return fmt.Errorf("required resource not specified")
|
return fmt.Errorf("required resource not specified")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -198,7 +198,7 @@ func (o *SetImageOptions) Validate() error {
|
||||||
if o.All && len(o.Selector) > 0 {
|
if o.All && len(o.Selector) > 0 {
|
||||||
errors = append(errors, fmt.Errorf("cannot set --all and --selector at the same time"))
|
errors = append(errors, fmt.Errorf("cannot set --all and --selector at the same time"))
|
||||||
}
|
}
|
||||||
if len(o.Resources) < 1 && cmdutil.IsFilenameSliceEmpty(o.Filenames) {
|
if len(o.Resources) < 1 && cmdutil.IsFilenameSliceEmpty(o.Filenames, o.Kustomize) {
|
||||||
errors = append(errors, fmt.Errorf("one or more resources must be specified as <resource> <name> or <resource>/<name>"))
|
errors = append(errors, fmt.Errorf("one or more resources must be specified as <resource> <name> or <resource>/<name>"))
|
||||||
}
|
}
|
||||||
if len(o.ContainerImages) < 1 {
|
if len(o.ContainerImages) < 1 {
|
||||||
|
|
|
@ -291,8 +291,8 @@ func UsageErrorf(cmd *cobra.Command, format string, args ...interface{}) error {
|
||||||
return fmt.Errorf("%s\nSee '%s -h' for help and examples", msg, cmd.CommandPath())
|
return fmt.Errorf("%s\nSee '%s -h' for help and examples", msg, cmd.CommandPath())
|
||||||
}
|
}
|
||||||
|
|
||||||
func IsFilenameSliceEmpty(filenames []string) bool {
|
func IsFilenameSliceEmpty(filenames []string, directory string) bool {
|
||||||
return len(filenames) == 0
|
return len(filenames) == 0 && directory == ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetFlagString(cmd *cobra.Command, flag string) string {
|
func GetFlagString(cmd *cobra.Command, flag string) string {
|
||||||
|
@ -382,6 +382,7 @@ func AddValidateOptionFlags(cmd *cobra.Command, options *ValidateOptions) {
|
||||||
|
|
||||||
func AddFilenameOptionFlags(cmd *cobra.Command, options *resource.FilenameOptions, usage string) {
|
func AddFilenameOptionFlags(cmd *cobra.Command, options *resource.FilenameOptions, usage string) {
|
||||||
AddJsonFilenameFlag(cmd.Flags(), &options.Filenames, "Filename, directory, or URL to files "+usage)
|
AddJsonFilenameFlag(cmd.Flags(), &options.Filenames, "Filename, directory, or URL to files "+usage)
|
||||||
|
AddKustomizeFlag(cmd.Flags(), &options.Kustomize)
|
||||||
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.")
|
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.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -394,6 +395,11 @@ func AddJsonFilenameFlag(flags *pflag.FlagSet, value *[]string, usage string) {
|
||||||
flags.SetAnnotation("filename", cobra.BashCompFilenameExt, annotations)
|
flags.SetAnnotation("filename", cobra.BashCompFilenameExt, annotations)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddKustomizeFlag adds kustomize flag to a command
|
||||||
|
func AddKustomizeFlag(flags *pflag.FlagSet, value *string) {
|
||||||
|
flags.StringVarP(value, "kustomize", "k", *value, "Process the kustomization directory. This flag can't be used together with -f or -R.")
|
||||||
|
}
|
||||||
|
|
||||||
// AddDryRunFlag adds dry-run flag to a command. Usually used by mutations.
|
// AddDryRunFlag adds dry-run flag to a command. Usually used by mutations.
|
||||||
func AddDryRunFlag(cmd *cobra.Command) {
|
func AddDryRunFlag(cmd *cobra.Command) {
|
||||||
cmd.Flags().Bool("dry-run", false, "If true, only print the object that would be sent, without sending it.")
|
cmd.Flags().Bool("dry-run", false, "If true, only print the object that would be sent, without sending it.")
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
- k8s.io/api/core/v1
|
- k8s.io/api/core/v1
|
||||||
- k8s.io/cli-runtime/pkg/genericclioptions/printers
|
- k8s.io/cli-runtime/pkg/genericclioptions/printers
|
||||||
- k8s.io/cli-runtime/pkg/genericclioptions/resource
|
- k8s.io/cli-runtime/pkg/genericclioptions/resource
|
||||||
|
- k8s.io/cli-runtime/pkg/kustomize
|
||||||
|
|
||||||
- baseImportPath: "./vendor/k8s.io/apimachinery/"
|
- baseImportPath: "./vendor/k8s.io/apimachinery/"
|
||||||
allowedImports:
|
allowedImports:
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: the-map
|
||||||
|
data:
|
||||||
|
altGreeting: "Good Morning!"
|
||||||
|
enableRisky: "false"
|
|
@ -0,0 +1,30 @@
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: the-deployment
|
||||||
|
spec:
|
||||||
|
replicas: 3
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
deployment: hello
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: the-container
|
||||||
|
image: monopole/hello:1
|
||||||
|
command: ["/hello",
|
||||||
|
"--port=8080",
|
||||||
|
"--enableRiskyFeature=$(ENABLE_RISKY)"]
|
||||||
|
ports:
|
||||||
|
- containerPort: 8080
|
||||||
|
env:
|
||||||
|
- name: ALT_GREETING
|
||||||
|
valueFrom:
|
||||||
|
configMapKeyRef:
|
||||||
|
name: the-map
|
||||||
|
key: altGreeting
|
||||||
|
- name: ENABLE_RISKY
|
||||||
|
valueFrom:
|
||||||
|
configMapKeyRef:
|
||||||
|
name: the-map
|
||||||
|
key: enableRisky
|
|
@ -0,0 +1,5 @@
|
||||||
|
nameprefix: test-
|
||||||
|
resources:
|
||||||
|
- deployment.yaml
|
||||||
|
- service.yaml
|
||||||
|
- configMap.yaml
|
|
@ -0,0 +1,12 @@
|
||||||
|
kind: Service
|
||||||
|
apiVersion: v1
|
||||||
|
metadata:
|
||||||
|
name: the-service
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
deployment: hello
|
||||||
|
type: LoadBalancer
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: 8666
|
||||||
|
targetPort: 8080
|
|
@ -0,0 +1,7 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: should-not-create-map
|
||||||
|
data:
|
||||||
|
altGreeting: "Good Morning!"
|
||||||
|
enableRisky: "false"
|
|
@ -0,0 +1,8 @@
|
||||||
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
|
kind: Kustomization
|
||||||
|
|
||||||
|
nameprefix: test-
|
||||||
|
resources:
|
||||||
|
- deployment.yaml
|
||||||
|
- service.yaml
|
||||||
|
- configMap.yaml
|
|
@ -32,6 +32,7 @@ type FileNameFlags struct {
|
||||||
Usage string
|
Usage string
|
||||||
|
|
||||||
Filenames *[]string
|
Filenames *[]string
|
||||||
|
Kustomize *string
|
||||||
Recursive *bool
|
Recursive *bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,6 +49,9 @@ func (o *FileNameFlags) ToOptions() resource.FilenameOptions {
|
||||||
if o.Filenames != nil {
|
if o.Filenames != nil {
|
||||||
options.Filenames = *o.Filenames
|
options.Filenames = *o.Filenames
|
||||||
}
|
}
|
||||||
|
if o.Kustomize != nil {
|
||||||
|
options.Kustomize = *o.Kustomize
|
||||||
|
}
|
||||||
|
|
||||||
return options
|
return options
|
||||||
}
|
}
|
||||||
|
@ -68,4 +72,8 @@ func (o *FileNameFlags) AddFlags(flags *pflag.FlagSet) {
|
||||||
}
|
}
|
||||||
flags.SetAnnotation("filename", cobra.BashCompFilenameExt, annotations)
|
flags.SetAnnotation("filename", cobra.BashCompFilenameExt, annotations)
|
||||||
}
|
}
|
||||||
|
if o.Kustomize != nil {
|
||||||
|
flags.StringVarP(o.Kustomize, "kustomize", "k", *o.Kustomize,
|
||||||
|
"Process a kustomization directory. This flag can't be used together with -f or -R.")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,12 +35,14 @@ go_library(
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/util/yaml:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/util/yaml:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/watch:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/watch:go_default_library",
|
||||||
|
"//staging/src/k8s.io/cli-runtime/pkg/kustomize:go_default_library",
|
||||||
"//staging/src/k8s.io/client-go/discovery:go_default_library",
|
"//staging/src/k8s.io/client-go/discovery:go_default_library",
|
||||||
"//staging/src/k8s.io/client-go/kubernetes/scheme:go_default_library",
|
"//staging/src/k8s.io/client-go/kubernetes/scheme:go_default_library",
|
||||||
"//staging/src/k8s.io/client-go/rest:go_default_library",
|
"//staging/src/k8s.io/client-go/rest:go_default_library",
|
||||||
"//staging/src/k8s.io/client-go/restmapper:go_default_library",
|
"//staging/src/k8s.io/client-go/restmapper:go_default_library",
|
||||||
"//vendor/golang.org/x/text/encoding/unicode:go_default_library",
|
"//vendor/golang.org/x/text/encoding/unicode:go_default_library",
|
||||||
"//vendor/golang.org/x/text/transform:go_default_library",
|
"//vendor/golang.org/x/text/transform:go_default_library",
|
||||||
|
"//vendor/sigs.k8s.io/kustomize/pkg/fs:go_default_library",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -130,9 +130,28 @@ func IsUsageError(err error) bool {
|
||||||
|
|
||||||
type FilenameOptions struct {
|
type FilenameOptions struct {
|
||||||
Filenames []string
|
Filenames []string
|
||||||
|
Kustomize string
|
||||||
Recursive bool
|
Recursive bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (o *FilenameOptions) validate() []error {
|
||||||
|
var errs []error
|
||||||
|
if len(o.Filenames) > 0 && len(o.Kustomize) > 0 {
|
||||||
|
errs = append(errs, fmt.Errorf("only one of -f or -k can be specified"))
|
||||||
|
}
|
||||||
|
if len(o.Kustomize) > 0 && o.Recursive {
|
||||||
|
errs = append(errs, fmt.Errorf("the -k flag can't be used with -f or -R"))
|
||||||
|
}
|
||||||
|
return errs
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *FilenameOptions) RequireFilenameOrKustomize() error {
|
||||||
|
if len(o.Filenames) == 0 && len(o.Kustomize) == 0 {
|
||||||
|
return fmt.Errorf("must specify one of -f and -k")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type resourceTuple struct {
|
type resourceTuple struct {
|
||||||
Resource string
|
Resource string
|
||||||
Name string
|
Name string
|
||||||
|
@ -195,6 +214,10 @@ func (b *Builder) AddError(err error) *Builder {
|
||||||
// If ContinueOnError() is set prior to this method, objects on the path that are not
|
// If ContinueOnError() is set prior to this method, objects on the path that are not
|
||||||
// recognized will be ignored (but logged at V(2)).
|
// recognized will be ignored (but logged at V(2)).
|
||||||
func (b *Builder) FilenameParam(enforceNamespace bool, filenameOptions *FilenameOptions) *Builder {
|
func (b *Builder) FilenameParam(enforceNamespace bool, filenameOptions *FilenameOptions) *Builder {
|
||||||
|
if errs := filenameOptions.validate(); len(errs) > 0 {
|
||||||
|
b.errs = append(b.errs, errs...)
|
||||||
|
return b
|
||||||
|
}
|
||||||
recursive := filenameOptions.Recursive
|
recursive := filenameOptions.Recursive
|
||||||
paths := filenameOptions.Filenames
|
paths := filenameOptions.Filenames
|
||||||
for _, s := range paths {
|
for _, s := range paths {
|
||||||
|
@ -215,6 +238,10 @@ func (b *Builder) FilenameParam(enforceNamespace bool, filenameOptions *Filename
|
||||||
b.Path(recursive, s)
|
b.Path(recursive, s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if filenameOptions.Kustomize != "" {
|
||||||
|
b.paths = append(b.paths, &KustomizeVisitor{filenameOptions.Kustomize,
|
||||||
|
NewStreamVisitor(nil, b.mapper, filenameOptions.Kustomize, b.schema)})
|
||||||
|
}
|
||||||
|
|
||||||
if enforceNamespace {
|
if enforceNamespace {
|
||||||
b.RequireNamespace()
|
b.RequireNamespace()
|
||||||
|
|
|
@ -374,6 +374,62 @@ func writeTestFile(t *testing.T, path string, contents string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestFilenameOptionsValidate(t *testing.T) {
|
||||||
|
testcases := []struct {
|
||||||
|
filenames []string
|
||||||
|
kustomize string
|
||||||
|
recursive bool
|
||||||
|
errExp bool
|
||||||
|
msgExp string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
filenames: []string{"file"},
|
||||||
|
kustomize: "dir",
|
||||||
|
errExp: true,
|
||||||
|
msgExp: "only one of -f or -k can be specified",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
kustomize: "dir",
|
||||||
|
recursive: true,
|
||||||
|
errExp: true,
|
||||||
|
msgExp: "the -k flag can't be used with -f or -R",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
filenames: []string{"file"},
|
||||||
|
errExp: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
filenames: []string{"dir"},
|
||||||
|
recursive: true,
|
||||||
|
errExp: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
kustomize: "dir",
|
||||||
|
errExp: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, testcase := range testcases {
|
||||||
|
o := &FilenameOptions{
|
||||||
|
Kustomize: testcase.kustomize,
|
||||||
|
Filenames: testcase.filenames,
|
||||||
|
Recursive: testcase.recursive,
|
||||||
|
}
|
||||||
|
errs := o.validate()
|
||||||
|
if testcase.errExp {
|
||||||
|
if len(errs) == 0 {
|
||||||
|
t.Fatalf("expected error not happened")
|
||||||
|
}
|
||||||
|
if errs[0].Error() != testcase.msgExp {
|
||||||
|
t.Fatalf("expected %s, but got %#v", testcase.msgExp, errs[0])
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if len(errs) > 0 {
|
||||||
|
t.Fatalf("Unexpected error %#v", errs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestPathBuilderWithMultiple(t *testing.T) {
|
func TestPathBuilderWithMultiple(t *testing.T) {
|
||||||
// create test dirs
|
// create test dirs
|
||||||
tmpDir, err := utiltesting.MkTmpdir("recursive_test_multiple")
|
tmpDir, err := utiltesting.MkTmpdir("recursive_test_multiple")
|
||||||
|
@ -513,6 +569,160 @@ func TestDirectoryBuilder(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func setupKustomizeDirectory() (string, error) {
|
||||||
|
path, err := ioutil.TempDir("/tmp", "")
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
contents := map[string]string{
|
||||||
|
"configmap.yaml": `
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: the-map
|
||||||
|
data:
|
||||||
|
altGreeting: "Good Morning!"
|
||||||
|
enableRisky: "false"
|
||||||
|
`,
|
||||||
|
"deployment.yaml": `
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: the-deployment
|
||||||
|
spec:
|
||||||
|
replicas: 3
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
deployment: hello
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: the-container
|
||||||
|
image: monopole/hello:1
|
||||||
|
command: ["/hello",
|
||||||
|
"--port=8080",
|
||||||
|
"--enableRiskyFeature=$(ENABLE_RISKY)"]
|
||||||
|
ports:
|
||||||
|
- containerPort: 8080
|
||||||
|
env:
|
||||||
|
- name: ALT_GREETING
|
||||||
|
valueFrom:
|
||||||
|
configMapKeyRef:
|
||||||
|
name: the-map
|
||||||
|
key: altGreeting
|
||||||
|
- name: ENABLE_RISKY
|
||||||
|
valueFrom:
|
||||||
|
configMapKeyRef:
|
||||||
|
name: the-map
|
||||||
|
key: enableRisky
|
||||||
|
`,
|
||||||
|
"service.yaml": `
|
||||||
|
kind: Service
|
||||||
|
apiVersion: v1
|
||||||
|
metadata:
|
||||||
|
name: the-service
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
deployment: hello
|
||||||
|
type: LoadBalancer
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: 8666
|
||||||
|
targetPort: 8080
|
||||||
|
`,
|
||||||
|
"kustomization.yaml": `
|
||||||
|
nameprefix: test-
|
||||||
|
resources:
|
||||||
|
- deployment.yaml
|
||||||
|
- service.yaml
|
||||||
|
- configmap.yaml
|
||||||
|
`,
|
||||||
|
}
|
||||||
|
|
||||||
|
for filename, content := range contents {
|
||||||
|
err = ioutil.WriteFile(filepath.Join(path, filename), []byte(content), 0660)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return path, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestKustomizeDirectoryBuilder(t *testing.T) {
|
||||||
|
dir, err := setupKustomizeDirectory()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected error %v", err)
|
||||||
|
}
|
||||||
|
defer os.RemoveAll(dir)
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
directory string
|
||||||
|
expectErr bool
|
||||||
|
errMsg string
|
||||||
|
number int
|
||||||
|
expectedNames []string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
directory: "../../../artifacts/guestbook",
|
||||||
|
expectErr: true,
|
||||||
|
errMsg: "No kustomization file found",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
directory: dir,
|
||||||
|
expectErr: false,
|
||||||
|
expectedNames: []string{"test-the-map", "test-the-deployment", "test-the-service"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
directory: filepath.Join(dir, "kustomization.yaml"),
|
||||||
|
expectErr: true,
|
||||||
|
errMsg: "must be a directory to be a root",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
directory: "../../../artifacts/kustomization/should-not-load.yaml",
|
||||||
|
expectErr: true,
|
||||||
|
errMsg: "must be a directory to be a root",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
b := newDefaultBuilder().
|
||||||
|
FilenameParam(false, &FilenameOptions{Kustomize: tt.directory}).
|
||||||
|
NamespaceParam("test").DefaultNamespace()
|
||||||
|
test := &testVisitor{}
|
||||||
|
err := b.Do().Visit(test.Handle)
|
||||||
|
if tt.expectErr {
|
||||||
|
if err == nil {
|
||||||
|
t.Fatalf("expected error unhappened")
|
||||||
|
}
|
||||||
|
if !strings.Contains(err.Error(), tt.errMsg) {
|
||||||
|
t.Fatalf("expected %s but got %s", tt.errMsg, err.Error())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if err != nil || len(test.Infos) < tt.number {
|
||||||
|
t.Fatalf("unexpected response: %v %#v", err, test.Infos)
|
||||||
|
}
|
||||||
|
contained := func(name string) bool {
|
||||||
|
for _, info := range test.Infos {
|
||||||
|
if info.Name == name && info.Namespace == "test" && info.Object != nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
allFound := true
|
||||||
|
for _, name := range tt.expectedNames {
|
||||||
|
if !contained(name) {
|
||||||
|
allFound = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !allFound {
|
||||||
|
t.Errorf("unexpected responses: %#v", test.Infos)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestNamespaceOverride(t *testing.T) {
|
func TestNamespaceOverride(t *testing.T) {
|
||||||
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||||
w.WriteHeader(http.StatusOK)
|
w.WriteHeader(http.StatusOK)
|
||||||
|
|
|
@ -39,6 +39,8 @@ import (
|
||||||
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
||||||
"k8s.io/apimachinery/pkg/util/yaml"
|
"k8s.io/apimachinery/pkg/util/yaml"
|
||||||
"k8s.io/apimachinery/pkg/watch"
|
"k8s.io/apimachinery/pkg/watch"
|
||||||
|
"k8s.io/cli-runtime/pkg/kustomize"
|
||||||
|
"sigs.k8s.io/kustomize/pkg/fs"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -520,6 +522,24 @@ func (v *FileVisitor) Visit(fn VisitorFunc) error {
|
||||||
return v.StreamVisitor.Visit(fn)
|
return v.StreamVisitor.Visit(fn)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// KustomizeVisitor is wrapper around a StreamVisitor, to handle Kustomization directories
|
||||||
|
type KustomizeVisitor struct {
|
||||||
|
Path string
|
||||||
|
*StreamVisitor
|
||||||
|
}
|
||||||
|
|
||||||
|
// Visit in a KustomizeVisitor gets the output of Kustomize build and save it in the Streamvisitor
|
||||||
|
func (v *KustomizeVisitor) Visit(fn VisitorFunc) error {
|
||||||
|
fSys := fs.MakeRealFS()
|
||||||
|
var out bytes.Buffer
|
||||||
|
err := kustomize.RunKustomizeBuild(&out, fSys, v.Path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v.StreamVisitor.Reader = bytes.NewReader(out.Bytes())
|
||||||
|
return v.StreamVisitor.Visit(fn)
|
||||||
|
}
|
||||||
|
|
||||||
// StreamVisitor reads objects from an io.Reader and walks them. A stream visitor can only be
|
// StreamVisitor reads objects from an io.Reader and walks them. A stream visitor can only be
|
||||||
// visited once.
|
// visited once.
|
||||||
// TODO: depends on objects being in JSON format before being passed to decode - need to implement
|
// TODO: depends on objects being in JSON format before being passed to decode - need to implement
|
||||||
|
|
|
@ -6,14 +6,50 @@
|
||||||
"./..."
|
"./..."
|
||||||
],
|
],
|
||||||
"Deps": [
|
"Deps": [
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/PuerkitoBio/purell",
|
||||||
|
"Rev": "8a290539e2e8629dbc4e6bad948158f790ec31f4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/PuerkitoBio/urlesc",
|
||||||
|
"Rev": "5bd2802263f21d8788851d5305584c82a5c75d7e"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/davecgh/go-spew/spew",
|
"ImportPath": "github.com/davecgh/go-spew/spew",
|
||||||
"Rev": "782f4967f2dc4564575ca782fe2d04090b5faca8"
|
"Rev": "782f4967f2dc4564575ca782fe2d04090b5faca8"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/emicklei/go-restful",
|
||||||
|
"Rev": "ff4f55a206334ef123e4f79bbf348980da81ca46"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/emicklei/go-restful/log",
|
||||||
|
"Rev": "ff4f55a206334ef123e4f79bbf348980da81ca46"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/evanphx/json-patch",
|
"ImportPath": "github.com/evanphx/json-patch",
|
||||||
"Rev": "5858425f75500d40c52783dce87d085a483ce135"
|
"Rev": "5858425f75500d40c52783dce87d085a483ce135"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/ghodss/yaml",
|
||||||
|
"Rev": "c7ce16629ff4cd059ed96ed06419dd3856fd3577"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/go-openapi/jsonpointer",
|
||||||
|
"Rev": "ef5f0afec364d3b9396b7b77b43dbe26bf1f8004"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/go-openapi/jsonreference",
|
||||||
|
"Rev": "8483a886a90412cd6858df4ea3483dce9c8e35a3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/go-openapi/spec",
|
||||||
|
"Rev": "5bae59e25b21498baea7f9d46e9c147ec106a42e"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/go-openapi/swag",
|
||||||
|
"Rev": "5899d5c5e619fda5fa86e14795a835f473ca284c"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/gogo/protobuf/proto",
|
"ImportPath": "github.com/gogo/protobuf/proto",
|
||||||
"Rev": "342cbe0a04158f6dcb03ca0079991a51a4248c02"
|
"Rev": "342cbe0a04158f6dcb03ca0079991a51a4248c02"
|
||||||
|
@ -82,6 +118,18 @@
|
||||||
"ImportPath": "github.com/json-iterator/go",
|
"ImportPath": "github.com/json-iterator/go",
|
||||||
"Rev": "ab8a2e0c74be9d3be70b3184d9acc634935ded82"
|
"Rev": "ab8a2e0c74be9d3be70b3184d9acc634935ded82"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/mailru/easyjson/buffer",
|
||||||
|
"Rev": "2f5df55504ebc322e4d52d34df6a1f5b503bf26d"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/mailru/easyjson/jlexer",
|
||||||
|
"Rev": "2f5df55504ebc322e4d52d34df6a1f5b503bf26d"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/mailru/easyjson/jwriter",
|
||||||
|
"Rev": "2f5df55504ebc322e4d52d34df6a1f5b503bf26d"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/modern-go/concurrent",
|
"ImportPath": "github.com/modern-go/concurrent",
|
||||||
"Rev": "bacd9c7ef1dd9b15be4a9909b8ac7a4e313eec94"
|
"Rev": "bacd9c7ef1dd9b15be4a9909b8ac7a4e313eec94"
|
||||||
|
@ -94,6 +142,10 @@
|
||||||
"ImportPath": "github.com/peterbourgon/diskv",
|
"ImportPath": "github.com/peterbourgon/diskv",
|
||||||
"Rev": "5f041e8faa004a95c88a202771f4cc3e991971e6"
|
"Rev": "5f041e8faa004a95c88a202771f4cc3e991971e6"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/pkg/errors",
|
||||||
|
"Rev": "645ef00459ed84a119197bfb8d8205042c6df63d"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/spf13/cobra",
|
"ImportPath": "github.com/spf13/cobra",
|
||||||
"Rev": "c439c4fa093711d42e1b01acb1235b52004753c1"
|
"Rev": "c439c4fa093711d42e1b01acb1235b52004753c1"
|
||||||
|
@ -142,6 +194,10 @@
|
||||||
"ImportPath": "golang.org/x/sys/windows",
|
"ImportPath": "golang.org/x/sys/windows",
|
||||||
"Rev": "95c6576299259db960f6c5b9b69ea52422860fce"
|
"Rev": "95c6576299259db960f6c5b9b69ea52422860fce"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "golang.org/x/text/cases",
|
||||||
|
"Rev": "b19bf474d317b857955b12035d2c5acb57ce8b01"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "golang.org/x/text/encoding",
|
"ImportPath": "golang.org/x/text/encoding",
|
||||||
"Rev": "b19bf474d317b857955b12035d2c5acb57ce8b01"
|
"Rev": "b19bf474d317b857955b12035d2c5acb57ce8b01"
|
||||||
|
@ -158,10 +214,22 @@
|
||||||
"ImportPath": "golang.org/x/text/encoding/unicode",
|
"ImportPath": "golang.org/x/text/encoding/unicode",
|
||||||
"Rev": "b19bf474d317b857955b12035d2c5acb57ce8b01"
|
"Rev": "b19bf474d317b857955b12035d2c5acb57ce8b01"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "golang.org/x/text/internal",
|
||||||
|
"Rev": "b19bf474d317b857955b12035d2c5acb57ce8b01"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "golang.org/x/text/internal/tag",
|
||||||
|
"Rev": "b19bf474d317b857955b12035d2c5acb57ce8b01"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "golang.org/x/text/internal/utf8internal",
|
"ImportPath": "golang.org/x/text/internal/utf8internal",
|
||||||
"Rev": "b19bf474d317b857955b12035d2c5acb57ce8b01"
|
"Rev": "b19bf474d317b857955b12035d2c5acb57ce8b01"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "golang.org/x/text/language",
|
||||||
|
"Rev": "b19bf474d317b857955b12035d2c5acb57ce8b01"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "golang.org/x/text/runes",
|
"ImportPath": "golang.org/x/text/runes",
|
||||||
"Rev": "b19bf474d317b857955b12035d2c5acb57ce8b01"
|
"Rev": "b19bf474d317b857955b12035d2c5acb57ce8b01"
|
||||||
|
@ -170,6 +238,10 @@
|
||||||
"ImportPath": "golang.org/x/text/secure/bidirule",
|
"ImportPath": "golang.org/x/text/secure/bidirule",
|
||||||
"Rev": "b19bf474d317b857955b12035d2c5acb57ce8b01"
|
"Rev": "b19bf474d317b857955b12035d2c5acb57ce8b01"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "golang.org/x/text/secure/precis",
|
||||||
|
"Rev": "b19bf474d317b857955b12035d2c5acb57ce8b01"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "golang.org/x/text/transform",
|
"ImportPath": "golang.org/x/text/transform",
|
||||||
"Rev": "b19bf474d317b857955b12035d2c5acb57ce8b01"
|
"Rev": "b19bf474d317b857955b12035d2c5acb57ce8b01"
|
||||||
|
@ -182,6 +254,10 @@
|
||||||
"ImportPath": "golang.org/x/text/unicode/norm",
|
"ImportPath": "golang.org/x/text/unicode/norm",
|
||||||
"Rev": "b19bf474d317b857955b12035d2c5acb57ce8b01"
|
"Rev": "b19bf474d317b857955b12035d2c5acb57ce8b01"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "golang.org/x/text/width",
|
||||||
|
"Rev": "b19bf474d317b857955b12035d2c5acb57ce8b01"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "golang.org/x/time/rate",
|
"ImportPath": "golang.org/x/time/rate",
|
||||||
"Rev": "f51c12702a4d776e4c1fa9b0fabab841babae631"
|
"Rev": "f51c12702a4d776e4c1fa9b0fabab841babae631"
|
||||||
|
@ -330,6 +406,10 @@
|
||||||
"ImportPath": "k8s.io/api/storage/v1beta1",
|
"ImportPath": "k8s.io/api/storage/v1beta1",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "k8s.io/apimachinery/pkg/api/equality",
|
||||||
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/api/errors",
|
"ImportPath": "k8s.io/apimachinery/pkg/api/errors",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
|
@ -342,6 +422,10 @@
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/api/resource",
|
"ImportPath": "k8s.io/apimachinery/pkg/api/resource",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "k8s.io/apimachinery/pkg/api/validation",
|
||||||
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1",
|
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
|
@ -354,6 +438,10 @@
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/unstructuredscheme",
|
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/unstructuredscheme",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1/validation",
|
||||||
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1beta1",
|
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1beta1",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
|
@ -434,6 +522,10 @@
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/util/json",
|
"ImportPath": "k8s.io/apimachinery/pkg/util/json",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "k8s.io/apimachinery/pkg/util/mergepatch",
|
||||||
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/util/naming",
|
"ImportPath": "k8s.io/apimachinery/pkg/util/naming",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
|
@ -450,6 +542,10 @@
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/util/sets",
|
"ImportPath": "k8s.io/apimachinery/pkg/util/sets",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "k8s.io/apimachinery/pkg/util/strategicpatch",
|
||||||
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/util/validation",
|
"ImportPath": "k8s.io/apimachinery/pkg/util/validation",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
|
@ -470,6 +566,10 @@
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/watch",
|
"ImportPath": "k8s.io/apimachinery/pkg/watch",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "k8s.io/apimachinery/third_party/forked/golang/json",
|
||||||
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/third_party/forked/golang/reflect",
|
"ImportPath": "k8s.io/apimachinery/third_party/forked/golang/reflect",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
|
@ -486,6 +586,42 @@
|
||||||
"ImportPath": "k8s.io/cli-runtime/pkg/genericclioptions/resource",
|
"ImportPath": "k8s.io/cli-runtime/pkg/genericclioptions/resource",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "k8s.io/cli-runtime/pkg/kustomize",
|
||||||
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "k8s.io/cli-runtime/pkg/kustomize/k8sdeps",
|
||||||
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "k8s.io/cli-runtime/pkg/kustomize/k8sdeps/configmapandsecret",
|
||||||
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "k8s.io/cli-runtime/pkg/kustomize/k8sdeps/kunstruct",
|
||||||
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "k8s.io/cli-runtime/pkg/kustomize/k8sdeps/kv",
|
||||||
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "k8s.io/cli-runtime/pkg/kustomize/k8sdeps/transformer",
|
||||||
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "k8s.io/cli-runtime/pkg/kustomize/k8sdeps/transformer/hash",
|
||||||
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "k8s.io/cli-runtime/pkg/kustomize/k8sdeps/transformer/patch",
|
||||||
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "k8s.io/cli-runtime/pkg/kustomize/k8sdeps/validator",
|
||||||
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/client-go/discovery",
|
"ImportPath": "k8s.io/client-go/discovery",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
|
@ -590,10 +726,106 @@
|
||||||
"ImportPath": "k8s.io/klog",
|
"ImportPath": "k8s.io/klog",
|
||||||
"Rev": "8139d8cb77af419532b33dfa7dd09fbc5f1d344f"
|
"Rev": "8139d8cb77af419532b33dfa7dd09fbc5f1d344f"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "k8s.io/kube-openapi/pkg/common",
|
||||||
|
"Rev": "d7c86cdc46e3a4fcf892b32dd7bc3aa775e0870e"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "k8s.io/kube-openapi/pkg/util/proto",
|
||||||
|
"Rev": "d7c86cdc46e3a4fcf892b32dd7bc3aa775e0870e"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/utils/integer",
|
"ImportPath": "k8s.io/utils/integer",
|
||||||
"Rev": "c2654d5206da6b7b6ace12841e8f359bb89b443c"
|
"Rev": "c2654d5206da6b7b6ace12841e8f359bb89b443c"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/commands/build",
|
||||||
|
"Rev": "ce7e5ee2c30cc5856fea01fe423cf167f2a2d0c3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/constants",
|
||||||
|
"Rev": "ce7e5ee2c30cc5856fea01fe423cf167f2a2d0c3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/expansion",
|
||||||
|
"Rev": "ce7e5ee2c30cc5856fea01fe423cf167f2a2d0c3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/factory",
|
||||||
|
"Rev": "ce7e5ee2c30cc5856fea01fe423cf167f2a2d0c3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/fs",
|
||||||
|
"Rev": "ce7e5ee2c30cc5856fea01fe423cf167f2a2d0c3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/git",
|
||||||
|
"Rev": "ce7e5ee2c30cc5856fea01fe423cf167f2a2d0c3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/gvk",
|
||||||
|
"Rev": "ce7e5ee2c30cc5856fea01fe423cf167f2a2d0c3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/ifc",
|
||||||
|
"Rev": "ce7e5ee2c30cc5856fea01fe423cf167f2a2d0c3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/ifc/transformer",
|
||||||
|
"Rev": "ce7e5ee2c30cc5856fea01fe423cf167f2a2d0c3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/image",
|
||||||
|
"Rev": "ce7e5ee2c30cc5856fea01fe423cf167f2a2d0c3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/internal/error",
|
||||||
|
"Rev": "ce7e5ee2c30cc5856fea01fe423cf167f2a2d0c3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/loader",
|
||||||
|
"Rev": "ce7e5ee2c30cc5856fea01fe423cf167f2a2d0c3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/patch",
|
||||||
|
"Rev": "ce7e5ee2c30cc5856fea01fe423cf167f2a2d0c3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/patch/transformer",
|
||||||
|
"Rev": "ce7e5ee2c30cc5856fea01fe423cf167f2a2d0c3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/resid",
|
||||||
|
"Rev": "ce7e5ee2c30cc5856fea01fe423cf167f2a2d0c3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/resmap",
|
||||||
|
"Rev": "ce7e5ee2c30cc5856fea01fe423cf167f2a2d0c3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/resource",
|
||||||
|
"Rev": "ce7e5ee2c30cc5856fea01fe423cf167f2a2d0c3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/target",
|
||||||
|
"Rev": "ce7e5ee2c30cc5856fea01fe423cf167f2a2d0c3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/transformers",
|
||||||
|
"Rev": "ce7e5ee2c30cc5856fea01fe423cf167f2a2d0c3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/transformers/config",
|
||||||
|
"Rev": "ce7e5ee2c30cc5856fea01fe423cf167f2a2d0c3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/transformers/config/defaultconfig",
|
||||||
|
"Rev": "ce7e5ee2c30cc5856fea01fe423cf167f2a2d0c3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/types",
|
||||||
|
"Rev": "ce7e5ee2c30cc5856fea01fe423cf167f2a2d0c3"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "sigs.k8s.io/yaml",
|
"ImportPath": "sigs.k8s.io/yaml",
|
||||||
"Rev": "fd68e9863619f6ec2fdd8625fe1f02e7c877e480"
|
"Rev": "fd68e9863619f6ec2fdd8625fe1f02e7c877e480"
|
||||||
|
|
|
@ -223,6 +223,21 @@ __EOF__
|
||||||
# cleanup
|
# cleanup
|
||||||
kubectl delete -f hack/testdata/service-revision2.yaml "${kube_flags[@]}"
|
kubectl delete -f hack/testdata/service-revision2.yaml "${kube_flags[@]}"
|
||||||
|
|
||||||
|
## kubectl apply -k somedir
|
||||||
|
kubectl apply -k hack/testdata/kustomize
|
||||||
|
kube::test::get_object_assert 'configmap test-the-map' "{{${id_field}}}" 'test-the-map'
|
||||||
|
kube::test::get_object_assert 'deployment test-the-deployment' "{{${id_field}}}" 'test-the-deployment'
|
||||||
|
kube::test::get_object_assert 'service test-the-service' "{{${id_field}}}" 'test-the-service'
|
||||||
|
# cleanup
|
||||||
|
kubectl delete -k hack/testdata/kustomize
|
||||||
|
|
||||||
|
## kubectl apply --kustomize somedir
|
||||||
|
kubectl apply --kustomize hack/testdata/kustomize
|
||||||
|
kube::test::get_object_assert 'configmap test-the-map' "{{${id_field}}}" 'test-the-map'
|
||||||
|
kube::test::get_object_assert 'deployment test-the-deployment' "{{${id_field}}}" 'test-the-deployment'
|
||||||
|
kube::test::get_object_assert 'service test-the-service' "{{${id_field}}}" 'test-the-service'
|
||||||
|
# cleanup
|
||||||
|
kubectl delete --kustomize hack/testdata/kustomize
|
||||||
|
|
||||||
set +o nounset
|
set +o nounset
|
||||||
set +o errexit
|
set +o errexit
|
||||||
|
|
|
@ -108,3 +108,28 @@ run_create_job_tests() {
|
||||||
set +o nounset
|
set +o nounset
|
||||||
set +o errexit
|
set +o errexit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
run_kubectl_create_kustomization_directory_tests() {
|
||||||
|
set -o nounset
|
||||||
|
set -o errexit
|
||||||
|
|
||||||
|
## kubectl create -k <dir> for kustomization directory
|
||||||
|
# Pre-condition: no ConfigMap, Deployment, Service exist
|
||||||
|
kube::test::get_object_assert configmaps "{{range.items}}{{$id_field}}:{{end}}" ''
|
||||||
|
kube::test::get_object_assert deployment "{{range.items}}{{$id_field}}:{{end}}" ''
|
||||||
|
kube::test::get_object_assert services "{{range.items}}{{$id_field}}:{{end}}" ''
|
||||||
|
# Command
|
||||||
|
kubectl create -k hack/testdata/kustomize
|
||||||
|
# Post-condition: test-the-map, test-the-deployment, test-the-service exist
|
||||||
|
|
||||||
|
# Check that all items in the list are printed
|
||||||
|
kube::test::get_object_assert 'configmap test-the-map' "{{${id_field}}}" 'test-the-map'
|
||||||
|
kube::test::get_object_assert 'deployment test-the-deployment' "{{${id_field}}}" 'test-the-deployment'
|
||||||
|
kube::test::get_object_assert 'service test-the-service' "{{${id_field}}}" 'test-the-service'
|
||||||
|
|
||||||
|
# cleanup
|
||||||
|
kubectl delete -k hack/testdata/kustomize
|
||||||
|
|
||||||
|
set +o nounset
|
||||||
|
set +o errexit
|
||||||
|
}
|
|
@ -202,6 +202,29 @@ run_kubectl_get_tests() {
|
||||||
# cleanup
|
# cleanup
|
||||||
kubectl delete pods redis-master valid-pod "${kube_flags[@]}"
|
kubectl delete pods redis-master valid-pod "${kube_flags[@]}"
|
||||||
|
|
||||||
|
### Test 'kubectl get -k <dir>' prints all the items built from a kustomization directory
|
||||||
|
# Pre-condition: no ConfigMap, Deployment, Service exist
|
||||||
|
kube::test::get_object_assert configmaps "{{range.items}}{{$id_field}}:{{end}}" ''
|
||||||
|
kube::test::get_object_assert deployment "{{range.items}}{{$id_field}}:{{end}}" ''
|
||||||
|
kube::test::get_object_assert services "{{range.items}}{{$id_field}}:{{end}}" ''
|
||||||
|
# Command
|
||||||
|
kubectl apply -k hack/testdata/kustomize
|
||||||
|
# Post-condition: test-the-map, test-the-deployment, test-the-service exist
|
||||||
|
|
||||||
|
# Check that all items in the list are printed
|
||||||
|
output_message=$(kubectl get -k hack/testdata/kustomize -o jsonpath="{..metadata.name}" "${kube_flags[@]}")
|
||||||
|
kube::test::if_has_string "${output_message}" "test-the-map"
|
||||||
|
kube::test::if_has_string "${output_message}" "test-the-deployment"
|
||||||
|
kube::test::if_has_string "${output_message}" "test-the-service"
|
||||||
|
|
||||||
|
# cleanup
|
||||||
|
kubectl delete -k hack/testdata/kustomize
|
||||||
|
|
||||||
|
# Check that all items in the list are deleted
|
||||||
|
kube::test::get_object_assert configmaps "{{range.items}}{{$id_field}}:{{end}}" ''
|
||||||
|
kube::test::get_object_assert deployment "{{range.items}}{{$id_field}}:{{end}}" ''
|
||||||
|
kube::test::get_object_assert services "{{range.items}}{{$id_field}}:{{end}}" ''
|
||||||
|
|
||||||
set +o nounset
|
set +o nounset
|
||||||
set +o errexit
|
set +o errexit
|
||||||
}
|
}
|
||||||
|
|
|
@ -510,6 +510,9 @@ runTests() {
|
||||||
if kube::test::if_supports_resource "${secrets}" ; then
|
if kube::test::if_supports_resource "${secrets}" ; then
|
||||||
record_command run_create_secret_tests
|
record_command run_create_secret_tests
|
||||||
fi
|
fi
|
||||||
|
if kube::test::if_supports_resource "${deployments}"; then
|
||||||
|
record_command run_kubectl_create_kustomization_directory_tests
|
||||||
|
fi
|
||||||
|
|
||||||
######################
|
######################
|
||||||
# Delete #
|
# Delete #
|
||||||
|
|
Loading…
Reference in New Issue