github.com/nats-io/nsc@v0.0.0-20221206222106-35db9400b257/cmd/deleteimport.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  	"fmt"
    20  	"strings"
    21  
    22  	cli "github.com/nats-io/cliprompts/v2"
    23  	"github.com/nats-io/jwt/v2"
    24  	"github.com/nats-io/nkeys"
    25  	"github.com/nats-io/nsc/cmd/store"
    26  	"github.com/spf13/cobra"
    27  )
    28  
    29  func createDeleteImportCmd() *cobra.Command {
    30  	var params DeleteImportParams
    31  	cmd := &cobra.Command{
    32  		Use:          "import",
    33  		Short:        "Delete an import",
    34  		Args:         MaxArgs(0),
    35  		Example:      params.longHelp(),
    36  		SilenceUsage: true,
    37  		RunE: func(cmd *cobra.Command, args []string) error {
    38  			return RunAction(cmd, args, &params)
    39  		},
    40  	}
    41  	cmd.Flags().StringVarP(&params.subject, "subject", "s", "", "stream/service subject")
    42  	cmd.Flags().StringVarP(&params.srcAccount, "src-account", "", "", "source account (only if subject is ambiguous)")
    43  	params.AccountContextParams.BindFlags(cmd)
    44  
    45  	return cmd
    46  }
    47  
    48  func init() {
    49  	deleteCmd.AddCommand(createDeleteImportCmd())
    50  }
    51  
    52  type DeleteImportParams struct {
    53  	AccountContextParams
    54  	SignerParams
    55  	claim      *jwt.AccountClaims
    56  	index      int
    57  	subject    string
    58  	picked     bool
    59  	srcAccount string
    60  }
    61  
    62  func (p *DeleteImportParams) longHelp() string {
    63  	v := `toolName delete import -i
    64  toolName delete import -s "bar.>"`
    65  	return strings.Replace(v, "toolName", GetToolName(), -1)
    66  }
    67  
    68  func (p *DeleteImportParams) SetDefaults(ctx ActionCtx) error {
    69  	if err := p.AccountContextParams.SetDefaults(ctx); err != nil {
    70  		return err
    71  	}
    72  	p.SignerParams.SetDefaults(nkeys.PrefixByteOperator, true, ctx)
    73  	p.index = -1
    74  
    75  	return nil
    76  }
    77  
    78  func (p *DeleteImportParams) PreInteractive(ctx ActionCtx) error {
    79  	p.picked = true
    80  	var err error
    81  	if err = p.AccountContextParams.Edit(ctx); err != nil {
    82  		return err
    83  	}
    84  	return nil
    85  }
    86  
    87  func (p *DeleteImportParams) Load(ctx ActionCtx) error {
    88  	var err error
    89  
    90  	if err = p.AccountContextParams.Validate(ctx); err != nil {
    91  		return err
    92  	}
    93  
    94  	p.claim, err = ctx.StoreCtx().Store.ReadAccountClaim(p.AccountContextParams.Name)
    95  	if err != nil {
    96  		return err
    97  	}
    98  
    99  	switch len(p.claim.Imports) {
   100  	case 0:
   101  		return fmt.Errorf("account %q doesn't have imports", p.AccountContextParams.Name)
   102  	case 1:
   103  		if p.subject == "" {
   104  			p.subject = string(p.claim.Imports[0].Subject)
   105  		}
   106  	}
   107  
   108  	// if auto-selecting there can only be one
   109  	count := 0
   110  	last := -1
   111  	for i, e := range p.claim.Imports {
   112  		if string(e.Subject) == p.subject {
   113  			count++
   114  			last = i
   115  		}
   116  	}
   117  	if count == 1 {
   118  		p.index = last
   119  	}
   120  	// if we have more than one, both the subject and src account must match
   121  	if count > 1 {
   122  		for i, e := range p.claim.Imports {
   123  			if string(e.Subject) == p.subject && p.srcAccount == e.Account {
   124  				p.index = i
   125  				break
   126  			}
   127  		}
   128  	}
   129  	return nil
   130  }
   131  
   132  func (p *DeleteImportParams) PostInteractive(ctx ActionCtx) error {
   133  	var err error
   134  
   135  	choices, err := GetAccountImports(p.claim)
   136  	if err != nil {
   137  		return err
   138  	}
   139  	labels := choices.String()
   140  	p.index, err = cli.Select("select import to delete", "", labels)
   141  	if err != nil {
   142  		return err
   143  	}
   144  
   145  	if err = p.SignerParams.Edit(ctx); err != nil {
   146  		return err
   147  	}
   148  
   149  	return nil
   150  }
   151  
   152  func (p *DeleteImportParams) Validate(ctx ActionCtx) error {
   153  	var err error
   154  	if p.subject == "" && p.index == -1 {
   155  		return fmt.Errorf("subject is required")
   156  	}
   157  
   158  	if p.index == -1 && p.srcAccount == "" && !p.picked {
   159  		var accounts []string
   160  		for _, e := range p.claim.Imports {
   161  			if string(e.Subject) == p.subject {
   162  				accounts = append(accounts, e.Account)
   163  			}
   164  		}
   165  		if len(accounts) > 1 && p.srcAccount == "" {
   166  			return fmt.Errorf("more than one import %q found - specify --src-account with one of %s", p.subject, strings.Join(accounts, ", "))
   167  		}
   168  	}
   169  
   170  	if p.index == -1 {
   171  		m := fmt.Sprintf("no import matching %q found", p.subject)
   172  		if p.srcAccount != "" {
   173  			m = fmt.Sprintf("%s from account %s", m, p.srcAccount)
   174  		}
   175  		return fmt.Errorf(m)
   176  	}
   177  
   178  	if err = p.SignerParams.Resolve(ctx); err != nil {
   179  		return err
   180  	}
   181  	return nil
   182  }
   183  
   184  func (p *DeleteImportParams) Run(ctx ActionCtx) (store.Status, error) {
   185  	din := p.claim.Imports[p.index]
   186  	p.claim.Imports = append(p.claim.Imports[:p.index], p.claim.Imports[p.index+1:]...)
   187  	token, err := p.claim.Encode(p.signerKP)
   188  	if err != nil {
   189  		return nil, err
   190  	}
   191  
   192  	r := store.NewDetailedReport(true)
   193  	r.AddOK("deleted %s import %q", din.Type, din.Subject)
   194  	rs, err := ctx.StoreCtx().Store.StoreClaim([]byte(token))
   195  	if rs != nil {
   196  		r.Add(rs)
   197  	}
   198  	if err != nil {
   199  		r.Add(store.FromError(err))
   200  	}
   201  	return r, nil
   202  }