github.com/splunk/dan1-qbec@v0.7.3/internal/commands/delete.go (about) 1 /* 2 Copyright 2019 Splunk Inc. 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 commands 18 19 import ( 20 "fmt" 21 22 "github.com/spf13/cobra" 23 "github.com/splunk/qbec/internal/model" 24 "github.com/splunk/qbec/internal/objsort" 25 "github.com/splunk/qbec/internal/remote" 26 "github.com/splunk/qbec/internal/sio" 27 ) 28 29 type deleteCommandConfig struct { 30 *Config 31 dryRun bool 32 useLocal bool 33 filterFunc func() (filterParams, error) 34 } 35 36 func doDelete(args []string, config deleteCommandConfig) error { 37 if len(args) != 1 { 38 return newUsageError("exactly one environment required") 39 } 40 env := args[0] 41 if env == model.Baseline { // cannot apply for the baseline environment 42 return newUsageError("cannot delete baseline environment, use a real environment") 43 } 44 fp, err := config.filterFunc() 45 if err != nil { 46 return err 47 } 48 49 client, err := config.Client(env) 50 if err != nil { 51 return err 52 } 53 54 var deletions []model.K8sQbecMeta 55 if config.useLocal { 56 objects, err := filteredObjects(config.Config, env, client.ObjectKey, fp) 57 if err != nil { 58 return err 59 } 60 for _, o := range objects { 61 if o.GetName() != "" { 62 deletions = append(deletions, o) 63 } 64 } 65 } else { 66 all, err := allObjects(config.Config, env) 67 if err != nil { 68 return err 69 } 70 lister, scope, err := newRemoteLister(client, all, config.app.DefaultNamespace(env)) 71 if err != nil { 72 return err 73 } 74 lister.start(remote.ListQueryConfig{ 75 Application: config.App().Name(), 76 Tag: config.App().Tag(), 77 Environment: env, 78 KindFilter: fp.kindFilter, 79 ListQueryScope: scope, 80 }) 81 deletions, err = lister.deletions(nil, fp.Includes) 82 if err != nil { 83 return err 84 } 85 } 86 87 dryRun := "" 88 if config.dryRun { 89 dryRun = "[dry-run] " 90 } 91 92 // process deletions 93 deletions = objsort.SortMeta(deletions, sortConfig(client.IsNamespaced)) 94 95 if !config.dryRun && len(deletions) > 0 { 96 msg := fmt.Sprintf("will delete %d objects", len(deletions)) 97 if err := config.Confirm(msg); err != nil { 98 return err 99 } 100 } 101 102 var stats applyStats 103 for i := len(deletions) - 1; i >= 0; i-- { 104 ob := deletions[i] 105 name := client.DisplayName(ob) 106 res, err := client.Delete(ob, config.dryRun) 107 if err != nil { 108 return err 109 } 110 stats.update(name, res) 111 sio.Noticeln(dryRun+"delete", name) 112 sio.Println(res.Details) 113 } 114 115 printStats(config.Stdout(), &stats) 116 if config.dryRun { 117 sio.Noticeln("** dry-run mode, nothing was actually changed **") 118 } 119 return nil 120 } 121 122 func newDeleteCommand(cp ConfigProvider) *cobra.Command { 123 cmd := &cobra.Command{ 124 Use: "delete [-n] <environment>", 125 Short: "delete one or more components from a Kubernetes cluster", 126 Example: deleteExamples(), 127 } 128 129 config := deleteCommandConfig{ 130 filterFunc: addFilterParams(cmd, true), 131 } 132 133 cmd.Flags().BoolVarP(&config.dryRun, "dry-run", "n", false, "dry-run, do not delete resources but show what would happen") 134 cmd.Flags().BoolVar(&config.useLocal, "local", false, "use local object names to delete, do not derive list from server") 135 136 cmd.RunE = func(c *cobra.Command, args []string) error { 137 config.Config = cp() 138 return wrapError(doDelete(args, config)) 139 } 140 return cmd 141 }