Skip to content

Commit

Permalink
phase 1, migrate the outer shell of cosign to cobra
Browse files Browse the repository at this point in the history
Signed-off-by: Scott Nichols <[email protected]>
  • Loading branch information
n3wscott committed Sep 20, 2021
1 parent acba596 commit e6fad61
Show file tree
Hide file tree
Showing 44 changed files with 792 additions and 565 deletions.
11 changes: 6 additions & 5 deletions cmd/cosign/cli/attach/sbom.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@ import (
"github.com/google/go-containerregistry/pkg/v1/types"
"github.com/peterbourgon/ff/v3/ffcli"

"github.com/sigstore/cosign/cmd/cosign/cli"
"github.com/sigstore/cosign/cmd/cosign/cli/options"
"github.com/sigstore/cosign/pkg/cosign"
cremote "github.com/sigstore/cosign/pkg/cosign/remote"
"github.com/sigstore/cosign/pkg/image"
ctypes "github.com/sigstore/cosign/pkg/types"
)

Expand All @@ -44,9 +45,9 @@ func SBOM() *ffcli.Command {
flagset = flag.NewFlagSet("cosign attach sbom", flag.ExitOnError)
sbom = flagset.String("sbom", "", "path to the sbom, or {-} for stdin")
sbomType = flagset.String("type", "spdx", "type of sbom (spdx|cyclonedx), default spdx")
regOpts cli.RegistryOpts
regOpts options.RegistryOpts
)
cli.ApplyRegistryFlags(&regOpts, flagset)
options.ApplyRegistryFlags(&regOpts, flagset)
return &ffcli.Command{
Name: "sbom",
ShortUsage: "cosign attach sbom <image uri>",
Expand All @@ -67,7 +68,7 @@ func SBOM() *ffcli.Command {
}
}

func SBOMCmd(ctx context.Context, regOpts cli.RegistryOpts, sbomRef, sbomType, imageRef string) error {
func SBOMCmd(ctx context.Context, regOpts options.RegistryOpts, sbomRef, sbomType, imageRef string) error {
ref, err := name.ParseReference(imageRef)
if err != nil {
return err
Expand All @@ -80,7 +81,7 @@ func SBOMCmd(ctx context.Context, regOpts cli.RegistryOpts, sbomRef, sbomType, i

remoteOpts := regOpts.GetRegistryClientOpts(ctx)

dstRef, err := cli.AttachedImageTag(ref, cosign.SBOMTagSuffix, remoteOpts...)
dstRef, err := image.AttachedImageTag(ref, cosign.SBOMTagSuffix, remoteOpts...)
if err != nil {
return err
}
Expand Down
13 changes: 7 additions & 6 deletions cmd/cosign/cli/attach/sig.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,10 @@ import (
"github.com/google/go-containerregistry/pkg/name"
"github.com/peterbourgon/ff/v3/ffcli"

"github.com/sigstore/cosign/cmd/cosign/cli"
"github.com/sigstore/cosign/cmd/cosign/cli/options"
"github.com/sigstore/cosign/pkg/cosign"
cremote "github.com/sigstore/cosign/pkg/cosign/remote"
"github.com/sigstore/cosign/pkg/image"
sigPayload "github.com/sigstore/sigstore/pkg/signature/payload"
)

Expand All @@ -38,9 +39,9 @@ func Signature() *ffcli.Command {
flagset = flag.NewFlagSet("cosign attach signature", flag.ExitOnError)
signature = flagset.String("signature", "", "the signature, path to the signature, or {-} for stdin")
payload = flagset.String("payload", "", "path to the payload covered by the signature (if using another format)")
regOpts cli.RegistryOpts
regOpts options.RegistryOpts
)
cli.ApplyRegistryFlags(&regOpts, flagset)
options.ApplyRegistryFlags(&regOpts, flagset)
return &ffcli.Command{
Name: "signature",
ShortUsage: "cosign attach signature <image uri>",
Expand All @@ -56,7 +57,7 @@ func Signature() *ffcli.Command {
}
}

func SignatureCmd(ctx context.Context, regOpts cli.RegistryOpts, sigRef, payloadRef, imageRef string) error {
func SignatureCmd(ctx context.Context, regOpts options.RegistryOpts, sigRef, payloadRef, imageRef string) error {
b64SigBytes, err := signatureBytes(sigRef)
if err != nil {
return err
Expand All @@ -71,7 +72,7 @@ func SignatureCmd(ctx context.Context, regOpts cli.RegistryOpts, sigRef, payload

remoteOpts := regOpts.GetRegistryClientOpts(ctx)

h, err := cli.Digest(ref, remoteOpts...)
h, err := image.Digest(ref, remoteOpts...)
if err != nil {
return err
}
Expand All @@ -93,7 +94,7 @@ func SignatureCmd(ctx context.Context, regOpts cli.RegistryOpts, sigRef, payload
return err
}

dstRef, err := cli.AttachedImageTag(ref, cosign.SignatureTagSuffix, remoteOpts...)
dstRef, err := image.AttachedImageTag(ref, cosign.SignatureTagSuffix, remoteOpts...)
if err != nil {
return err
}
Expand Down
43 changes: 24 additions & 19 deletions cmd/cosign/cli/attest.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,18 @@ import (
"github.com/peterbourgon/ff/v3/ffcli"
"github.com/pkg/errors"

"github.com/sigstore/cosign/cmd/cosign/cli/generate"
"github.com/sigstore/cosign/cmd/cosign/cli/options"
"github.com/sigstore/cosign/cmd/cosign/cli/sign"
"github.com/sigstore/cosign/pkg/cosign"
"github.com/sigstore/cosign/pkg/cosign/attestation"
cremote "github.com/sigstore/cosign/pkg/cosign/remote"
"github.com/sigstore/cosign/pkg/image"
"github.com/sigstore/cosign/pkg/signature"
"github.com/sigstore/cosign/pkg/types"
rekorClient "github.com/sigstore/rekor/pkg/client"
"github.com/sigstore/sigstore/pkg/signature/dsse"
"github.com/sigstore/sigstore/pkg/signature/options"
signatureoptions "github.com/sigstore/sigstore/pkg/signature/options"
)

func Attest() *ffcli.Command {
Expand All @@ -51,9 +56,9 @@ func Attest() *ffcli.Command {
force = flagset.Bool("f", false, "skip warnings and confirmations")
idToken = flagset.String("identity-token", "", "[EXPERIMENTAL] identity token to use for certificate from fulcio")
predicateType = flagset.String("type", "custom", "specify predicate type (default: custom) (slsaprovenance|link|spdx)")
regOpts RegistryOpts
regOpts options.RegistryOpts
)
ApplyRegistryFlags(&regOpts, flagset)
options.ApplyRegistryFlags(&regOpts, flagset)
return &ffcli.Command{
Name: "attest",
ShortUsage: "cosign attest -key <key path>|<kms uri> [-predicate <path>] [-a key=value] [-upload=true|false] [-f] [-r] <image uri>",
Expand Down Expand Up @@ -88,9 +93,9 @@ EXAMPLES
return flag.ErrHelp
}

ko := KeyOpts{
ko := sign.KeyOpts{
KeyRef: *key,
PassFunc: GetPass,
PassFunc: generate.GetPass,
Sk: *sk,
Slot: *slot,
IDToken: *idToken,
Expand Down Expand Up @@ -119,16 +124,16 @@ var predicateTypeMap = map[string]string{
predicateLink: in_toto.PredicateLinkV1,
}

func AttestCmd(ctx context.Context, ko KeyOpts, regOpts RegistryOpts, imageRef string, certPath string,
func AttestCmd(ctx context.Context, ko sign.KeyOpts, regOpts options.RegistryOpts, imageRef string, certPath string,
upload bool, predicatePath string, force bool, predicateType string) error {
// A key file or token is required unless we're in experimental mode!
if EnableExperimental() {
if nOf(ko.KeyRef, ko.Sk) > 1 {
return &KeyParseError{}
if options.EnableExperimental() {
if options.NOf(ko.KeyRef, ko.Sk) > 1 {
return &options.KeyParseError{}
}
} else {
if !oneOf(ko.KeyRef, ko.Sk) {
return &KeyParseError{}
if !options.OneOf(ko.KeyRef, ko.Sk) {
return &options.KeyParseError{}
}
}

Expand All @@ -143,12 +148,12 @@ func AttestCmd(ctx context.Context, ko KeyOpts, regOpts RegistryOpts, imageRef s
if err != nil {
return errors.Wrap(err, "parsing reference")
}
h, err := Digest(ref, remoteOpts...)
h, err := image.Digest(ref, remoteOpts...)
if err != nil {
return err
}

sv, err := signerFromKeyOpts(ctx, certPath, ko)
sv, err := sign.SignerFromKeyOpts(ctx, certPath, ko)
if err != nil {
return errors.Wrap(err, "getting signer")
}
Expand All @@ -170,7 +175,7 @@ func AttestCmd(ctx context.Context, ko KeyOpts, regOpts RegistryOpts, imageRef s
if err != nil {
return err
}
sig, err := wrapped.SignMessage(bytes.NewReader(payload), options.WithContext(ctx))
sig, err := wrapped.SignMessage(bytes.NewReader(payload), signatureoptions.WithContext(ctx))
if err != nil {
return errors.Wrap(err, "signing")
}
Expand All @@ -188,7 +193,7 @@ func AttestCmd(ctx context.Context, ko KeyOpts, regOpts RegistryOpts, imageRef s
MediaType: types.DssePayloadType,
}

uploadTLog, err := shouldUploadToTlog(ref, force, ko.RekorURL)
uploadTLog, err := sign.ShouldUploadToTlog(ref, force, ko.RekorURL)
if err != nil {
return err
}
Expand All @@ -200,7 +205,7 @@ func AttestCmd(ctx context.Context, ko KeyOpts, regOpts RegistryOpts, imageRef s
if sv.Cert != nil {
rekorBytes = sv.Cert
} else {
pemBytes, err := publicKeyPem(sv, options.WithContext(ctx))
pemBytes, err := signature.PublicKeyPem(sv, signatureoptions.WithContext(ctx))
if err != nil {
return err
}
Expand All @@ -216,11 +221,11 @@ func AttestCmd(ctx context.Context, ko KeyOpts, regOpts RegistryOpts, imageRef s
}
fmt.Fprintln(os.Stderr, "tlog entry created with index:", *entry.LogIndex)

uo.Bundle = bundle(entry)
uo.AdditionalAnnotations = parseAnnotations(entry)
uo.Bundle = sign.Bundle(entry)
uo.AdditionalAnnotations = sign.ParseAnnotations(entry)
}

attRef, err := AttachedImageTag(ref, cosign.AttestationTagSuffix, remoteOpts...)
attRef, err := image.AttachedImageTag(ref, cosign.AttestationTagSuffix, remoteOpts...)
if err != nil {
return err
}
Expand Down
10 changes: 6 additions & 4 deletions cmd/cosign/cli/clean.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,17 @@ import (
"github.com/google/go-containerregistry/pkg/v1/remote"
"github.com/peterbourgon/ff/v3/ffcli"

"github.com/sigstore/cosign/cmd/cosign/cli/options"
"github.com/sigstore/cosign/pkg/cosign"
"github.com/sigstore/cosign/pkg/image"
)

func Clean() *ffcli.Command {
var (
flagset = flag.NewFlagSet("cosign clean", flag.ExitOnError)
regOpts RegistryOpts
regOpts options.RegistryOpts
)
ApplyRegistryFlags(&regOpts, flagset)
options.ApplyRegistryFlags(&regOpts, flagset)
return &ffcli.Command{
Name: "clean",
ShortUsage: "cosign clean <image uri>",
Expand All @@ -49,14 +51,14 @@ func Clean() *ffcli.Command {
}
}

func CleanCmd(ctx context.Context, regOpts RegistryOpts, imageRef string) error {
func CleanCmd(ctx context.Context, regOpts options.RegistryOpts, imageRef string) error {
ref, err := name.ParseReference(imageRef)
if err != nil {
return err
}

remoteOpts := regOpts.GetRegistryClientOpts(ctx)
sigRef, err := AttachedImageTag(ref, cosign.SignatureTagSuffix, remoteOpts...)
sigRef, err := image.AttachedImageTag(ref, cosign.SignatureTagSuffix, remoteOpts...)
if err != nil {
return err
}
Expand Down
124 changes: 124 additions & 0 deletions cmd/cosign/cli/commands.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
//
// 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 (
"context"
"flag"
"fmt"
"os"

"github.com/google/go-containerregistry/pkg/logs"
"github.com/peterbourgon/ff/v3/ffcli"
"github.com/pkg/errors"
"github.com/spf13/cobra"

"github.com/sigstore/cosign/cmd/cosign/cli/attach"
"github.com/sigstore/cosign/cmd/cosign/cli/dockerfile"
"github.com/sigstore/cosign/cmd/cosign/cli/download"
"github.com/sigstore/cosign/cmd/cosign/cli/generate"
"github.com/sigstore/cosign/cmd/cosign/cli/manifest"
"github.com/sigstore/cosign/cmd/cosign/cli/options"
"github.com/sigstore/cosign/cmd/cosign/cli/pivcli"
"github.com/sigstore/cosign/cmd/cosign/cli/sign"
"github.com/sigstore/cosign/cmd/cosign/cli/upload"
"github.com/sigstore/cosign/cmd/cosign/cli/verify"
)

var (
ro = &options.RootOptions{}
)

func New() *cobra.Command {
cmd := &cobra.Command{
Use: "cosign",
RunE: func(cmd *cobra.Command, args []string) error {
root := &ffcli.Command{
ShortUsage: "cosign [flags] <subcommand>",
Subcommands: []*ffcli.Command{
// Key Management
PublicKey(),
generate.GenerateKeyPair(),
// Signing
verify.Verify(),
sign.Sign(),
Attest(),
generate.Generate(),
sign.SignBlob(),
verify.VerifyAttestation(),
verify.VerifyBlob(),
// Manifest sub-tree
manifest.Manifest(),
// Upload sub-tree
upload.Upload(),
// Download sub-tree
download.Download(),
// Attach sub-tree
attach.Attach(),
// Dockerfile sub-tree
dockerfile.Dockerfile(),
// PIV sub-tree
pivcli.PivKey(),
// PIV sub-tree
Copy(),
Clean(),
Triangulate(),
// Init
Init(),
// Version
Version()},
Exec: func(context.Context, []string) error {
return flag.ErrHelp
},
}

if err := root.Parse(args); err != nil {
printErrAndExit(err)
}

if ro.OutputFile != "" {
out, err := os.Create(ro.OutputFile)
if err != nil {
fmt.Fprintf(os.Stderr, "error: %v\n", errors.Wrapf(err, "Error creating output file %s", ro.OutputFile))
os.Exit(1)
}
stdout := os.Stdout
defer func() {
os.Stdout = stdout
out.Close()
}()
os.Stdout = out
}

if ro.Verbose {
logs.Debug.SetOutput(os.Stderr)
}

if err := root.Run(context.Background()); err != nil {
printErrAndExit(err)
}
return nil // TODO: use cobra to output help.
},
}
options.AddRootArgs(cmd, ro)

return cmd
}

func printErrAndExit(err error) {
fmt.Fprintf(os.Stderr, "error: %v\n", err)
os.Exit(1)
}
Loading

0 comments on commit e6fad61

Please sign in to comment.