github.com/nats-io/nsc@v0.0.0-20221206222106-35db9400b257/cmd/importkeys.go (about)

     1  /*
     2   * Copyright 2018-2019 The NATS Authors
     3   * Licensed under the Apache License, Version 2.0 (the "License");
     4   * you may not use this file except in compliance with the License.
     5   * You may obtain a copy of the License at
     6   *
     7   * http://www.apache.org/licenses/LICENSE-2.0
     8   *
     9   * Unless required by applicable law or agreed to in writing, software
    10   * distributed under the License is distributed on an "AS IS" BASIS,
    11   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12   * See the License for the specific language governing permissions and
    13   * limitations under the License.
    14   */
    15  
    16  package cmd
    17  
    18  import (
    19  	"errors"
    20  	"fmt"
    21  	"os"
    22  	"path/filepath"
    23  
    24  	"github.com/nats-io/nkeys"
    25  	"github.com/nats-io/nsc/cmd/store"
    26  	"github.com/spf13/cobra"
    27  )
    28  
    29  func createImportKeysCmd() *cobra.Command {
    30  	var params ImportKeysParams
    31  	cmd := &cobra.Command{
    32  		Use:   "keys",
    33  		Short: "Imports all nkeys found in a directory",
    34  		Long:  `Imports all nkeys found in a directory`,
    35  		Example: `nsc import keys --dir <path>
    36  nsc import keys --recursive --dir <path>
    37  `,
    38  		Args:         MaxArgs(0),
    39  		SilenceUsage: false,
    40  		RunE: func(cmd *cobra.Command, args []string) error {
    41  			if err := RunMaybeStorelessAction(cmd, args, &params); err != nil {
    42  				return err
    43  			}
    44  			return nil
    45  		},
    46  	}
    47  	cmd.Flags().StringVarP(&params.Dir, "dir", "d", "", "directory to import keys from")
    48  	cmd.Flags().BoolVarP(&params.Recurse, "recurse", "R", false, "recurse directories")
    49  	cmd.MarkFlagRequired("dir")
    50  
    51  	return cmd
    52  }
    53  
    54  func init() {
    55  	importCmd.AddCommand(createImportKeysCmd())
    56  }
    57  
    58  type ImportKeysParams struct {
    59  	Dir     string
    60  	Recurse bool
    61  }
    62  
    63  func (p *ImportKeysParams) SetDefaults(ctx ActionCtx) error {
    64  	return nil
    65  }
    66  
    67  func (p *ImportKeysParams) PreInteractive(ctx ActionCtx) error {
    68  	return nil
    69  }
    70  
    71  func (p *ImportKeysParams) Load(ctx ActionCtx) error {
    72  	return nil
    73  }
    74  
    75  func (p *ImportKeysParams) PostInteractive(ctx ActionCtx) error {
    76  	return nil
    77  }
    78  
    79  func (p *ImportKeysParams) Validate(ctx ActionCtx) error {
    80  	var err error
    81  	p.Dir, err = Expand(p.Dir)
    82  	if err != nil {
    83  		return err
    84  	}
    85  
    86  	fi, err := os.Stat(p.Dir)
    87  	if err != nil {
    88  		return err
    89  	}
    90  	if !fi.IsDir() {
    91  		return fmt.Errorf("%#q is not a directory", p.Dir)
    92  	}
    93  	return nil
    94  }
    95  
    96  func (p *ImportKeysParams) Run(ctx ActionCtx) (store.Status, error) {
    97  	var a []*ImportNKeyJob
    98  	ks := ctx.StoreCtx().KeyStore
    99  	ctx.CurrentCmd().SilenceUsage = true
   100  	err := filepath.Walk(p.Dir, func(path string, info os.FileInfo, err error) error {
   101  		if info.IsDir() && path != p.Dir && !p.Recurse {
   102  			return filepath.SkipDir
   103  		}
   104  		ext := filepath.Ext(info.Name())
   105  		if ext == ".nk" {
   106  			var j ImportNKeyJob
   107  			a = append(a, &j)
   108  			j.filepath = path
   109  			j.keypair, j.err = ks.Read(path)
   110  			if j.err != nil {
   111  				return nil
   112  			}
   113  			j.description, j.err = j.keypair.PublicKey()
   114  			if j.err != nil {
   115  				return nil
   116  			}
   117  			_, j.err = j.keypair.Seed()
   118  			if j.err != nil {
   119  				return nil
   120  			}
   121  			_, j.err = ks.Store(j.keypair)
   122  		}
   123  		return nil
   124  	})
   125  
   126  	if len(a) == 0 {
   127  		return nil, errors.New("no nkey (.nk) files found")
   128  	}
   129  	r := store.NewDetailedReport(true)
   130  	for _, j := range a {
   131  		if j.err != nil {
   132  			r.AddError("failed to import %#q: %v", j.filepath, j.err)
   133  			continue
   134  		} else {
   135  			r.AddOK("%s was added to the keystore", j.description)
   136  		}
   137  	}
   138  	return r, err
   139  }
   140  
   141  type ImportNKeyJob struct {
   142  	description string
   143  	filepath    string
   144  	keypair     nkeys.KeyPair
   145  	err         error
   146  }