vendor update for CSI 0.3.0

This commit is contained in:
gman
2018-07-18 16:47:22 +02:00
parent 6f484f92fc
commit 8ea659f0d5
6810 changed files with 438061 additions and 193861 deletions

View File

@ -23,21 +23,25 @@ import (
"github.com/docker/distribution/reference"
"github.com/spf13/cobra"
batchv1 "k8s.io/api/batch/v1"
batchv1beta1 "k8s.io/api/batch/v1beta1"
extensionsv1beta1 "k8s.io/api/extensions/v1beta1"
"k8s.io/client-go/dynamic"
"github.com/golang/glog"
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
utilerrors "k8s.io/apimachinery/pkg/util/errors"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/kubernetes/pkg/api/legacyscheme"
api "k8s.io/kubernetes/pkg/apis/core"
coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion"
"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/resource"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource"
"k8s.io/kubernetes/pkg/kubectl/polymorphichelpers"
"k8s.io/kubernetes/pkg/kubectl/scheme"
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
"k8s.io/kubernetes/pkg/util/interrupt"
uexec "k8s.io/utils/exec"
@ -89,11 +93,52 @@ var (
type RunObject struct {
Object runtime.Object
Kind string
Mapping *meta.RESTMapping
}
func NewCmdRun(f cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer) *cobra.Command {
type RunOptions struct {
PrintFlags *genericclioptions.PrintFlags
DeleteFlags *DeleteFlags
DeleteOptions *DeleteOptions
RecordFlags *genericclioptions.RecordFlags
DryRun bool
PrintObj func(runtime.Object) error
Recorder genericclioptions.Recorder
DynamicClient dynamic.Interface
ArgsLenAtDash int
Attach bool
Expose bool
Generator string
Image string
Interactive bool
LeaveStdinOpen bool
Port string
Quiet bool
Schedule string
TTY bool
genericclioptions.IOStreams
}
func NewRunOptions(streams genericclioptions.IOStreams) *RunOptions {
return &RunOptions{
PrintFlags: genericclioptions.NewPrintFlags("created").WithTypeSetter(scheme.Scheme),
DeleteFlags: NewDeleteFlags("to use to replace the resource."),
RecordFlags: genericclioptions.NewRecordFlags(),
Recorder: genericclioptions.NoopRecorder{},
IOStreams: streams,
}
}
func NewCmdRun(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
o := NewRunOptions(streams)
cmd := &cobra.Command{
Use: "run NAME --image=image [--env=\"key=value\"] [--port=port] [--replicas=replicas] [--dry-run=bool] [--overrides=inline-json] [--command] -- [COMMAND] [args...]",
DisableFlagsInUseLine: true,
@ -101,24 +146,25 @@ func NewCmdRun(f cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer) *co
Long: runLong,
Example: runExample,
Run: func(cmd *cobra.Command, args []string) {
argsLenAtDash := cmd.ArgsLenAtDash()
err := RunRun(f, cmdIn, cmdOut, cmdErr, cmd, args, argsLenAtDash)
cmdutil.CheckErr(err)
cmdutil.CheckErr(o.Complete(f, cmd))
cmdutil.CheckErr(o.Run(f, cmd, args))
},
}
cmdutil.AddPrinterFlags(cmd)
addRunFlags(cmd)
o.DeleteFlags.AddFlags(cmd)
o.PrintFlags.AddFlags(cmd)
o.RecordFlags.AddFlags(cmd)
addRunFlags(cmd, o)
cmdutil.AddApplyAnnotationFlags(cmd)
cmdutil.AddRecordFlag(cmd)
cmdutil.AddInclude3rdPartyFlags(cmd)
cmdutil.AddPodRunningTimeoutFlag(cmd, defaultPodAttachTimeout)
return cmd
}
func addRunFlags(cmd *cobra.Command) {
func addRunFlags(cmd *cobra.Command, opt *RunOptions) {
cmdutil.AddDryRunFlag(cmd)
cmd.Flags().String("generator", "", i18n.T("The name of the API generator to use, see http://kubernetes.io/docs/user-guide/kubectl-conventions/#generators for a list."))
cmd.Flags().String("image", "", i18n.T("The image for the container to run."))
cmd.Flags().StringVar(&opt.Generator, "generator", opt.Generator, i18n.T("The name of the API generator to use, see http://kubernetes.io/docs/user-guide/kubectl-conventions/#generators for a list."))
cmd.Flags().StringVar(&opt.Image, "image", opt.Image, i18n.T("The image for the container to run."))
cmd.MarkFlagRequired("image")
cmd.Flags().String("image-pull-policy", "", i18n.T("The image pull policy for the container. If left empty, this value will not be specified by the client and defaulted by the server"))
cmd.Flags().IntP("replicas", "r", 1, "Number of replicas to create for this container. Default is 1.")
@ -126,27 +172,70 @@ func addRunFlags(cmd *cobra.Command) {
cmd.Flags().String("overrides", "", i18n.T("An inline JSON override for the generated object. If this is non-empty, it is used to override the generated object. Requires that the object supply a valid apiVersion field."))
cmd.Flags().StringArray("env", []string{}, "Environment variables to set in the container")
cmd.Flags().String("serviceaccount", "", "Service account to set in the pod spec")
cmd.Flags().String("port", "", i18n.T("The port that this container exposes. If --expose is true, this is also the port used by the service that is created."))
cmd.Flags().StringVar(&opt.Port, "port", opt.Port, i18n.T("The port that this container exposes. If --expose is true, this is also the port used by the service that is created."))
cmd.Flags().Int("hostport", -1, "The host port mapping for the container port. To demonstrate a single-machine container.")
cmd.Flags().StringP("labels", "l", "", "Comma separated labels to apply to the pod(s). Will override previous values.")
cmd.Flags().BoolP("stdin", "i", false, "Keep stdin open on the container(s) in the pod, even if nothing is attached.")
cmd.Flags().BoolP("tty", "t", false, "Allocated a TTY for each container in the pod.")
cmd.Flags().Bool("attach", false, "If true, wait for the Pod to start running, and then attach to the Pod as if 'kubectl attach ...' were called. Default false, unless '-i/--stdin' is set, in which case the default is true. With '--restart=Never' the exit code of the container process is returned.")
cmd.Flags().Bool("leave-stdin-open", false, "If the pod is started in interactive mode or with stdin, leave stdin open after the first attach completes. By default, stdin will be closed after the first attach completes.")
cmd.Flags().BoolVarP(&opt.Interactive, "stdin", "i", opt.Interactive, "Keep stdin open on the container(s) in the pod, even if nothing is attached.")
cmd.Flags().BoolVarP(&opt.TTY, "tty", "t", opt.TTY, "Allocated a TTY for each container in the pod.")
cmd.Flags().BoolVar(&opt.Attach, "attach", opt.Attach, "If true, wait for the Pod to start running, and then attach to the Pod as if 'kubectl attach ...' were called. Default false, unless '-i/--stdin' is set, in which case the default is true. With '--restart=Never' the exit code of the container process is returned.")
cmd.Flags().BoolVar(&opt.LeaveStdinOpen, "leave-stdin-open", opt.LeaveStdinOpen, "If the pod is started in interactive mode or with stdin, leave stdin open after the first attach completes. By default, stdin will be closed after the first attach completes.")
cmd.Flags().String("restart", "Always", i18n.T("The restart policy for this Pod. Legal values [Always, OnFailure, Never]. If set to 'Always' a deployment is created, if set to 'OnFailure' a job is created, if set to 'Never', a regular pod is created. For the latter two --replicas must be 1. Default 'Always', for CronJobs `Never`."))
cmd.Flags().Bool("command", false, "If true and extra arguments are present, use them as the 'command' field in the container, rather than the 'args' field which is the default.")
cmd.Flags().String("requests", "", i18n.T("The resource requirement requests for this container. For example, 'cpu=100m,memory=256Mi'. Note that server side components may assign requests depending on the server configuration, such as limit ranges."))
cmd.Flags().String("limits", "", i18n.T("The resource requirement limits for this container. For example, 'cpu=200m,memory=512Mi'. Note that server side components may assign limits depending on the server configuration, such as limit ranges."))
cmd.Flags().Bool("expose", false, "If true, a public, external service is created for the container(s) which are run")
cmd.Flags().BoolVar(&opt.Expose, "expose", opt.Expose, "If true, a public, external service is created for the container(s) which are run")
cmd.Flags().String("service-generator", "service/v2", i18n.T("The name of the generator to use for creating a service. Only used if --expose is true"))
cmd.Flags().String("service-overrides", "", i18n.T("An inline JSON override for the generated service object. If this is non-empty, it is used to override the generated object. Requires that the object supply a valid apiVersion field. Only used if --expose is true."))
cmd.Flags().Bool("quiet", false, "If true, suppress prompt messages.")
cmd.Flags().String("schedule", "", i18n.T("A schedule in the Cron format the job should be run with."))
cmd.Flags().BoolVar(&opt.Quiet, "quiet", opt.Quiet, "If true, suppress prompt messages.")
cmd.Flags().StringVar(&opt.Schedule, "schedule", opt.Schedule, i18n.T("A schedule in the Cron format the job should be run with."))
}
func RunRun(f cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer, cmd *cobra.Command, args []string, argsLenAtDash int) error {
func (o *RunOptions) Complete(f cmdutil.Factory, cmd *cobra.Command) error {
var err error
o.RecordFlags.Complete(cmd)
o.Recorder, err = o.RecordFlags.ToRecorder()
if err != nil {
return err
}
o.DynamicClient, err = f.DynamicClient()
if err != nil {
return err
}
o.ArgsLenAtDash = cmd.ArgsLenAtDash()
o.DryRun = cmdutil.GetFlagBool(cmd, "dry-run")
attachFlag := cmd.Flags().Lookup("attach")
if !attachFlag.Changed && o.Interactive {
o.Attach = true
}
if o.DryRun {
o.PrintFlags.Complete("%s (dry run)")
}
printer, err := o.PrintFlags.ToPrinter()
if err != nil {
return err
}
o.PrintObj = func(obj runtime.Object) error {
return printer.PrintObj(obj, o.Out)
}
deleteOpts := o.DeleteFlags.ToOptions(o.DynamicClient, o.IOStreams)
deleteOpts.IgnoreNotFound = true
deleteOpts.WaitForDeletion = false
deleteOpts.GracePeriod = -1
o.DeleteOptions = deleteOpts
return nil
}
func (o *RunOptions) Run(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
// Let kubectl run follow rules for `--`, see #13004 issue
if len(args) == 0 || argsLenAtDash == 0 {
if len(args) == 0 || o.ArgsLenAtDash == 0 {
return cmdutil.UsageErrorf(cmd, "NAME is required for run")
}
@ -156,7 +245,7 @@ func RunRun(f cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer, cmd *c
}
// validate image name
imageName := cmdutil.GetFlagString(cmd, "image")
imageName := o.Image
if imageName == "" {
return fmt.Errorf("--image is required")
}
@ -165,24 +254,22 @@ func RunRun(f cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer, cmd *c
return fmt.Errorf("Invalid image name %q: %v", imageName, reference.ErrReferenceInvalidFormat)
}
interactive := cmdutil.GetFlagBool(cmd, "stdin")
tty := cmdutil.GetFlagBool(cmd, "tty")
if tty && !interactive {
if o.TTY && !o.Interactive {
return cmdutil.UsageErrorf(cmd, "-i/--stdin is required for containers with -t/--tty=true")
}
replicas := cmdutil.GetFlagInt(cmd, "replicas")
if interactive && replicas != 1 {
if o.Interactive && replicas != 1 {
return cmdutil.UsageErrorf(cmd, "-i/--stdin requires that replicas is 1, found %d", replicas)
}
if cmdutil.GetFlagBool(cmd, "expose") && len(cmdutil.GetFlagString(cmd, "port")) == 0 {
if o.Expose && len(o.Port) == 0 {
return cmdutil.UsageErrorf(cmd, "--port must be set when exposing a service")
}
namespace, _, err := f.DefaultNamespace()
namespace, _, err := f.ToRawKubeConfigLoader().Namespace()
if err != nil {
return err
}
restartPolicy, err := getRestartPolicy(cmd, interactive)
restartPolicy, err := getRestartPolicy(cmd, o.Interactive)
if err != nil {
return err
}
@ -190,19 +277,12 @@ func RunRun(f cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer, cmd *c
return cmdutil.UsageErrorf(cmd, "--restart=%s requires that --replicas=1, found %d", restartPolicy, replicas)
}
attachFlag := cmd.Flags().Lookup("attach")
attach := cmdutil.GetFlagBool(cmd, "attach")
if !attachFlag.Changed && interactive {
attach = true
}
remove := cmdutil.GetFlagBool(cmd, "rm")
if !attach && remove {
if !o.Attach && remove {
return cmdutil.UsageErrorf(cmd, "--rm should only be used for attached containers")
}
if attach && cmdutil.GetDryRunFlag(cmd) {
if o.Attach && o.DryRun {
return cmdutil.UsageErrorf(cmd, "--dry-run can't be used with attached containers options (--attach, --stdin, or --tty)")
}
@ -215,54 +295,33 @@ func RunRun(f cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer, cmd *c
return err
}
generatorName := cmdutil.GetFlagString(cmd, "generator")
schedule := cmdutil.GetFlagString(cmd, "schedule")
if len(schedule) != 0 && len(generatorName) == 0 {
hasResource, err := cmdutil.HasResource(clientset.Discovery(), batchv1beta1.SchemeGroupVersion.WithResource("cronjobs"))
if err != nil {
return err
}
if hasResource {
generatorName = cmdutil.CronJobV1Beta1GeneratorName
} else {
generatorName = cmdutil.CronJobV2Alpha1GeneratorName
}
generatorName := o.Generator
if len(o.Schedule) != 0 && len(generatorName) == 0 {
generatorName = cmdutil.CronJobV1Beta1GeneratorName
}
if len(generatorName) == 0 {
switch restartPolicy {
case api.RestartPolicyAlways:
// TODO: we need to deprecate this along with extensions/v1beta1.Deployments
// in favor of the new generator for apps/v1beta1.Deployments
hasResource, err := cmdutil.HasResource(clientset.Discovery(), extensionsv1beta1.SchemeGroupVersion.WithResource("deployments"))
if err != nil {
return err
}
if hasResource {
generatorName = cmdutil.DeploymentV1Beta1GeneratorName
} else {
generatorName = cmdutil.RunV1GeneratorName
}
generatorName = cmdutil.DeploymentAppsV1Beta1GeneratorName
case api.RestartPolicyOnFailure:
hasResource, err := cmdutil.HasResource(clientset.Discovery(), batchv1.SchemeGroupVersion.WithResource("jobs"))
if err != nil {
return err
}
if hasResource {
generatorName = cmdutil.JobV1GeneratorName
} else {
generatorName = cmdutil.RunPodV1GeneratorName
}
generatorName = cmdutil.JobV1GeneratorName
case api.RestartPolicyNever:
generatorName = cmdutil.RunPodV1GeneratorName
}
// Falling back because the generator was not provided and the default one could be unavailable.
generatorNameTemp, err := cmdutil.FallbackGeneratorNameIfNecessary(generatorName, clientset.Discovery(), o.ErrOut)
if err != nil {
return err
}
if generatorNameTemp != generatorName {
cmdutil.Warning(o.ErrOut, generatorName, generatorNameTemp)
} else {
generatorName = generatorNameTemp
}
}
generatorName, err = cmdutil.FallbackGeneratorNameIfNecessary(generatorName, clientset.Discovery(), cmdErr)
if err != nil {
return err
}
generators := f.Generators("run")
generators := cmdutil.GeneratorFn("run")
generator, found := generators[generatorName]
if !found {
return cmdutil.UsageErrorf(cmd, "generator %q not found", generatorName)
@ -276,44 +335,45 @@ func RunRun(f cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer, cmd *c
params["env"] = cmdutil.GetFlagStringArray(cmd, "env")
allErrs := []error{}
var runObjectMap = map[string]*RunObject{}
runObject, err := createGeneratedObject(f, cmd, generator, names, params, cmdutil.GetFlagString(cmd, "overrides"), namespace)
var createdObjects = []*RunObject{}
runObject, err := o.createGeneratedObject(f, cmd, generator, names, params, cmdutil.GetFlagString(cmd, "overrides"), namespace)
if err != nil {
allErrs = append(allErrs, err)
return err
} else {
runObjectMap[generatorName] = runObject
createdObjects = append(createdObjects, runObject)
}
if cmdutil.GetFlagBool(cmd, "expose") {
allErrs := []error{}
if o.Expose {
serviceGenerator := cmdutil.GetFlagString(cmd, "service-generator")
if len(serviceGenerator) == 0 {
return cmdutil.UsageErrorf(cmd, "No service generator specified")
}
serviceRunObject, err := generateService(f, cmd, args, serviceGenerator, params, namespace, cmdOut)
serviceRunObject, err := o.generateService(f, cmd, serviceGenerator, params, namespace)
if err != nil {
allErrs = append(allErrs, err)
} else {
runObjectMap[generatorName] = serviceRunObject
createdObjects = append(createdObjects, serviceRunObject)
}
}
if attach {
quiet := cmdutil.GetFlagBool(cmd, "quiet")
if o.Attach {
if remove {
defer o.removeCreatedObjects(f, createdObjects)
}
opts := &AttachOptions{
StreamOptions: StreamOptions{
In: cmdIn,
Out: cmdOut,
Err: cmdErr,
Stdin: interactive,
TTY: tty,
Quiet: quiet,
IOStreams: o.IOStreams,
Stdin: o.Interactive,
TTY: o.TTY,
Quiet: o.Quiet,
},
GetPodTimeout: timeout,
CommandName: cmd.Parent().CommandPath() + " attach",
Attach: &DefaultRemoteAttach{},
}
config, err := f.ClientConfig()
config, err := f.ToRESTConfig()
if err != nil {
return err
}
@ -325,7 +385,7 @@ func RunRun(f cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer, cmd *c
}
opts.PodClient = clientset.Core()
attachablePod, err := f.AttachablePodForObject(runObject.Object, opts.GetPodTimeout)
attachablePod, err := polymorphichelpers.AttachablePodForObjectFn(f, runObject.Object, opts.GetPodTimeout)
if err != nil {
return err
}
@ -335,7 +395,7 @@ func RunRun(f cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer, cmd *c
}
var pod *api.Pod
leaveStdinOpen := cmdutil.GetFlagBool(cmd, "leave-stdin-open")
leaveStdinOpen := o.LeaveStdinOpen
waitForExitCode := !leaveStdinOpen && restartPolicy == api.RestartPolicyNever
if waitForExitCode {
pod, err = waitForPod(clientset.Core(), attachablePod.Namespace, attachablePod.Name, kubectl.PodCompleted)
@ -344,37 +404,6 @@ func RunRun(f cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer, cmd *c
}
}
if remove {
for _, obj := range runObjectMap {
namespace, err = obj.Mapping.MetadataAccessor.Namespace(obj.Object)
if err != nil {
return err
}
var name string
name, err = obj.Mapping.MetadataAccessor.Name(obj.Object)
if err != nil {
return err
}
r := f.NewBuilder().
Internal().
ContinueOnError().
NamespaceParam(namespace).DefaultNamespace().
ResourceNames(obj.Mapping.Resource, name).
Flatten().
Do()
// Note: we pass in "true" for the "quiet" parameter because
// ReadResult will only print one thing based on the "quiet"
// flag, and that's the "pod xxx deleted" message. If they
// asked for us to remove the pod (via --rm) then telling them
// its been deleted is unnecessary since that's what they asked
// for. We should only print something if the "rm" fails.
err = ReapResult(r, f, cmdOut, true, true, 0, -1, false, false, true)
if err != nil {
return err
}
}
}
// after removal is done, return successfully if we are not interested in the exit code
if !waitForExitCode {
return nil
@ -403,16 +432,40 @@ func RunRun(f cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer, cmd *c
}
if runObject != nil {
outputFormat := cmdutil.GetFlagString(cmd, "output")
if outputFormat != "" || cmdutil.GetDryRunFlag(cmd) {
return cmdutil.PrintObject(cmd, runObject.Object, cmdOut)
if err := o.PrintObj(runObject.Object); err != nil {
return err
}
cmdutil.PrintSuccess(false, cmdOut, runObject.Object, cmdutil.GetDryRunFlag(cmd), "created")
}
return utilerrors.NewAggregate(allErrs)
}
func (o *RunOptions) removeCreatedObjects(f cmdutil.Factory, createdObjects []*RunObject) error {
for _, obj := range createdObjects {
namespace, err := metadataAccessor.Namespace(obj.Object)
if err != nil {
return err
}
var name string
name, err = metadataAccessor.Name(obj.Object)
if err != nil {
return err
}
r := f.NewBuilder().
WithScheme(legacyscheme.Scheme).
ContinueOnError().
NamespaceParam(namespace).DefaultNamespace().
ResourceNames(obj.Mapping.Resource.Resource+"."+obj.Mapping.Resource.Group, name).
Flatten().
Do()
if err := o.DeleteOptions.DeleteResult(r); err != nil {
return err
}
}
return nil
}
// waitForPod watches the given pod until the exitCondition is true
func waitForPod(podClient coreclient.PodsGetter, ns, name string, exitCondition watch.ConditionFunc) (*api.Pod, error) {
w, err := podClient.Pods(ns).Watch(metav1.SingleObject(metav1.ObjectMeta{Name: name}))
@ -455,7 +508,7 @@ func handleAttachPod(f cmdutil.Factory, podClient coreclient.PodsGetter, ns, nam
opts.Namespace = ns
// TODO: opts.Run sets opts.Err to nil, we need to find a better way
stderr := opts.Err
stderr := opts.ErrOut
if err := opts.Run(); err != nil {
fmt.Fprintf(stderr, "Error attaching, falling back to logs: %v\n", err)
return logOpts(f, pod, opts)
@ -464,13 +517,13 @@ func handleAttachPod(f cmdutil.Factory, podClient coreclient.PodsGetter, ns, nam
}
// logOpts logs output from opts to the pods log.
func logOpts(f cmdutil.Factory, pod *api.Pod, opts *AttachOptions) error {
func logOpts(restClientGetter genericclioptions.RESTClientGetter, pod *api.Pod, opts *AttachOptions) error {
ctrName, err := opts.GetContainerName(pod)
if err != nil {
return err
}
req, err := f.LogsForObject(pod, &api.PodLogOptions{Container: ctrName}, opts.GetPodTimeout)
req, err := polymorphichelpers.LogsForObjectFn(restClientGetter, pod, &api.PodLogOptions{Container: ctrName}, opts.GetPodTimeout)
if err != nil {
return err
}
@ -519,8 +572,8 @@ func verifyImagePullPolicy(cmd *cobra.Command) error {
return cmdutil.UsageErrorf(cmd, "invalid image pull policy: %s", pullPolicy)
}
func generateService(f cmdutil.Factory, cmd *cobra.Command, args []string, serviceGenerator string, paramsIn map[string]interface{}, namespace string, out io.Writer) (*RunObject, error) {
generators := f.Generators("expose")
func (o *RunOptions) generateService(f cmdutil.Factory, cmd *cobra.Command, serviceGenerator string, paramsIn map[string]interface{}, namespace string) (*RunObject, error) {
generators := cmdutil.GeneratorFn("expose")
generator, found := generators[serviceGenerator]
if !found {
return nil, fmt.Errorf("missing service generator: %s", serviceGenerator)
@ -549,27 +602,23 @@ func generateService(f cmdutil.Factory, cmd *cobra.Command, args []string, servi
params["default-name"] = name
}
runObject, err := createGeneratedObject(f, cmd, generator, names, params, cmdutil.GetFlagString(cmd, "service-overrides"), namespace)
runObject, err := o.createGeneratedObject(f, cmd, generator, names, params, cmdutil.GetFlagString(cmd, "service-overrides"), namespace)
if err != nil {
return nil, err
}
if cmdutil.GetFlagString(cmd, "output") != "" || cmdutil.GetDryRunFlag(cmd) {
err := cmdutil.PrintObject(cmd, runObject.Object, out)
if err != nil {
return nil, err
}
if cmdutil.GetFlagString(cmd, "output") == "yaml" {
fmt.Fprintln(out, "---")
}
return runObject, nil
if err := o.PrintObj(runObject.Object); err != nil {
return nil, err
}
// separate yaml objects
if o.PrintFlags.OutputFormat != nil && *o.PrintFlags.OutputFormat == "yaml" {
fmt.Fprintln(o.Out, "---")
}
cmdutil.PrintSuccess(false, out, runObject.Object, cmdutil.GetDryRunFlag(cmd), "created")
return runObject, nil
}
func createGeneratedObject(f cmdutil.Factory, cmd *cobra.Command, generator kubectl.Generator, names []kubectl.GeneratorParam, params map[string]interface{}, overrides, namespace string) (*RunObject, error) {
func (o *RunOptions) createGeneratedObject(f cmdutil.Factory, cmd *cobra.Command, generator kubectl.Generator, names []kubectl.GeneratorParam, params map[string]interface{}, overrides, namespace string) (*RunObject, error) {
err := kubectl.ValidateParams(names, params)
if err != nil {
return nil, err
@ -581,63 +630,50 @@ func createGeneratedObject(f cmdutil.Factory, cmd *cobra.Command, generator kube
return nil, err
}
mapper, typer := f.Object()
groupVersionKinds, _, err := typer.ObjectKinds(obj)
mapper, err := f.ToRESTMapper()
if err != nil {
return nil, err
}
// run has compiled knowledge of the thing is is creating
gvks, _, err := scheme.Scheme.ObjectKinds(obj)
if err != nil {
return nil, err
}
mapping, err := mapper.RESTMapping(gvks[0].GroupKind(), gvks[0].Version)
if err != nil {
return nil, err
}
groupVersionKind := groupVersionKinds[0]
if len(overrides) > 0 {
codec := runtime.NewCodec(cmdutil.InternalVersionJSONEncoder(), cmdutil.InternalVersionDecoder())
codec := runtime.NewCodec(scheme.DefaultJSONEncoder(), scheme.Codecs.UniversalDecoder(scheme.Scheme.PrioritizedVersionsAllGroups()...))
obj, err = cmdutil.Merge(codec, obj, overrides)
if err != nil {
return nil, err
}
}
mapping, err := mapper.RESTMapping(groupVersionKind.GroupKind(), groupVersionKind.Version)
if err != nil {
return nil, err
}
client, err := f.ClientForMapping(mapping)
if err != nil {
return nil, err
if err := o.Recorder.Record(obj); err != nil {
glog.V(4).Infof("error recording current command: %v", err)
}
annotations, err := mapping.MetadataAccessor.Annotations(obj)
if err != nil {
return nil, err
}
if cmdutil.GetRecordFlag(cmd) || len(annotations[kubectl.ChangeCauseAnnotation]) > 0 {
if err := cmdutil.RecordChangeCause(obj, f.Command(cmd, false)); err != nil {
actualObj := obj
if !o.DryRun {
if err := kubectl.CreateOrUpdateAnnotation(cmdutil.GetFlagBool(cmd, cmdutil.ApplyAnnotationsFlag), obj, scheme.DefaultJSONEncoder()); err != nil {
return nil, err
}
}
if !cmdutil.GetDryRunFlag(cmd) {
resourceMapper := &resource.Mapper{
ObjectTyper: typer,
RESTMapper: mapper,
ClientMapper: resource.ClientMapperFunc(f.ClientForMapping),
Decoder: cmdutil.InternalVersionDecoder(),
}
info, err := resourceMapper.InfoForObject(obj, nil)
client, err := f.ClientForMapping(mapping)
if err != nil {
return nil, err
}
if err := kubectl.CreateOrUpdateAnnotation(cmdutil.GetFlagBool(cmd, cmdutil.ApplyAnnotationsFlag), info, cmdutil.InternalVersionJSONEncoder()); err != nil {
return nil, err
}
obj, err = resource.NewHelper(client, mapping).Create(namespace, false, info.Object)
actualObj, err = resource.NewHelper(client, mapping).Create(namespace, false, obj)
if err != nil {
return nil, err
}
}
actualObj = cmdutil.AsDefaultVersionedOrOriginal(actualObj, mapping)
return &RunObject{
Object: obj,
Kind: groupVersionKind.Kind,
Object: actualObj,
Mapping: mapping,
}, nil
}