github.com/containerd/nerdctl@v1.7.7/cmd/nerdctl/image_cryptutil.go (about)

     1  /*
     2     Copyright The containerd Authors.
     3  
     4     Licensed under the Apache License, Version 2.0 (the "License");
     5     you may not use this file except in compliance with the License.
     6     You may obtain a copy of the License at
     7  
     8         http://www.apache.org/licenses/LICENSE-2.0
     9  
    10     Unless required by applicable law or agreed to in writing, software
    11     distributed under the License is distributed on an "AS IS" BASIS,
    12     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13     See the License for the specific language governing permissions and
    14     limitations under the License.
    15  */
    16  
    17  package main
    18  
    19  import (
    20  	"github.com/containerd/nerdctl/pkg/api/types"
    21  	"github.com/containerd/nerdctl/pkg/clientutil"
    22  	"github.com/containerd/nerdctl/pkg/cmd/image"
    23  	"github.com/spf13/cobra"
    24  )
    25  
    26  // registerImgcryptFlags register flags that correspond to parseImgcryptFlags().
    27  // Platform flags are registered too.
    28  //
    29  // From:
    30  // - https://github.com/containerd/imgcrypt/blob/v1.1.2/cmd/ctr/commands/flags/flags.go#L23-L44 (except skip-decrypt-auth)
    31  // - https://github.com/containerd/imgcrypt/blob/v1.1.2/cmd/ctr/commands/images/encrypt.go#L52-L55
    32  func registerImgcryptFlags(cmd *cobra.Command, encrypt bool) {
    33  	flags := cmd.Flags()
    34  
    35  	// #region platform flags
    36  	// platform is defined as StringSlice, not StringArray, to allow specifying "--platform=amd64,arm64"
    37  	flags.StringSlice("platform", []string{}, "Convert content for a specific platform")
    38  	cmd.RegisterFlagCompletionFunc("platform", shellCompletePlatforms)
    39  	flags.Bool("all-platforms", false, "Convert content for all platforms")
    40  	// #endregion
    41  
    42  	flags.String("gpg-homedir", "", "The GPG homedir to use; by default gpg uses ~/.gnupg")
    43  	flags.String("gpg-version", "", "The GPG version (\"v1\" or \"v2\"), default will make an educated guess")
    44  	flags.StringSlice("key", []string{}, "A secret key's filename and an optional password separated by colon; this option may be provided multiple times")
    45  	// While --recipient can be specified only for `nerdctl image encrypt`,
    46  	// --dec-recipient can be specified for both `nerdctl image encrypt` and `nerdctl image decrypt`.
    47  	flags.StringSlice("dec-recipient", []string{}, "Recipient of the image; used only for PKCS7 and must be an x509 certificate")
    48  
    49  	if encrypt {
    50  		// recipient is defined as StringSlice, not StringArray, to allow specifying "--recipient=jwe:FILE1,jwe:FILE2"
    51  		flags.StringSlice("recipient", []string{}, "Recipient of the image is the person who can decrypt it in the form specified above (i.e. jwe:/path/to/pubkey)")
    52  	}
    53  }
    54  
    55  func processImgCryptOptions(cmd *cobra.Command, args []string, encrypt bool) (types.ImageCryptOptions, error) {
    56  	globalOptions, err := processRootCmdFlags(cmd)
    57  	if err != nil {
    58  		return types.ImageCryptOptions{}, err
    59  	}
    60  	platforms, err := cmd.Flags().GetStringSlice("platform")
    61  	if err != nil {
    62  		return types.ImageCryptOptions{}, err
    63  	}
    64  	allPlatforms, err := cmd.Flags().GetBool("all-platforms")
    65  	if err != nil {
    66  		return types.ImageCryptOptions{}, err
    67  	}
    68  	gpgHomeDir, err := cmd.Flags().GetString("gpg-homedir")
    69  	if err != nil {
    70  		return types.ImageCryptOptions{}, err
    71  	}
    72  	gpgVersion, err := cmd.Flags().GetString("gpg-version")
    73  	if err != nil {
    74  		return types.ImageCryptOptions{}, err
    75  	}
    76  	keys, err := cmd.Flags().GetStringSlice("key")
    77  	if err != nil {
    78  		return types.ImageCryptOptions{}, err
    79  	}
    80  	decRecipients, err := cmd.Flags().GetStringSlice("dec-recipient")
    81  	if err != nil {
    82  		return types.ImageCryptOptions{}, err
    83  	}
    84  	var recipients []string
    85  	if encrypt {
    86  		recipients, err = cmd.Flags().GetStringSlice("recipient")
    87  		if err != nil {
    88  			return types.ImageCryptOptions{}, err
    89  		}
    90  	}
    91  	return types.ImageCryptOptions{
    92  		GOptions:      globalOptions,
    93  		Platforms:     platforms,
    94  		AllPlatforms:  allPlatforms,
    95  		GpgHomeDir:    gpgHomeDir,
    96  		GpgVersion:    gpgVersion,
    97  		Keys:          keys,
    98  		DecRecipients: decRecipients,
    99  		Recipients:    recipients,
   100  		Stdout:        cmd.OutOrStdout(),
   101  	}, nil
   102  }
   103  
   104  func getImgcryptAction(encrypt bool) func(cmd *cobra.Command, args []string) error {
   105  	return func(cmd *cobra.Command, args []string) error {
   106  		options, err := processImgCryptOptions(cmd, args, encrypt)
   107  		if err != nil {
   108  			return err
   109  		}
   110  		srcRawRef := args[0]
   111  		targetRawRef := args[1]
   112  
   113  		client, ctx, cancel, err := clientutil.NewClient(cmd.Context(), options.GOptions.Namespace, options.GOptions.Address)
   114  		if err != nil {
   115  			return err
   116  		}
   117  		defer cancel()
   118  
   119  		return image.Crypt(ctx, client, srcRawRef, targetRawRef, encrypt, options)
   120  	}
   121  }
   122  
   123  func imgcryptShellComplete(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
   124  	// show image names
   125  	return shellCompleteImageNames(cmd)
   126  }