Skip to content

Commit

Permalink
Merge pull request #20244 from juanvallejo/jvallejo/update-more-cmds
Browse files Browse the repository at this point in the history
update importimage, projects, rsh, req_project
  • Loading branch information
openshift-merge-robot authored Jul 11, 2018
2 parents dd68e3f + beb0f33 commit dab5aad
Show file tree
Hide file tree
Showing 9 changed files with 158 additions and 139 deletions.
115 changes: 57 additions & 58 deletions pkg/oc/cli/cmd/importimage.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package cmd

import (
"fmt"
"io"
"strings"

"github.com/spf13/cobra"
Expand Down Expand Up @@ -41,39 +40,15 @@ var (
`)
)

// NewCmdImportImage implements the OpenShift cli import-image command.
func NewCmdImportImage(fullName string, f kcmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
opts := &ImportImageOptions{}
cmd := &cobra.Command{
Use: "import-image IMAGESTREAM[:TAG]",
Short: "Imports images from a Docker registry",
Long: importImageLong,
Example: fmt.Sprintf(importImageExample, fullName),
Run: func(cmd *cobra.Command, args []string) {
kcmdutil.CheckErr(opts.Complete(f, cmd, args, fullName, streams.Out, streams.ErrOut))
kcmdutil.CheckErr(opts.Validate(cmd))
kcmdutil.CheckErr(opts.Run())
},
}
cmd.Flags().StringVar(&opts.From, "from", "", "A Docker image repository to import images from")
cmd.Flags().BoolVar(&opts.Confirm, "confirm", false, "If true, allow the image stream import location to be set or changed")
cmd.Flags().BoolVar(&opts.All, "all", false, "If true, import all tags from the provided source on creation or if --from is specified")
cmd.Flags().StringVar(&opts.ReferencePolicy, "reference-policy", sourceReferencePolicy, "Allow to request pullthrough for external image when set to 'local'. Defaults to 'source'.")
cmd.Flags().BoolVar(&opts.DryRun, "dry-run", false, "Fetch information about images without creating or updating an image stream.")
cmd.Flags().BoolVar(&opts.Scheduled, "scheduled", false, "Set each imported Docker image to be periodically imported from a remote repository. Defaults to false.")
opts.Insecure = cmd.Flags().Bool("insecure", false, "If true, allow importing from registries that have invalid HTTPS certificates or are hosted via HTTP. This flag will take precedence over the insecure annotation.")

return cmd
}

// ImageImportOptions contains all the necessary information to perform an import.
type ImportImageOptions struct {
// user set values
From string
Confirm bool
All bool
Scheduled bool
Insecure *bool
From string
Confirm bool
All bool
Scheduled bool
Insecure bool
InsecureFlagProvided bool

DryRun bool

Expand All @@ -84,27 +59,54 @@ type ImportImageOptions struct {
Target string
ReferencePolicy string

CommandName string

// helpers
out io.Writer
errout io.Writer
imageClient imageclient.ImageInterface
isClient imageclient.ImageStreamInterface

genericclioptions.IOStreams
}

func NewImportImageOptions(name string, streams genericclioptions.IOStreams) *ImportImageOptions {
return &ImportImageOptions{
IOStreams: streams,
ReferencePolicy: sourceReferencePolicy,
}
}

// NewCmdImportImage implements the OpenShift cli import-image command.
func NewCmdImportImage(fullName string, f kcmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
o := NewImportImageOptions(fullName, streams)

cmd := &cobra.Command{
Use: "import-image IMAGESTREAM[:TAG]",
Short: "Imports images from a Docker registry",
Long: importImageLong,
Example: fmt.Sprintf(importImageExample, fullName),
Run: func(cmd *cobra.Command, args []string) {
kcmdutil.CheckErr(o.Complete(f, cmd, args))
kcmdutil.CheckErr(o.Validate(cmd))
kcmdutil.CheckErr(o.Run())
},
}
cmd.Flags().StringVar(&o.From, "from", o.From, "A Docker image repository to import images from")
cmd.Flags().BoolVar(&o.Confirm, "confirm", o.Confirm, "If true, allow the image stream import location to be set or changed")
cmd.Flags().BoolVar(&o.All, "all", o.All, "If true, import all tags from the provided source on creation or if --from is specified")
cmd.Flags().StringVar(&o.ReferencePolicy, "reference-policy", o.ReferencePolicy, "Allow to request pullthrough for external image when set to 'local'. Defaults to 'source'.")
cmd.Flags().BoolVar(&o.DryRun, "dry-run", o.DryRun, "Fetch information about images without creating or updating an image stream.")
cmd.Flags().BoolVar(&o.Scheduled, "scheduled", o.Scheduled, "Set each imported Docker image to be periodically imported from a remote repository. Defaults to false.")
cmd.Flags().BoolVar(&o.Insecure, "insecure", o.Insecure, "If true, allow importing from registries that have invalid HTTPS certificates or are hosted via HTTP. This flag will take precedence over the insecure annotation.")

return cmd
}

// Complete turns a partially defined ImportImageOptions into a solvent structure
// which can be validated and used for aa import.
func (o *ImportImageOptions) Complete(f kcmdutil.Factory, cmd *cobra.Command, args []string, commandName string, out, errout io.Writer) error {
o.CommandName = commandName

func (o *ImportImageOptions) Complete(f kcmdutil.Factory, cmd *cobra.Command, args []string) error {
if len(args) > 0 {
o.Target = args[0]
}

if !cmd.Flags().Lookup("insecure").Changed {
o.Insecure = nil
}
o.InsecureFlagProvided = cmd.Flags().Lookup("insecure").Changed
if !cmd.Flags().Lookup("reference-policy").Changed {
o.ReferencePolicy = ""
}
Expand All @@ -127,9 +129,6 @@ func (o *ImportImageOptions) Complete(f kcmdutil.Factory, cmd *cobra.Command, ar
o.imageClient = client.Image()
o.isClient = client.Image().ImageStreams(namespace)

o.out = out
o.errout = errout

return nil
}

Expand Down Expand Up @@ -173,15 +172,15 @@ func (o *ImportImageOptions) Run() error {

if o.DryRun {
if wasError(result) {
fmt.Fprintf(o.errout, "The dry-run import completed with errors.\n\n")
fmt.Fprintf(o.ErrOut, "The dry-run import completed with errors.\n\n")
} else {
fmt.Fprint(o.out, "The dry-run import completed successfully.\n\n")
fmt.Fprint(o.Out, "The dry-run import completed successfully.\n\n")
}
} else {
if wasError(result) {
fmt.Fprintf(o.errout, "The import completed with errors.\n\n")
fmt.Fprintf(o.ErrOut, "The import completed with errors.\n\n")
} else {
fmt.Fprint(o.out, "The import completed successfully.\n\n")
fmt.Fprint(o.Out, "The import completed successfully.\n\n")
}
}

Expand All @@ -191,20 +190,20 @@ func (o *ImportImageOptions) Run() error {
if err != nil {
return err
}
fmt.Fprintln(o.out, info)
fmt.Fprintln(o.Out, info)
}

if repo := result.Status.Repository; repo != nil {
for _, image := range repo.Images {
if image.Image != nil {
info, err := describe.DescribeImage(image.Image, imageapi.JoinImageStreamTag(stream.Name, image.Tag))
if err != nil {
fmt.Fprintf(o.errout, "error: tag %s failed: %v\n", image.Tag, err)
fmt.Fprintf(o.ErrOut, "error: tag %s failed: %v\n", image.Tag, err)
} else {
fmt.Fprintln(o.out, info)
fmt.Fprintln(o.Out, info)
}
} else {
fmt.Fprintf(o.errout, "error: repository tag %s failed: %v\n", image.Tag, image.Status.Message)
fmt.Fprintf(o.ErrOut, "error: repository tag %s failed: %v\n", image.Tag, image.Status.Message)
}
}
}
Expand All @@ -213,17 +212,17 @@ func (o *ImportImageOptions) Run() error {
if image.Image != nil {
info, err := describe.DescribeImage(image.Image, imageapi.JoinImageStreamTag(stream.Name, image.Tag))
if err != nil {
fmt.Fprintf(o.errout, "error: tag %s failed: %v\n", image.Tag, err)
fmt.Fprintf(o.ErrOut, "error: tag %s failed: %v\n", image.Tag, err)
} else {
fmt.Fprintln(o.out, info)
fmt.Fprintln(o.Out, info)
}
} else {
fmt.Fprintf(o.errout, "error: tag %s failed: %v\n", image.Tag, image.Status.Message)
fmt.Fprintf(o.ErrOut, "error: tag %s failed: %v\n", image.Tag, image.Status.Message)
}
}

if r := result.Status.Repository; r != nil && len(r.AdditionalTags) > 0 {
fmt.Fprintf(o.out, "\ninfo: The remote repository contained %d additional tags which were not imported: %s\n", len(r.AdditionalTags), strings.Join(r.AdditionalTags, ", "))
fmt.Fprintf(o.Out, "\ninfo: The remote repository contained %d additional tags which were not imported: %s\n", len(r.AdditionalTags), strings.Join(r.AdditionalTags, ", "))
}
return nil
}
Expand Down Expand Up @@ -457,8 +456,8 @@ func (o *ImportImageOptions) newImageStreamImport(stream *imageapi.ImageStream)
insecureAnnotation := stream.Annotations[imageapi.InsecureRepositoryAnnotation]
insecure := insecureAnnotation == "true"
// --insecure flag (if provided) takes precedence over insecure annotation
if o.Insecure != nil {
insecure = *o.Insecure
if o.InsecureFlagProvided {
insecure = o.Insecure
}

return isi, insecure
Expand Down
7 changes: 6 additions & 1 deletion pkg/oc/cli/cmd/importimage_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -580,11 +580,16 @@ func TestCreateImageImport(t *testing.T) {
From: test.from,
All: test.all,
Scheduled: test.scheduled,
Insecure: test.insecure,
ReferencePolicy: test.referencePolicy,
Confirm: test.confirm,
isClient: fake.Image().ImageStreams("other"),
}

if test.insecure != nil {
o.Insecure = *test.insecure
o.InsecureFlagProvided = true
}

// we need to run Validate, because it sets appropriate Name and Tag
if err := o.Validate(&cobra.Command{}); err != nil {
t.Errorf("%s: unexpected error: %v", name, err)
Expand Down
43 changes: 23 additions & 20 deletions pkg/oc/cli/cmd/project.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"bytes"
"errors"
"fmt"
"io"
"net/url"

kapierrors "k8s.io/apimachinery/pkg/api/errors"
Expand Down Expand Up @@ -32,7 +31,6 @@ type ProjectOptions struct {
Config clientcmdapi.Config
ClientConfig *restclient.Config
ClientFn func() (projectclient.ProjectInterface, kclientset.Interface, error)
Out io.Writer
PathOptions *kclientcmd.PathOptions

ProjectName string
Expand All @@ -41,6 +39,8 @@ type ProjectOptions struct {

// SkipAccessValidation means that if a specific name is requested, don't bother checking for access to the project
SkipAccessValidation bool

genericclioptions.IOStreams
}

var (
Expand All @@ -65,32 +65,38 @@ var (
%[1]s`)
)

func NewProjectOptions(streams genericclioptions.IOStreams) *ProjectOptions {
return &ProjectOptions{
IOStreams: streams,
}
}

// NewCmdProject implements the OpenShift cli rollback command
func NewCmdProject(fullName string, f kcmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
options := &ProjectOptions{}
o := NewProjectOptions(streams)

cmd := &cobra.Command{
Use: "project [NAME]",
Short: "Switch to another project",
Long: projectLong,
Example: fmt.Sprintf(projectExample, fullName),
Run: func(cmd *cobra.Command, args []string) {
options.PathOptions = cliconfig.NewPathOptions(cmd)
o.PathOptions = cliconfig.NewPathOptions(cmd)

if err := options.Complete(f, args, streams.Out); err != nil {
if err := o.Complete(f, args); err != nil {
kcmdutil.CheckErr(kcmdutil.UsageErrorf(cmd, err.Error()))
}

if err := options.RunProject(); err != nil {
if err := o.RunProject(); err != nil {
kcmdutil.CheckErr(err)
}
},
}
cmd.Flags().BoolVarP(&options.DisplayShort, "short", "q", false, "If true, display only the project name")
cmd.Flags().BoolVarP(&o.DisplayShort, "short", "q", false, "If true, display only the project name")
return cmd
}

func (o *ProjectOptions) Complete(f genericclioptions.RESTClientGetter, args []string, out io.Writer) error {
func (o *ProjectOptions) Complete(f genericclioptions.RESTClientGetter, args []string) error {
var err error

argsLength := len(args)
Expand Down Expand Up @@ -146,8 +152,6 @@ func (o *ProjectOptions) Complete(f genericclioptions.RESTClientGetter, args []s
return projectClient.Project(), kc, nil
}

o.Out = out

return nil
}
func (o ProjectOptions) Validate() error {
Expand All @@ -158,7 +162,6 @@ func (o ProjectOptions) Validate() error {
func (o ProjectOptions) RunProject() error {
config := o.Config
clientCfg := o.ClientConfig
out := o.Out

var currentProject string
currentContext := config.Contexts[config.CurrentContext]
Expand All @@ -170,7 +173,7 @@ func (o ProjectOptions) RunProject() error {
if len(o.ProjectName) == 0 {
if len(currentProject) > 0 {
if o.DisplayShort {
fmt.Fprintln(out, currentProject)
fmt.Fprintln(o.Out, currentProject)
return nil
}

Expand All @@ -193,17 +196,17 @@ func (o ProjectOptions) RunProject() error {
// if they specified a project name and got a generated context, then only show the information they care about. They won't recognize
// a context name they didn't choose
if config.CurrentContext == defaultContextName {
fmt.Fprintf(out, "Using project %q on server %q.\n", currentProject, clientCfg.Host)
fmt.Fprintf(o.Out, "Using project %q on server %q.\n", currentProject, clientCfg.Host)

} else {
fmt.Fprintf(out, "Using project %q from context named %q on server %q.\n", currentProject, config.CurrentContext, clientCfg.Host)
fmt.Fprintf(o.Out, "Using project %q from context named %q on server %q.\n", currentProject, config.CurrentContext, clientCfg.Host)
}

} else {
if o.DisplayShort {
return fmt.Errorf("no project has been set")
}
fmt.Fprintf(out, "No project has been set. Pass a project name to make that the default.\n")
fmt.Fprintf(o.Out, "No project has been set. Pass a project name to make that the default.\n")
}
return nil
}
Expand Down Expand Up @@ -282,7 +285,7 @@ func (o ProjectOptions) RunProject() error {
}

if o.DisplayShort {
fmt.Fprintln(out, namespaceInUse)
fmt.Fprintln(o.Out, namespaceInUse)
return nil
}

Expand All @@ -293,20 +296,20 @@ func (o ProjectOptions) RunProject() error {
switch {
// if there is no namespace, then the only information we can provide is the context and server
case (len(namespaceInUse) == 0):
fmt.Fprintf(out, "Now using context named %q on server %q.\n", contextInUse, clientCfg.Host)
fmt.Fprintf(o.Out, "Now using context named %q on server %q.\n", contextInUse, clientCfg.Host)

// inform them that they are already in the project they are trying to switch to
case currentProject == namespaceInUse:
fmt.Fprintf(out, "Already on project %q on server %q.\n", currentProject, clientCfg.Host)
fmt.Fprintf(o.Out, "Already on project %q on server %q.\n", currentProject, clientCfg.Host)

// if they specified a project name and got a generated context, then only show the information they care about. They won't recognize
// a context name they didn't choose
case (argument == namespaceInUse) && (contextInUse == defaultContextName):
fmt.Fprintf(out, "Now using project %q on server %q.\n", namespaceInUse, clientCfg.Host)
fmt.Fprintf(o.Out, "Now using project %q on server %q.\n", namespaceInUse, clientCfg.Host)

// in all other cases, display all information
default:
fmt.Fprintf(out, "Now using project %q from context named %q on server %q.\n", namespaceInUse, contextInUse, clientCfg.Host)
fmt.Fprintf(o.Out, "Now using project %q from context named %q on server %q.\n", namespaceInUse, contextInUse, clientCfg.Host)

}

Expand Down
Loading

0 comments on commit dab5aad

Please sign in to comment.