github.com/kbehouse/nsc@v0.0.6/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 "github.com/kbehouse/nsc/cmd/store" 23 cli "github.com/nats-io/cliprompts/v2" 24 "github.com/nats-io/jwt/v2" 25 "github.com/nats-io/nkeys" 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, ¶ms) 39 }, 40 } 41 cmd.Flags().StringVarP(¶ms.subject, "subject", "s", "", "stream/service subject") 42 cmd.Flags().StringVarP(¶ms.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 }