From 1607ad7d155ff225b30fab446516a4c67d2ff9bd Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Mon, 15 Oct 2018 21:42:51 -0700 Subject: [PATCH] pkg/oc/cli/admin/release: Add --insecure Matching 'oc image mirror --insecure'. This lets callers avoid: $ podman run -d -p 5000:5000 --name registry docker.io/library/registry $ oc adm release mirror --from=registry.svc.ci.openshift.org/openshift/origin-release:v4.0 --to localhost:5000/openshift-v4.0 info: Mirroring 79 images to localhost:5000/openshift-v4.0 ... error: unable to connect to localhost:5000/openshift-v4.0: Get https://localhost:5000/v2/: http: server gave HTTP response to HTTPS client ... error: unable to connect to localhost:5000/openshift-v4.0: Get https://localhost:5000/v2/: http: server gave HTTP response to HTTPS client error: an error occurred during planning when the local registry only speaks HTTP. Ideally we could turn this off only for pushes, allowing us to pull from a remote registry over HTTPS but push to the local registry over HTTP. But 'oc image mirror' doesn't seem to support that level of granularity. And even though the course --insecure allows access over HTTP, we should still be using HTTPS where possible, so the risk of leaking secrets from a properly-configured registry is small. Although maybe there are increased man-in-the-middle risks? I'm not entirely clear on whether --insecure weakens our "acceptable" HTTPS quality as well, or if it's just limited to the documented "allow HTTPS too". The contrib/completions/*/oc updates were generated with: $ make all WHAT=cmd/oc $ hack/update-generated-completions.sh --- contrib/completions/bash/oc | 6 ++++++ contrib/completions/zsh/oc | 6 ++++++ pkg/oc/cli/admin/release/extract.go | 3 +++ pkg/oc/cli/admin/release/mirror.go | 4 ++++ pkg/oc/cli/admin/release/new.go | 11 +++++++++-- 5 files changed, 28 insertions(+), 2 deletions(-) diff --git a/contrib/completions/bash/oc b/contrib/completions/bash/oc index 210b9a7bf668..91d19ac3e4a8 100644 --- a/contrib/completions/bash/oc +++ b/contrib/completions/bash/oc @@ -4603,6 +4603,8 @@ _oc_adm_release_extract() local_nonpersistent_flags+=("--from=") flags+=("--git=") local_nonpersistent_flags+=("--git=") + flags+=("--insecure") + local_nonpersistent_flags+=("--insecure") flags+=("--registry-config=") two_word_flags+=("-a") local_nonpersistent_flags+=("--registry-config=") @@ -4720,6 +4722,8 @@ _oc_adm_release_mirror() local_nonpersistent_flags+=("--dry-run") flags+=("--from=") local_nonpersistent_flags+=("--from=") + flags+=("--insecure") + local_nonpersistent_flags+=("--insecure") flags+=("--registry-config=") two_word_flags+=("-a") local_nonpersistent_flags+=("--registry-config=") @@ -4792,6 +4796,8 @@ _oc_adm_release_new() local_nonpersistent_flags+=("--from-release=") flags+=("--include=") local_nonpersistent_flags+=("--include=") + flags+=("--insecure") + local_nonpersistent_flags+=("--insecure") flags+=("--max-per-registry=") local_nonpersistent_flags+=("--max-per-registry=") flags+=("--metadata=") diff --git a/contrib/completions/zsh/oc b/contrib/completions/zsh/oc index 226e9c105133..e4d78b1c19ad 100644 --- a/contrib/completions/zsh/oc +++ b/contrib/completions/zsh/oc @@ -4745,6 +4745,8 @@ _oc_adm_release_extract() local_nonpersistent_flags+=("--from=") flags+=("--git=") local_nonpersistent_flags+=("--git=") + flags+=("--insecure") + local_nonpersistent_flags+=("--insecure") flags+=("--registry-config=") two_word_flags+=("-a") local_nonpersistent_flags+=("--registry-config=") @@ -4862,6 +4864,8 @@ _oc_adm_release_mirror() local_nonpersistent_flags+=("--dry-run") flags+=("--from=") local_nonpersistent_flags+=("--from=") + flags+=("--insecure") + local_nonpersistent_flags+=("--insecure") flags+=("--registry-config=") two_word_flags+=("-a") local_nonpersistent_flags+=("--registry-config=") @@ -4934,6 +4938,8 @@ _oc_adm_release_new() local_nonpersistent_flags+=("--from-release=") flags+=("--include=") local_nonpersistent_flags+=("--include=") + flags+=("--insecure") + local_nonpersistent_flags+=("--insecure") flags+=("--max-per-registry=") local_nonpersistent_flags+=("--max-per-registry=") flags+=("--metadata=") diff --git a/pkg/oc/cli/admin/release/extract.go b/pkg/oc/cli/admin/release/extract.go index 15da8622a2dc..4a892a30591a 100644 --- a/pkg/oc/cli/admin/release/extract.go +++ b/pkg/oc/cli/admin/release/extract.go @@ -59,6 +59,7 @@ func NewExtract(f kcmdutil.Factory, parentName string, streams genericclioptions flags := cmd.Flags() flags.StringVarP(&o.RegistryConfig, "registry-config", "a", o.RegistryConfig, "Path to your registry credentials (defaults to ~/.docker/config.json)") flags.StringVar(&o.GitExtractDir, "git", o.GitExtractDir, "Check out the sources that created this release into the provided dir. Repos will be created at //. Requires 'git' on your path.") + flags.BoolVar(&o.Insecure, "insecure", o.Insecure, "Allow pull operations from registries to be made over HTTP.") flags.StringVar(&o.From, "from", o.From, "Image containing the release payload.") flags.StringVar(&o.File, "file", o.File, "Extract a single file from the payload to standard output.") flags.StringVar(&o.Directory, "to", o.Directory, "Directory to write release contents to, defaults to the current directory.") @@ -77,6 +78,7 @@ type ExtractOptions struct { File string RegistryConfig string + Insecure bool ImageMetadataCallback func(m *extract.Mapping, dgst digest.Digest, config *docker10.DockerImageConfig) } @@ -141,6 +143,7 @@ func (o *ExtractOptions) Run() error { } opts := extract.NewOptions(genericclioptions.IOStreams{Out: o.Out, ErrOut: o.ErrOut}) opts.RegistryConfig = o.RegistryConfig + opts.Insecure = o.Insecure switch { case len(o.File) > 0: diff --git a/pkg/oc/cli/admin/release/mirror.go b/pkg/oc/cli/admin/release/mirror.go index 08a4c212ac71..f38125c377e3 100644 --- a/pkg/oc/cli/admin/release/mirror.go +++ b/pkg/oc/cli/admin/release/mirror.go @@ -68,6 +68,7 @@ func NewMirror(f kcmdutil.Factory, parentName string, streams genericclioptions. flags.StringVar(&o.From, "from", o.From, "Image containing the release payload.") flags.StringVar(&o.To, "to", o.To, "An image repository to push to.") flags.BoolVar(&o.DryRun, "dry-run", o.DryRun, "Display information about the mirror without actually executing it.") + flags.BoolVar(&o.Insecure, "insecure", o.Insecure, "Allow push and pull operations to registries to be made over HTTP.") flags.BoolVar(&o.SkipRelease, "skip-release-image", o.SkipRelease, "Do not push the release image.") flags.StringVar(&o.ToRelease, "to-release-image", o.ToRelease, "Specify an alternate locations for the release image instead as tag 'release' in --to") @@ -85,6 +86,7 @@ type MirrorOptions struct { RegistryConfig string DryRun bool + Insecure bool ImageStream *imageapi.ImageStream TargetFn func(component string) imagereference.DockerImageReference @@ -161,6 +163,7 @@ func (o *MirrorOptions) Run() error { extractOpts := NewExtractOptions(genericclioptions.IOStreams{Out: buf, ErrOut: o.ErrOut}) extractOpts.RegistryConfig = o.RegistryConfig extractOpts.ImageMetadataCallback = func(m *extract.Mapping, dgst digest.Digest, config *docker10.DockerImageConfig) {} + extractOpts.Insecure = o.Insecure extractOpts.From = o.From extractOpts.File = "image-references" if err := extractOpts.Run(); err != nil { @@ -237,6 +240,7 @@ func (o *MirrorOptions) Run() error { opts.RegistryConfig = o.RegistryConfig opts.Mappings = mappings opts.DryRun = o.DryRun + opts.Insecure = o.Insecure opts.ManifestUpdateCallback = func(registry string, manifests map[digest.Digest]digest.Digest) error { lock.Lock() defer lock.Unlock() diff --git a/pkg/oc/cli/admin/release/new.go b/pkg/oc/cli/admin/release/new.go index 1393e9749343..eec878637599 100644 --- a/pkg/oc/cli/admin/release/new.go +++ b/pkg/oc/cli/admin/release/new.go @@ -123,6 +123,7 @@ func NewRelease(f kcmdutil.Factory, parentName string, streams genericclioptions // destination flags.BoolVar(&o.DryRun, "dry-run", o.DryRun, "Skips changes to external registries via mirroring or pushing images.") + flags.BoolVar(&o.Insecure, "insecure", o.Insecure, "Allow push and pull operations to registries to be made over HTTP.") flags.StringVar(&o.Mirror, "mirror", o.Mirror, "Mirror the contents of the release to this repository.") flags.StringVar(&o.ToDir, "to-dir", o.ToDir, "Output the release manifests to a directory instead of creating an image.") flags.StringVar(&o.ToFile, "to-file", o.ToFile, "Output the release to a tar file instead of creating an image.") @@ -164,7 +165,8 @@ type NewOptions struct { ReleaseMetadata string PreviousVersions []string - DryRun bool + DryRun bool + Insecure bool ToFile string ToDir string @@ -352,6 +354,7 @@ func (o *NewOptions) Run() error { buf := &bytes.Buffer{} extractOpts := extract.NewOptions(genericclioptions.IOStreams{Out: buf, ErrOut: o.ErrOut}) extractOpts.RegistryConfig = o.RegistryConfig + extractOpts.Insecure = o.Insecure extractOpts.OnlyFiles = true extractOpts.Mappings = []extract.Mapping{ { @@ -759,6 +762,7 @@ func (o *NewOptions) extractManifests(is *imageapi.ImageStream, name string, met var lock sync.Mutex opts := extract.NewOptions(genericclioptions.IOStreams{Out: o.Out, ErrOut: o.ErrOut}) opts.RegistryConfig = o.RegistryConfig + opts.Insecure = o.Insecure opts.OnlyFiles = true opts.MaxPerRegistry = o.MaxPerRegistry opts.ImageMetadataCallback = func(m *extract.Mapping, dgst digest.Digest, config *docker10.DockerImageConfig) { @@ -771,6 +775,7 @@ func (o *NewOptions) extractManifests(is *imageapi.ImageStream, name string, met Digest: dgst, } } + opts.Insecure = o.Insecure for i := range is.Spec.Tags { tag := &is.Spec.Tags[i] @@ -855,6 +860,7 @@ func (o *NewOptions) mirrorImages(is *imageapi.ImageStream, payload *Payload) er copied := is.DeepCopy() opts := NewMirrorOptions(genericclioptions.IOStreams{Out: o.Out, ErrOut: o.ErrOut}) opts.DryRun = o.DryRun + opts.Insecure = o.Insecure opts.ImageStream = copied opts.To = o.Mirror opts.SkipRelease = true @@ -978,7 +984,8 @@ func (o *NewOptions) write(r io.Reader, is *imageapi.ImageStream, now time.Time) options := imageappend.NewAppendImageOptions(genericclioptions.IOStreams{Out: o.Out, ErrOut: o.ErrOut}) options.RegistryConfig = o.RegistryConfig options.DryRun = o.DryRun - options.From = toImageBase + options.Insecure = o.Insecure + options.From = o.ToImageBase options.ConfigurationCallback = func(dgst digest.Digest, config *docker10.DockerImageConfig) error { // reset any base image info if len(config.OS) == 0 {