Skip to content
This repository has been archived by the owner on May 26, 2023. It is now read-only.

Commit

Permalink
read cd from local filesystem for signing (#97)
Browse files Browse the repository at this point in the history
  • Loading branch information
jschicktanz authored Sep 30, 2022
1 parent 36440b6 commit 99d78bf
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 35 deletions.
2 changes: 1 addition & 1 deletion pkg/commands/componentarchive/remote/copy.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ func (o *CopyOptions) AddFlags(fs *pflag.FlagSet) {
fs.StringVar(&o.TargetArtifactRepository, "target-artifact-repository", "",
"target repository where the artifacts are copied to. This is only relevant if artifacts are copied by value and it will be defaulted to the target component repository")
fs.StringVar(&o.SourceArtifactRepository, "source-artifact-repository", "",
"source repository where realtiove oci artifacts are copied from. This is only relevant if artifacts are copied by value and it will be defaulted to the source component repository")
"source repository where relative oci artifacts are copied from. This is only relevant if artifacts are copied by value and it will be defaulted to the source component repository")
fs.BoolVar(&o.ConvertToRelativeOCIReferences, "relative-urls", false, "converts all copied oci artifacts to relative urls")
fs.StringSliceVar(&o.ReplaceOCIRefs, "replace-oci-ref", []string{}, "list of replace expressions in the format left:right. For every resource with accessType == "+cdv2.OCIRegistryType+", all occurences of 'left' in the target ref are replaced with 'right' before the upload")
fs.Uint64Var(&o.MaxRetries, "max-retries", 0, "maximum number of retries for copying a component descriptor")
Expand Down
3 changes: 1 addition & 2 deletions pkg/commands/componentarchive/signature/sign/rsa.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,7 @@ func NewRSASignCommand(ctx context.Context) *cobra.Command {
opts := &RSASignOptions{}
cmd := &cobra.Command{
Use: "rsa BASE_URL COMPONENT_NAME VERSION",
Args: cobra.ExactArgs(3),
Short: fmt.Sprintf("fetch the component descriptor from an oci registry, sign it using %s, and re-upload", cdv2.RSAPKCS1v15),
Short: fmt.Sprintf("fetch the component descriptor from an oci registry or local filesystem, sign it using %s, and re-upload", cdv2.RSAPKCS1v15),
Run: func(cmd *cobra.Command, args []string) {
if err := opts.Complete(args); err != nil {
fmt.Println(err.Error())
Expand Down
86 changes: 56 additions & 30 deletions pkg/commands/componentarchive/signature/sign/sign.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (

ociopts "github.com/gardener/component-cli/ociclient/options"
"github.com/gardener/component-cli/pkg/commands/constants"
"github.com/gardener/component-cli/pkg/componentarchive"
"github.com/gardener/component-cli/pkg/components"
"github.com/gardener/component-cli/pkg/logger"
"github.com/gardener/component-cli/pkg/signatures"
Expand All @@ -46,6 +47,8 @@ type GenericSignOptions struct {
// Version is the component Version in the oci registry.
Version string

ComponentArchivePath string

// SignatureName defines the name for the generated signature
SignatureName string

Expand All @@ -63,15 +66,30 @@ type GenericSignOptions struct {

// OciOptions contains all exposed options to configure the oci client.
OciOptions ociopts.Options

SignedRef string
}

//Complete validates the arguments and flags from the command line
// Complete validates the arguments and flags from the command line
func (o *GenericSignOptions) Complete(args []string) error {
o.BaseUrl = args[0]
o.ComponentName = args[1]
o.Version = args[2]
switch len(args) {
case 1:
o.ComponentArchivePath = args[0]
case 3:
o.BaseUrl = args[0]
o.ComponentName = args[1]
o.Version = args[2]

if len(o.BaseUrl) == 0 {
return errors.New("a base url must be provided")
}
if len(o.ComponentName) == 0 {
return errors.New("a component name must be provided")
}
if len(o.Version) == 0 {
return errors.New("a component version must be provided")
}
default:
return fmt.Errorf("illegal number of arguments: %d", len(args))
}

cliHomeDir, err := constants.CliHomeDir()
if err != nil {
Expand All @@ -83,28 +101,13 @@ func (o *GenericSignOptions) Complete(args []string) error {
return fmt.Errorf("unable to create cache directory %s: %w", o.OciOptions.CacheDir, err)
}

if len(o.BaseUrl) == 0 {
return errors.New("a base url must be provided")
}
if len(o.ComponentName) == 0 {
return errors.New("a component name must be provided")
}
if len(o.Version) == 0 {
return errors.New("a component version must be provided")
}
if o.UploadBaseUrlForSigned == "" {
return errors.New("a upload base url must be provided")
}
if o.SignatureName == "" {
return errors.New("a signature name must be provided")
}

signedRef, err := components.OCIRef(cdv2.NewOCIRegistryRepository(o.UploadBaseUrlForSigned, ""), o.ComponentName, o.Version)
if err != nil {
return fmt.Errorf("invalid reference for signed component descriptor: %w", err)
}
o.SignedRef = signedRef

return nil
}

Expand All @@ -118,17 +121,40 @@ func (o *GenericSignOptions) AddFlags(fs *pflag.FlagSet) {
}

func (o *GenericSignOptions) SignAndUploadWithSigner(ctx context.Context, log logr.Logger, fs vfs.FileSystem, signer cdv2Sign.Signer) error {
repoCtx := cdv2.NewOCIRegistryRepository(o.BaseUrl, "")

ociClient, cache, err := o.OciOptions.Build(log, fs)
if err != nil {
return fmt.Errorf("unable to build oci client: %s", err.Error())
}

cdresolver := cdoci.NewResolver(ociClient)
cd, blobResolver, err := cdresolver.ResolveWithBlobResolver(ctx, repoCtx, o.ComponentName, o.Version)
var cd cdv2.ComponentDescriptor
var blobResolver ctf.BlobResolver
var repoCtx *cdv2.OCIRegistryRepository
if o.ComponentArchivePath != "" {
archive, _, err := componentarchive.Parse(fs, o.ComponentArchivePath)
if err != nil {
return fmt.Errorf("unable to open component archive : %w", err)
}
cd = *archive.ComponentDescriptor
blobResolver = archive.BlobResolver
_repoCtx, err := components.GetOCIRepositoryContext(cd.GetEffectiveRepositoryContext())
if err != nil {
return fmt.Errorf("unable to create repository context: %w", err)
}
repoCtx = &_repoCtx
} else {
repoCtx = cdv2.NewOCIRegistryRepository(o.BaseUrl, "")
cdresolver := cdoci.NewResolver(ociClient)
_cd, _blobResolver, err := cdresolver.ResolveWithBlobResolver(ctx, repoCtx, o.ComponentName, o.Version)
if err != nil {
return fmt.Errorf("unable to to fetch component descriptor %s:%s: %w", o.ComponentName, o.Version, err)
}
cd = *_cd
blobResolver = _blobResolver
}

signedRef, err := components.OCIRef(cdv2.NewOCIRegistryRepository(o.UploadBaseUrlForSigned, ""), cd.Name, cd.Version)
if err != nil {
return fmt.Errorf("unable to to fetch component descriptor %s:%s: %w", o.ComponentName, o.Version, err)
return fmt.Errorf("invalid reference for signed component descriptor: %w", err)
}

blobResolvers := map[string]ctf.BlobResolver{}
Expand All @@ -139,7 +165,7 @@ func (o *GenericSignOptions) SignAndUploadWithSigner(ctx context.Context, log lo
skipAccessTypesMap[v] = true
}

digestedCds, err := signatures.RecursivelyAddDigestsToCd(cd, *repoCtx, ociClient, blobResolvers, context.TODO(), skipAccessTypesMap)
digestedCds, err := signatures.RecursivelyAddDigestsToCd(&cd, *repoCtx, ociClient, blobResolvers, context.TODO(), skipAccessTypesMap)
if err != nil {
return fmt.Errorf("unable to add digests to component descriptor: %w", err)
}
Expand Down Expand Up @@ -170,18 +196,18 @@ func (o *GenericSignOptions) SignAndUploadWithSigner(ctx context.Context, log lo
return fmt.Errorf("unable to create hasher: %w", err)
}

if err := cdv2Sign.SignComponentDescriptor(cd, signer, *hasher, o.SignatureName); err != nil {
if err := cdv2Sign.SignComponentDescriptor(&cd, signer, *hasher, o.SignatureName); err != nil {
return fmt.Errorf("unable to sign component descriptor: %w", err)
}
logger.Log.Info(fmt.Sprintf("Signed component descriptor %s %s", cd.Name, cd.Version))

logger.Log.Info(fmt.Sprintf("Uploading to %s %s %s", o.UploadBaseUrlForSigned, cd.Name, cd.Version))

if err := signatures.UploadCDPreservingLocalOciBlobs(ctx, *cd, *targetRepoCtx, ociClient, cache, blobResolvers, o.Force, log); err != nil {
if err := signatures.UploadCDPreservingLocalOciBlobs(ctx, cd, *targetRepoCtx, ociClient, cache, blobResolvers, o.Force, log); err != nil {
return fmt.Errorf("unable to upload component descriptor: %w", err)
}
}

log.Info(fmt.Sprintf("Successfully uploaded signed component descriptor at %s", o.SignedRef))
log.Info(fmt.Sprintf("Successfully uploaded signed component descriptor at %s", signedRef))
return nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,7 @@ func NewSigningServerSignCommand(ctx context.Context) *cobra.Command {
opts := &SigningServerSignOptions{}
cmd := &cobra.Command{
Use: "signing-server BASE_URL COMPONENT_NAME VERSION",
Args: cobra.ExactArgs(3),
Short: "fetch the component descriptor from an oci registry, sign it with a signature provided from a signing server, and re-upload",
Short: "fetch the component descriptor from an oci registry or local filesystem, sign it with a signature provided from a signing server, and re-upload",
Run: func(cmd *cobra.Command, args []string) {
if err := opts.Complete(args); err != nil {
fmt.Println(err.Error())
Expand Down

0 comments on commit 99d78bf

Please sign in to comment.