2014-10-05 21:24:19 -04:00
/ *
2016-06-02 20:25:58 -04:00
Copyright 2014 The Kubernetes Authors .
2014-10-05 21:24:19 -04:00
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 .
* /
2018-04-10 10:21:50 -04:00
package create
2014-10-05 21:24:19 -04:00
import (
2014-10-26 22:21:31 -04:00
"fmt"
2014-10-05 21:24:19 -04:00
"io"
2018-05-07 17:47:29 -04:00
"net/url"
2017-10-19 11:00:50 -04:00
"os"
2017-05-30 13:15:39 -04:00
"runtime"
2017-10-19 11:00:50 -04:00
"strings"
2014-10-05 21:24:19 -04:00
"github.com/spf13/cobra"
2018-11-09 13:49:10 -05:00
"k8s.io/klog"
2014-12-31 18:35:52 -05:00
2017-10-09 15:44:02 -04:00
"k8s.io/apimachinery/pkg/api/meta"
2018-08-01 13:35:43 -04:00
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2018-04-27 11:38:34 -04:00
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
2018-04-05 18:39:17 -04:00
kruntime "k8s.io/apimachinery/pkg/runtime"
2017-01-11 09:09:48 -05:00
"k8s.io/apimachinery/pkg/runtime/schema"
2018-08-21 06:46:39 -04:00
"k8s.io/cli-runtime/pkg/genericclioptions"
2019-03-06 09:54:25 -05:00
"k8s.io/cli-runtime/pkg/printers"
"k8s.io/cli-runtime/pkg/resource"
2018-05-07 17:47:29 -04:00
"k8s.io/client-go/dynamic"
2015-08-05 18:03:47 -04:00
"k8s.io/kubernetes/pkg/kubectl"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
2017-04-18 08:44:25 -04:00
"k8s.io/kubernetes/pkg/kubectl/cmd/util/editor"
2018-09-09 02:59:55 -04:00
"k8s.io/kubernetes/pkg/kubectl/generate"
2018-08-02 13:52:33 -04:00
"k8s.io/kubernetes/pkg/kubectl/scheme"
2017-07-07 00:04:11 -04:00
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
2018-10-10 14:29:30 -04:00
"k8s.io/kubernetes/pkg/kubectl/util/templates"
2014-10-05 21:24:19 -04:00
)
2018-10-30 06:35:24 -04:00
// CreateOptions is the commandline options for 'create' sub command
2017-01-17 22:07:55 -05:00
type CreateOptions struct {
2018-07-02 10:05:24 -04:00
PrintFlags * genericclioptions . PrintFlags
2018-04-18 11:20:33 -04:00
RecordFlags * genericclioptions . RecordFlags
2018-04-05 18:39:17 -04:00
DryRun bool
2017-01-17 22:07:55 -05:00
FilenameOptions resource . FilenameOptions
Selector string
EditBeforeCreate bool
2017-10-19 11:00:50 -04:00
Raw string
2018-04-18 11:20:33 -04:00
Recorder genericclioptions . Recorder
PrintObj func ( obj kruntime . Object ) error
2018-04-19 17:43:28 -04:00
genericclioptions . IOStreams
2017-01-17 22:07:55 -05:00
}
2016-05-20 13:49:56 -04:00
var (
2017-05-25 16:37:56 -04:00
createLong = templates . LongDesc ( i18n . T ( `
2017-05-25 15:23:22 -04:00
Create a resource from a file or from stdin .
2015-02-20 16:28:43 -05:00
2017-03-14 23:49:10 -04:00
JSON and YAML formats are accepted . ` ) )
2016-10-07 18:24:42 -04:00
2017-05-25 16:37:56 -04:00
createExample = templates . Examples ( i18n . T ( `
2016-05-20 13:49:56 -04:00
# Create a pod using the data in pod . json .
kubectl create - f . / pod . json
2015-02-20 16:28:43 -05:00
2016-05-20 13:49:56 -04:00
# Create a pod based on the JSON passed into stdin .
2016-09-21 19:41:07 -04:00
cat pod . json | kubectl create - f -
2018-03-26 03:40:40 -04:00
# Edit the data in docker - registry . yaml in JSON then create the resource using the edited data .
kubectl create - f docker - registry . yaml -- edit - o json ` ) )
2015-02-20 16:28:43 -05:00
)
2018-10-30 06:35:24 -04:00
// NewCreateOptions returns an initialized CreateOptions instance
2018-04-19 17:43:28 -04:00
func NewCreateOptions ( ioStreams genericclioptions . IOStreams ) * CreateOptions {
2018-04-18 11:20:33 -04:00
return & CreateOptions {
2018-08-02 13:52:33 -04:00
PrintFlags : genericclioptions . NewPrintFlags ( "created" ) . WithTypeSetter ( scheme . Scheme ) ,
2018-04-18 11:20:33 -04:00
RecordFlags : genericclioptions . NewRecordFlags ( ) ,
2018-04-05 18:39:17 -04:00
2018-04-19 08:32:15 -04:00
Recorder : genericclioptions . NoopRecorder { } ,
2018-04-19 17:43:28 -04:00
IOStreams : ioStreams ,
2017-12-04 22:23:54 -05:00
}
2018-04-18 11:20:33 -04:00
}
2018-10-30 06:35:24 -04:00
// NewCmdCreate returns new initialized instance of create sub command
2018-04-19 17:43:28 -04:00
func NewCmdCreate ( f cmdutil . Factory , ioStreams genericclioptions . IOStreams ) * cobra . Command {
o := NewCreateOptions ( ioStreams )
2015-08-14 14:46:43 -04:00
2014-10-05 21:24:19 -04:00
cmd := & cobra . Command {
2018-10-05 15:59:38 -04:00
Use : "create -f FILENAME" ,
2017-10-11 02:26:02 -04:00
DisableFlagsInUseLine : true ,
2018-10-05 15:59:38 -04:00
Short : i18n . T ( "Create a resource from a file or from stdin." ) ,
Long : createLong ,
Example : createExample ,
2014-10-05 21:24:19 -04:00
Run : func ( cmd * cobra . Command , args [ ] string ) {
2019-02-25 19:30:50 -05:00
if cmdutil . IsFilenameSliceEmpty ( o . FilenameOptions . Filenames , o . FilenameOptions . Kustomize ) {
ioStreams . ErrOut . Write ( [ ] byte ( "Error: must specify one of -f and -k\n\n" ) )
2018-04-19 17:43:28 -04:00
defaultRunFunc := cmdutil . DefaultSubCommandRun ( ioStreams . ErrOut )
2016-10-20 10:41:46 -04:00
defaultRunFunc ( cmd , args )
2015-10-21 10:41:42 -04:00
return
}
2018-04-18 11:20:33 -04:00
cmdutil . CheckErr ( o . Complete ( f , cmd ) )
cmdutil . CheckErr ( o . ValidateArgs ( cmd , args ) )
cmdutil . CheckErr ( o . RunCreate ( f , cmd ) )
2015-03-09 18:08:16 -04:00
} ,
}
2015-03-28 23:38:46 -04:00
2018-04-18 11:20:33 -04:00
// bind flag structs
o . RecordFlags . AddFlags ( cmd )
2016-08-17 14:28:07 -04:00
usage := "to use to create the resource"
2018-04-18 11:20:33 -04:00
cmdutil . AddFilenameOptionFlags ( cmd , & o . FilenameOptions , usage )
2015-09-10 17:58:09 -04:00
cmdutil . AddValidateFlags ( cmd )
2018-04-18 11:20:33 -04:00
cmd . Flags ( ) . BoolVar ( & o . EditBeforeCreate , "edit" , o . EditBeforeCreate , "Edit the API resource before creating" )
2017-05-30 13:15:39 -04:00
cmd . Flags ( ) . Bool ( "windows-line-endings" , runtime . GOOS == "windows" ,
"Only relevant if --edit=true. Defaults to the line ending native to your platform." )
2015-11-04 16:47:08 -05:00
cmdutil . AddApplyAnnotationFlags ( cmd )
2016-10-11 11:41:02 -04:00
cmdutil . AddDryRunFlag ( cmd )
2018-04-18 11:20:33 -04:00
cmd . Flags ( ) . StringVarP ( & o . Selector , "selector" , "l" , o . Selector , "Selector (label query) to filter on, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2)" )
cmd . Flags ( ) . StringVar ( & o . Raw , "raw" , o . Raw , "Raw URI to POST to the server. Uses the transport specified by the kubeconfig file." )
2015-10-21 10:41:42 -04:00
2018-04-18 11:20:33 -04:00
o . PrintFlags . AddFlags ( cmd )
2018-04-05 18:39:17 -04:00
2015-10-21 10:41:42 -04:00
// create subcommands
2018-04-19 17:43:28 -04:00
cmd . AddCommand ( NewCmdCreateNamespace ( f , ioStreams ) )
cmd . AddCommand ( NewCmdCreateQuota ( f , ioStreams ) )
cmd . AddCommand ( NewCmdCreateSecret ( f , ioStreams ) )
cmd . AddCommand ( NewCmdCreateConfigMap ( f , ioStreams ) )
cmd . AddCommand ( NewCmdCreateServiceAccount ( f , ioStreams ) )
cmd . AddCommand ( NewCmdCreateService ( f , ioStreams ) )
cmd . AddCommand ( NewCmdCreateDeployment ( f , ioStreams ) )
cmd . AddCommand ( NewCmdCreateClusterRole ( f , ioStreams ) )
cmd . AddCommand ( NewCmdCreateClusterRoleBinding ( f , ioStreams ) )
cmd . AddCommand ( NewCmdCreateRole ( f , ioStreams ) )
cmd . AddCommand ( NewCmdCreateRoleBinding ( f , ioStreams ) )
cmd . AddCommand ( NewCmdCreatePodDisruptionBudget ( f , ioStreams ) )
cmd . AddCommand ( NewCmdCreatePriorityClass ( f , ioStreams ) )
cmd . AddCommand ( NewCmdCreateJob ( f , ioStreams ) )
2018-12-03 02:21:39 -05:00
cmd . AddCommand ( NewCmdCreateCronJob ( f , ioStreams ) )
2015-03-09 18:08:16 -04:00
return cmd
}
2014-10-05 21:24:19 -04:00
2018-10-30 06:35:24 -04:00
// ValidateArgs makes sure there is no discrepency in command options
2017-10-19 11:00:50 -04:00
func ( o * CreateOptions ) ValidateArgs ( cmd * cobra . Command , args [ ] string ) error {
2015-03-24 14:21:52 -04:00
if len ( args ) != 0 {
2017-06-14 17:14:42 -04:00
return cmdutil . UsageErrorf ( cmd , "Unexpected args: %v" , args )
2015-03-24 14:21:52 -04:00
}
2017-10-19 11:00:50 -04:00
if len ( o . Raw ) > 0 {
if o . EditBeforeCreate {
return cmdutil . UsageErrorf ( cmd , "--raw and --edit are mutually exclusive" )
}
if len ( o . FilenameOptions . Filenames ) != 1 {
return cmdutil . UsageErrorf ( cmd , "--raw can only use a single local file or stdin" )
}
2017-12-18 00:42:58 -05:00
if strings . Index ( o . FilenameOptions . Filenames [ 0 ] , "http://" ) == 0 || strings . Index ( o . FilenameOptions . Filenames [ 0 ] , "https://" ) == 0 {
2017-10-19 11:00:50 -04:00
return cmdutil . UsageErrorf ( cmd , "--raw cannot read from a url" )
}
if o . FilenameOptions . Recursive {
return cmdutil . UsageErrorf ( cmd , "--raw and --recursive are mutually exclusive" )
}
if len ( o . Selector ) > 0 {
return cmdutil . UsageErrorf ( cmd , "--raw and --selector (-l) are mutually exclusive" )
}
if len ( cmdutil . GetFlagString ( cmd , "output" ) ) > 0 {
return cmdutil . UsageErrorf ( cmd , "--raw and --output are mutually exclusive" )
}
if _ , err := url . ParseRequestURI ( o . Raw ) ; err != nil {
return cmdutil . UsageErrorf ( cmd , "--raw must be a valid URL path: %v" , err )
}
}
2015-03-24 14:21:52 -04:00
return nil
}
2018-10-30 06:35:24 -04:00
// Complete completes all the required options
2018-04-18 11:20:33 -04:00
func ( o * CreateOptions ) Complete ( f cmdutil . Factory , cmd * cobra . Command ) error {
var err error
2018-05-21 15:27:11 -04:00
o . RecordFlags . Complete ( cmd )
2018-04-18 11:20:33 -04:00
o . Recorder , err = o . RecordFlags . ToRecorder ( )
if err != nil {
return err
}
2018-04-05 18:39:17 -04:00
o . DryRun = cmdutil . GetDryRunFlag ( cmd )
if o . DryRun {
o . PrintFlags . Complete ( "%s (dry run)" )
}
printer , err := o . PrintFlags . ToPrinter ( )
if err != nil {
return err
}
o . PrintObj = func ( obj kruntime . Object ) error {
return printer . PrintObj ( obj , o . Out )
}
return nil
}
2018-10-30 06:35:24 -04:00
// RunCreate performs the creation
2017-12-04 22:23:54 -05:00
func ( o * CreateOptions ) RunCreate ( f cmdutil . Factory , cmd * cobra . Command ) error {
2017-10-19 11:00:50 -04:00
// raw only makes sense for a single file resource multiple objects aren't likely to do what you want.
// the validator enforces this, so
2017-12-04 22:23:54 -05:00
if len ( o . Raw ) > 0 {
return o . raw ( f )
2017-10-19 11:00:50 -04:00
}
2017-12-04 22:23:54 -05:00
if o . EditBeforeCreate {
2018-07-16 02:27:20 -04:00
return RunEditOnCreate ( f , o . PrintFlags , o . RecordFlags , o . IOStreams , cmd , & o . FilenameOptions )
2016-09-21 19:41:07 -04:00
}
2017-09-28 18:39:17 -04:00
schema , err := f . Validator ( cmdutil . GetFlagBool ( cmd , "validate" ) )
2015-03-09 18:08:16 -04:00
if err != nil {
return err
}
2015-01-02 13:08:37 -05:00
2018-05-24 09:33:36 -04:00
cmdNamespace , enforceNamespace , err := f . ToRawKubeConfigLoader ( ) . Namespace ( )
2015-03-09 18:08:16 -04:00
if err != nil {
return err
}
2014-11-04 13:59:23 -05:00
2017-11-13 22:43:58 -05:00
r := f . NewBuilder ( ) .
2017-11-13 23:01:51 -05:00
Unstructured ( ) .
2015-05-07 16:53:43 -04:00
Schema ( schema ) .
2015-03-09 18:08:16 -04:00
ContinueOnError ( ) .
2015-06-26 16:49:34 -04:00
NamespaceParam ( cmdNamespace ) . DefaultNamespace ( ) .
2017-12-04 22:23:54 -05:00
FilenameParam ( enforceNamespace , & o . FilenameOptions ) .
LabelSelectorParam ( o . Selector ) .
2015-03-09 18:08:16 -04:00
Flatten ( ) .
Do ( )
err = r . Err ( )
if err != nil {
return err
2014-10-05 21:24:19 -04:00
}
2015-03-09 18:08:16 -04:00
count := 0
2015-06-14 22:48:56 -04:00
err = r . Visit ( func ( info * resource . Info , err error ) error {
if err != nil {
return err
}
2018-09-14 17:31:45 -04:00
if err := kubectl . CreateOrUpdateAnnotation ( cmdutil . GetFlagBool ( cmd , cmdutil . ApplyAnnotationsFlag ) , info . Object , scheme . DefaultJSONEncoder ( ) ) ; err != nil {
2015-09-10 17:32:57 -04:00
return cmdutil . AddSourceToErr ( "creating" , info . Source , err )
}
2018-04-18 11:20:33 -04:00
if err := o . Recorder . Record ( info . Object ) ; err != nil {
2018-11-09 13:49:10 -05:00
klog . V ( 4 ) . Infof ( "error recording current command: %v" , err )
2016-01-22 13:33:23 -05:00
}
2018-04-05 18:39:17 -04:00
if ! o . DryRun {
2016-10-11 11:41:02 -04:00
if err := createAndRefresh ( info ) ; err != nil {
return cmdutil . AddSourceToErr ( "creating" , info . Source , err )
}
2015-03-09 18:08:16 -04:00
}
2015-09-10 17:32:57 -04:00
2015-03-09 18:08:16 -04:00
count ++
2016-12-08 15:26:37 -05:00
2018-04-05 18:39:17 -04:00
return o . PrintObj ( info . Object )
2015-03-09 18:08:16 -04:00
} )
if err != nil {
return err
}
if count == 0 {
return fmt . Errorf ( "no objects passed to create" )
}
return nil
2014-10-05 21:24:19 -04:00
}
2015-06-04 23:52:46 -04:00
2017-12-04 22:23:54 -05:00
// raw makes a simple HTTP request to the provided path on the server using the default
// credentials.
func ( o * CreateOptions ) raw ( f cmdutil . Factory ) error {
restClient , err := f . RESTClient ( )
if err != nil {
return err
}
var data io . ReadCloser
if o . FilenameOptions . Filenames [ 0 ] == "-" {
data = os . Stdin
} else {
data , err = os . Open ( o . FilenameOptions . Filenames [ 0 ] )
if err != nil {
return err
}
}
// TODO post content with stream. Right now it ignores body content
2018-04-07 23:59:41 -04:00
result := restClient . Post ( ) . RequestURI ( o . Raw ) . Body ( data ) . Do ( )
if err := result . Error ( ) ; err != nil {
return err
}
body , err := result . Raw ( )
2017-12-04 22:23:54 -05:00
if err != nil {
return err
}
2018-04-07 23:59:41 -04:00
fmt . Fprintf ( o . Out , "%v" , string ( body ) )
2017-12-04 22:23:54 -05:00
return nil
}
2018-10-30 06:35:24 -04:00
// RunEditOnCreate performs edit on creation
2018-07-16 02:27:20 -04:00
func RunEditOnCreate ( f cmdutil . Factory , printFlags * genericclioptions . PrintFlags , recordFlags * genericclioptions . RecordFlags , ioStreams genericclioptions . IOStreams , cmd * cobra . Command , options * resource . FilenameOptions ) error {
2018-04-19 17:43:28 -04:00
editOptions := editor . NewEditOptions ( editor . EditBeforeCreateMode , ioStreams )
2018-04-18 11:20:33 -04:00
editOptions . FilenameOptions = * options
editOptions . ValidateOptions = cmdutil . ValidateOptions {
EnableValidation : cmdutil . GetFlagBool ( cmd , "validate" ) ,
2017-04-18 08:44:25 -04:00
}
2018-07-16 02:27:20 -04:00
editOptions . PrintFlags = printFlags
2018-04-18 11:20:33 -04:00
editOptions . ApplyAnnotation = cmdutil . GetFlagBool ( cmd , cmdutil . ApplyAnnotationsFlag )
editOptions . RecordFlags = recordFlags
err := editOptions . Complete ( f , [ ] string { } , cmd )
2017-04-18 08:44:25 -04:00
if err != nil {
return err
}
return editOptions . Run ( )
2016-09-21 19:41:07 -04:00
}
2015-11-04 21:29:56 -05:00
// createAndRefresh creates an object from input info and refreshes info with that object
func createAndRefresh ( info * resource . Info ) error {
2018-08-30 09:33:34 -04:00
obj , err := resource . NewHelper ( info . Client , info . Mapping ) . Create ( info . Namespace , true , info . Object , nil )
2015-11-04 21:29:56 -05:00
if err != nil {
return err
}
info . Refresh ( obj , true )
return nil
}
2015-10-21 10:41:42 -04:00
// NameFromCommandArgs is a utility function for commands that assume the first argument is a resource name
func NameFromCommandArgs ( cmd * cobra . Command , args [ ] string ) ( string , error ) {
2018-08-22 07:56:34 -04:00
argsLen := cmd . ArgsLenAtDash ( )
// ArgsLenAtDash returns -1 when -- was not specified
if argsLen == - 1 {
argsLen = len ( args )
}
if argsLen != 1 {
return "" , cmdutil . UsageErrorf ( cmd , "exactly one NAME is required, got %d" , argsLen )
2015-10-21 10:41:42 -04:00
}
return args [ 0 ] , nil
}
// CreateSubcommandOptions is an options struct to support create subcommands
type CreateSubcommandOptions struct {
2018-04-05 18:39:17 -04:00
// PrintFlags holds options necessary for obtaining a printer
2018-07-02 10:05:24 -04:00
PrintFlags * genericclioptions . PrintFlags
2015-10-21 10:41:42 -04:00
// Name of resource being created
Name string
// StructuredGenerator is the resource generator for the object being created
2018-09-09 02:59:55 -04:00
StructuredGenerator generate . StructuredGenerator
2015-10-21 10:41:42 -04:00
// DryRun is true if the command should be simulated but not run against the server
2018-04-05 18:39:17 -04:00
DryRun bool
CreateAnnotation bool
2018-05-07 17:47:29 -04:00
Namespace string
EnforceNamespace bool
Mapper meta . RESTMapper
2018-05-09 12:58:12 -04:00
DynamicClient dynamic . Interface
2018-05-07 17:47:29 -04:00
2018-05-14 12:36:12 -04:00
PrintObj printers . ResourcePrinterFunc
2018-04-05 18:39:17 -04:00
2018-04-19 17:43:28 -04:00
genericclioptions . IOStreams
}
2018-10-30 06:35:24 -04:00
// NewCreateSubcommandOptions returns initialized CreateSubcommandOptions
2018-04-19 17:43:28 -04:00
func NewCreateSubcommandOptions ( ioStreams genericclioptions . IOStreams ) * CreateSubcommandOptions {
return & CreateSubcommandOptions {
2018-08-02 13:52:33 -04:00
PrintFlags : genericclioptions . NewPrintFlags ( "created" ) . WithTypeSetter ( scheme . Scheme ) ,
2018-04-19 17:43:28 -04:00
IOStreams : ioStreams ,
}
2015-10-21 10:41:42 -04:00
}
2018-10-30 06:35:24 -04:00
// Complete completes all the required options
2018-09-09 02:59:55 -04:00
func ( o * CreateSubcommandOptions ) Complete ( f cmdutil . Factory , cmd * cobra . Command , args [ ] string , generator generate . StructuredGenerator ) error {
2018-04-05 18:39:17 -04:00
name , err := NameFromCommandArgs ( cmd , args )
if err != nil {
return err
}
o . Name = name
o . StructuredGenerator = generator
o . DryRun = cmdutil . GetDryRunFlag ( cmd )
o . CreateAnnotation = cmdutil . GetFlagBool ( cmd , cmdutil . ApplyAnnotationsFlag )
if o . DryRun {
o . PrintFlags . Complete ( "%s (dry run)" )
}
printer , err := o . PrintFlags . ToPrinter ( )
if err != nil {
return err
}
2018-05-14 12:36:12 -04:00
o . PrintObj = func ( obj kruntime . Object , out io . Writer ) error {
return printer . PrintObj ( obj , out )
2018-04-05 18:39:17 -04:00
}
2018-05-24 09:33:36 -04:00
o . Namespace , o . EnforceNamespace , err = f . ToRawKubeConfigLoader ( ) . Namespace ( )
2018-05-07 17:47:29 -04:00
if err != nil {
return err
}
2018-04-05 18:39:17 -04:00
2018-05-07 17:47:29 -04:00
o . DynamicClient , err = f . DynamicClient ( )
2015-10-21 10:41:42 -04:00
if err != nil {
return err
}
2018-05-07 17:47:29 -04:00
2018-05-16 10:54:42 -04:00
o . Mapper , err = f . ToRESTMapper ( )
2015-10-21 10:41:42 -04:00
if err != nil {
return err
}
2018-05-07 17:47:29 -04:00
return nil
}
2018-10-30 06:35:24 -04:00
// Run executes a create subcommand using the specified options
2018-05-07 17:47:29 -04:00
func ( o * CreateSubcommandOptions ) Run ( ) error {
obj , err := o . StructuredGenerator . StructuredGenerate ( )
2018-04-30 08:04:43 -04:00
if err != nil {
return err
}
2018-05-07 17:47:29 -04:00
if ! o . DryRun {
2018-04-27 09:27:19 -04:00
// create subcommands have compiled knowledge of things they create, so type them directly
2018-08-02 13:52:33 -04:00
gvks , _ , err := scheme . Scheme . ObjectKinds ( obj )
2018-04-06 10:33:32 -04:00
if err != nil {
return err
}
gvk := gvks [ 0 ]
2018-05-07 17:47:29 -04:00
mapping , err := o . Mapper . RESTMapping ( schema . GroupKind { Group : gvk . Group , Kind : gvk . Kind } , gvk . Version )
2018-04-06 10:33:32 -04:00
if err != nil {
return err
}
2018-04-27 11:38:34 -04:00
2018-09-14 17:31:45 -04:00
if err := kubectl . CreateOrUpdateAnnotation ( o . CreateAnnotation , obj , scheme . DefaultJSONEncoder ( ) ) ; err != nil {
2018-04-06 10:33:32 -04:00
return err
}
2018-04-27 11:38:34 -04:00
asUnstructured := & unstructured . Unstructured { }
2018-05-14 12:36:12 -04:00
2018-08-02 13:52:33 -04:00
if err := scheme . Scheme . Convert ( obj , asUnstructured , nil ) ; err != nil {
2018-04-27 11:38:34 -04:00
return err
2018-04-06 10:33:32 -04:00
}
2018-04-27 11:38:34 -04:00
if mapping . Scope . Name ( ) == meta . RESTScopeNameRoot {
2018-05-07 17:47:29 -04:00
o . Namespace = ""
2018-04-06 10:33:32 -04:00
}
2018-08-01 13:35:43 -04:00
actualObject , err := o . DynamicClient . Resource ( mapping . Resource ) . Namespace ( o . Namespace ) . Create ( asUnstructured , metav1 . CreateOptions { } )
2015-10-21 10:41:42 -04:00
if err != nil {
return err
}
2018-04-05 18:39:17 -04:00
// ensure we pass a versioned object to the printer
2018-04-27 11:38:34 -04:00
obj = actualObject
2017-10-09 15:44:02 -04:00
} else {
2018-05-07 17:47:29 -04:00
if meta , err := meta . Accessor ( obj ) ; err == nil && o . EnforceNamespace {
meta . SetNamespace ( o . Namespace )
2017-10-09 15:44:02 -04:00
}
2015-10-21 10:41:42 -04:00
}
2018-05-14 12:36:12 -04:00
return o . PrintObj ( obj , o . Out )
2015-10-21 10:41:42 -04:00
}