Skip to content

Commit

Permalink
Migrate upload tree to cobra (#826)
Browse files Browse the repository at this point in the history
Signed-off-by: Scott Nichols <[email protected]>
  • Loading branch information
n3wscott authored Sep 30, 2021
1 parent f1d816c commit 849057c
Show file tree
Hide file tree
Showing 18 changed files with 302 additions and 66 deletions.
7 changes: 1 addition & 6 deletions cmd/cosign/cli/attest.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@
package cli

import (
"flag"

"github.com/pkg/errors"
"github.com/spf13/cobra"

Expand Down Expand Up @@ -56,11 +54,8 @@ func addAttest(topLevel *cobra.Command) {
# attach an attestation to a container image which does not fully support OCI media types
COSIGN_DOCKER_MEDIA_TYPES=1 cosign attest --predicate <FILE> --type <TYPE> --key cosign.key legacy-registry.example.com/my/image`,

Args: cobra.MinimumNArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
if len(args) == 0 {
return flag.ErrHelp
}

ko := sign.KeyOpts{
KeyRef: o.Key,
PassFunc: generate.GetPass,
Expand Down
6 changes: 1 addition & 5 deletions cmd/cosign/cli/clean.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,8 @@ func addClean(topLevel *cobra.Command) {
Use: "clean",
Short: "Remove all signatures from an image.\ncosign clean <image uri>",
Long: "Remove all signatures from an image.",

Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
if len(args) != 1 {
return flag.ErrHelp
}

return CleanCmd(cmd.Context(), *o, args[0])
},
}
Expand Down
1 change: 1 addition & 0 deletions cmd/cosign/cli/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ func New() *cobra.Command {
addSignBlob(cmd)
addGenerateKeyPair(cmd)
addAttest(cmd)
addUpload(cmd)
addCopy(cmd)
addClean(cmd)
addTriangulate(cmd)
Expand Down
6 changes: 1 addition & 5 deletions cmd/cosign/cli/copy.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@
package cli

import (
"flag"

"github.com/spf13/cobra"

"github.com/sigstore/cosign/cmd/cosign/cli/copy"
Expand All @@ -41,10 +39,8 @@ func addCopy(topLevel *cobra.Command) {
# overwrite destination image and signatures
cosign copy -f example.com/src example.com/dest`,

Args: cobra.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {
if len(args) != 2 {
return flag.ErrHelp
}
return copy.CopyCmd(cmd.Context(), o.Registry, args[0], args[1], o.SignatureOnly, o.Force)
},
}
Expand Down
6 changes: 1 addition & 5 deletions cmd/cosign/cli/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@
package cli

import (
"flag"

"github.com/spf13/cobra"

"github.com/sigstore/cosign/cmd/cosign/cli/generate"
Expand All @@ -43,10 +41,8 @@ to sign payloads with your own tooling or algorithms.`,
# Use this payload in another tool
gpg --output image.sig --detach-sig <(cosign generate <IMAGE>)`,

Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
if len(args) != 1 {
return flag.ErrHelp
}
annotationMap, err := o.AnnotationsMap()
if err != nil {
return err
Expand Down
2 changes: 1 addition & 1 deletion cmd/cosign/cli/options/annotations.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ func (o *AnnotationOptions) AnnotationsMap() (sigs.AnnotationsMap, error) {
return ann, nil
}

// AddFlags implements Inteface
// AddFlags implements Interface
func (o *AnnotationOptions) AddFlags(cmd *cobra.Command) {
cmd.Flags().StringSliceVarP(&o.Annotations, "annotations", "a", nil,
"extra key=value pairs to sign")
Expand Down
57 changes: 57 additions & 0 deletions cmd/cosign/cli/options/files.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
//
// Copyright 2021 The Sigstore Authors.
//
// 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.

package options

import (
"fmt"
"strings"

"github.com/spf13/cobra"

cremote "github.com/sigstore/cosign/pkg/cosign/remote"
)

// FilesOptions is the wrapper for the files.
type FilesOptions struct {
Files []string
}

var _ Interface = (*FilesOptions)(nil)

func (o *FilesOptions) Parse() ([]cremote.File, error) {
fs := cremote.FilesFromFlagList(o.Files)

// If we have multiple files, each file must have a platform.
if len(fs) > 1 {
for _, f := range fs {
if f.Platform() == nil {
return nil, fmt.Errorf("each file must include a unique platform, %s had no platform", f.Path())
}
}
}

return fs, nil
}

func (o *FilesOptions) String() string {
return strings.Join(o.Files, ",")
}

// AddFlags implements Interface
func (o *FilesOptions) AddFlags(cmd *cobra.Command) {
cmd.Flags().StringSliceVarP(&o.Files, "files", "f", nil,
"<filepath>:[platform/arch]")
}
55 changes: 55 additions & 0 deletions cmd/cosign/cli/options/upload.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
//
// Copyright 2021 The Sigstore Authors.
//
// 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.

package options

import (
"github.com/spf13/cobra"
)

// UploadBlobOptions is the top level wrapper for the `upload blob` command.
type UploadBlobOptions struct {
ContentType string
Files FilesOptions
Registry RegistryOptions
}

var _ Interface = (*UploadBlobOptions)(nil)

// AddFlags implements Interface
func (o *UploadBlobOptions) AddFlags(cmd *cobra.Command) {
o.Registry.AddFlags(cmd)
o.Files.AddFlags(cmd)

cmd.Flags().StringVar(&o.ContentType, "ct", "",
"content type to set")
}

// UploadWASMOptions is the top level wrapper for the `upload wasm` command.
type UploadWASMOptions struct {
File string
Registry RegistryOptions
}

var _ Interface = (*UploadWASMOptions)(nil)

// AddFlags implements Interface
func (o *UploadWASMOptions) AddFlags(cmd *cobra.Command) {
o.Registry.AddFlags(cmd)

cmd.Flags().StringVarP(&o.File, "file", "f", "",
"path to the wasm file to upload")
_ = cmd.MarkFlagRequired("file")
}
7 changes: 4 additions & 3 deletions cmd/cosign/cli/public_key.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,13 @@ func addPublicKey(topLevel *cobra.Command) {
# extract public key from Hashicorp Vault KMS
cosign public-key --key hashivault://[KEY]`,

RunE: func(cmd *cobra.Command, args []string) error {
PreRunE: func(cmd *cobra.Command, args []string) error {
if !options.OneOf(o.Key, o.SecurityKey.Use) {
return &options.KeyParseError{}
}

return nil
},
RunE: func(cmd *cobra.Command, args []string) error {
writer := publickey.NamedWriter{Name: "", Writer: nil}
var f *os.File
// Open output file for public key if specified.
Expand Down
5 changes: 1 addition & 4 deletions cmd/cosign/cli/sign.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,8 @@ func addSign(topLevel *cobra.Command) {
# sign a container in a registry which does not fully support OCI media types
COSIGN_DOCKER_MEDIA_TYPES=1 cosign sign --key cosign.key legacy-registry.example.com/my/image`,

Args: cobra.MinimumNArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
if len(args) == 0 {
return flag.ErrHelp
}
switch o.Attachment {
case "sbom", "":
break
Expand Down
13 changes: 5 additions & 8 deletions cmd/cosign/cli/signblob.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@
package cli

import (
"flag"

"github.com/pkg/errors"
"github.com/spf13/cobra"

Expand Down Expand Up @@ -51,18 +49,17 @@ func addSignBlob(topLevel *cobra.Command) {
# sign a blob with a key pair stored in Hashicorp Vault
cosign sign-blob --key hashivault://[KEY] <FILE>`,

RunE: func(cmd *cobra.Command, args []string) error {
Args: cobra.MinimumNArgs(1),
PreRunE: func(cmd *cobra.Command, args []string) error {
// A key file is required unless we're in experimental mode!
if !options.EnableExperimental() {
if !options.OneOf(o.Key, o.SecurityKey.Use) {
return &options.KeyParseError{}
}
}

if len(args) == 0 {
return flag.ErrHelp
}
return nil
},
RunE: func(cmd *cobra.Command, args []string) error {
ko := sign.KeyOpts{
KeyRef: o.Key,
PassFunc: generate.GetPass,
Expand Down
99 changes: 99 additions & 0 deletions cmd/cosign/cli/upload.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
//
// Copyright 2021 The Sigstore Authors.
//
// 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.

package cli

import (
"flag"

"github.com/spf13/cobra"

"github.com/sigstore/cosign/cmd/cosign/cli/options"
"github.com/sigstore/cosign/cmd/cosign/cli/upload"
)

func addUpload(topLevel *cobra.Command) {
cmd := &cobra.Command{
Use: "upload",
Short: "Provides utilities for uploading artifacts to a registry",
}

cmd.AddCommand(
uploadBlob(),
uploadWASM(),
)

topLevel.AddCommand(cmd)
}

func uploadBlob() *cobra.Command {
o := &options.UploadBlobOptions{}

cmd := &cobra.Command{
Use: "blob",
Short: "Upload one or more blobs to the supplied container image address.",
Long: "Upload one or more blobs to the supplied container image address.\ncosign upload blob -f <blob ref> <image uri>",
Example: `
# upload a blob named foo to the location specified by <IMAGE>
cosign upload blob -f foo <IMAGE>
# upload a blob named foo to the location specified by <IMAGE>, setting the os field to "MYOS".
cosign upload blob -f foo:MYOS <IMAGE>
# upload a blob named foo to the location specified by <IMAGE>, setting the os field to "MYOS" and the platform field to "MYPLATFORM".
cosign upload blob -f foo:MYOS/MYPLATFORM <IMAGE>
# upload two blobs named foo-darwin and foo-linux to the location specified by <IMAGE>, setting the os fields
cosign upload blob -f foo-darwin:darwin -f foo-linux:linux <IMAGE>`,
Args: cobra.ExactArgs(1),
PreRunE: func(cmd *cobra.Command, args []string) error {
if len(o.Files.Files) < 1 {
return flag.ErrHelp
}
return nil
},
RunE: func(cmd *cobra.Command, args []string) error {
files, err := o.Files.Parse()
if err != nil {
return err
}

return upload.BlobCmd(cmd.Context(), o.Registry, files, o.ContentType, args[0])
},
}

o.AddFlags(cmd)

return cmd
}

func uploadWASM() *cobra.Command {
o := &options.UploadWASMOptions{}

cmd := &cobra.Command{
Use: "wasm",
Short: "Upload a wasm module to the supplied container image reference",
Long: "Upload a wasm module to the supplied container image reference",
Example: "cosign upload wasm -f foo.wasm <image uri>",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
return upload.WasmCmd(cmd.Context(), o.Registry, o.File, args[0])
},
}

o.AddFlags(cmd)

return cmd
}
Loading

0 comments on commit 849057c

Please sign in to comment.