github.com/pluralsh/plural-cli@v0.9.5/cmd/plural/repos.go (about) 1 package plural 2 3 import ( 4 "fmt" 5 "strings" 6 7 "github.com/urfave/cli" 8 9 "github.com/pluralsh/plural-cli/pkg/api" 10 "github.com/pluralsh/plural-cli/pkg/bundle" 11 "github.com/pluralsh/plural-cli/pkg/config" 12 "github.com/pluralsh/plural-cli/pkg/format" 13 "github.com/pluralsh/plural-cli/pkg/manifest" 14 "github.com/pluralsh/plural-cli/pkg/utils" 15 ) 16 17 func (p *Plural) reposCommands() []cli.Command { 18 return []cli.Command{ 19 { 20 Name: "unlock", 21 Usage: "unlocks installations in a repo that have breaking changes", 22 ArgsUsage: "APP", 23 Action: latestVersion(requireArgs(p.handleUnlockRepo, []string{"APP"})), 24 }, 25 { 26 Name: "release", 27 Usage: "tags the installations in the current cluster with the given release channels", 28 ArgsUsage: "APP", 29 Flags: []cli.Flag{ 30 cli.StringSliceFlag{ 31 Name: "tag", 32 Usage: "tag name for a given release channel, eg stable, warm, dev, prod", 33 }, 34 }, 35 Action: latestVersion(requireArgs(p.handleRelease, []string{"APP"})), 36 }, 37 { 38 Name: "reinstall", 39 Usage: "reinstalls all bundles from a previous installation", 40 Flags: []cli.Flag{ 41 cli.BoolFlag{ 42 Name: "refresh", 43 Usage: "re-enter the configuration for all bundles", 44 }, 45 }, 46 Action: p.handleReinstall, 47 }, 48 { 49 Name: "reset", 50 Usage: "eliminates your current plural installation set, to change cloud provider or eject from plural", 51 Action: latestVersion(p.handleResetInstallations), 52 }, 53 { 54 Name: "synced", 55 Usage: "marks installations in this repo as being synced", 56 Action: p.handleMarkSynced, 57 }, 58 { 59 Name: "uninstall", 60 Usage: "uninstall an app from the plural api", 61 ArgsUsage: "APP", 62 Action: latestVersion(requireArgs(p.handleUninstall, []string{"APP"})), 63 }, 64 { 65 Name: "list", 66 Usage: "list available repositories to install", 67 ArgsUsage: "", 68 Flags: []cli.Flag{ 69 cli.StringFlag{ 70 Name: "query", 71 Usage: "string to search by", 72 }, 73 cli.StringFlag{ 74 Name: "format", 75 Usage: "format to print the repositories out, eg csv or default is table", 76 }, 77 }, 78 Action: latestVersion(p.handleListRepositories), 79 }, 80 } 81 } 82 83 func (p *Plural) handleRelease(c *cli.Context) error { 84 p.InitPluralClient() 85 app := c.Args().First() 86 tags := c.StringSlice("tag") 87 err := p.Release(c.Args().First(), c.StringSlice("tag")) 88 if err != nil { 89 return api.GetErrorResponse(err, "Release") 90 } 91 92 utils.Success("Published release for %s to channels [%s]\n", app, strings.Join(tags, ", ")) 93 return nil 94 } 95 96 func (p *Plural) handleUnlockRepo(c *cli.Context) error { 97 p.InitPluralClient() 98 err := p.UnlockRepository(c.Args().First()) 99 return api.GetErrorResponse(err, "UnlockRepository") 100 } 101 102 func (p *Plural) handleUninstall(c *cli.Context) error { 103 p.InitPluralClient() 104 inst, err := p.GetInstallation(c.Args().First()) 105 if err != nil { 106 return api.GetErrorResponse(err, "GetInstallation") 107 } 108 109 if inst == nil { 110 return fmt.Errorf("%s already uninstalled", c.Args().First()) 111 } 112 err = p.DeleteInstallation(inst.Id) 113 return api.GetErrorResponse(err, "DeleteInstallation") 114 } 115 116 func (p *Plural) handleListRepositories(c *cli.Context) error { 117 p.InitPluralClient() 118 repos, err := p.ListRepositories(c.String("query")) 119 if err != nil { 120 return api.GetErrorResponse(err, "ListRepositories") 121 } 122 123 addIcon := c.String("format") == "csv" 124 125 formatter := format.New(format.FormatType(c.String("format"))) 126 header := []string{"Repo", "Description", "Publisher", "Bundles"} 127 if addIcon { 128 header = append(header, "Icon") 129 } 130 131 formatter.Header(header) 132 for _, repo := range repos { 133 recipeNames := utils.Map(repo.Recipes, func(recipe *api.Recipe) string { 134 return recipe.Name 135 }) 136 137 line := []string{repo.Name, repo.Description, repo.Publisher.Name, strings.Join(recipeNames, ", ")} 138 if addIcon { 139 line = append(line, repo.Icon) 140 } 141 if err := formatter.Write(line); err != nil { 142 return err 143 } 144 } 145 146 if err := formatter.Flush(); err != nil { 147 return err 148 } 149 return nil 150 } 151 152 func (p *Plural) handleReinstall(c *cli.Context) error { 153 p.InitPluralClient() 154 ctx, err := manifest.FetchContext() 155 if err != nil { 156 return err 157 } 158 159 for _, b := range ctx.Bundles { 160 if err := bundle.Install(p.Client, b.Repository, b.Name, c.Bool("refresh")); err != nil { 161 return err 162 } 163 164 fmt.Println("Moving to the next bundle....") 165 } 166 167 return nil 168 } 169 170 func (p *Plural) handleMarkSynced(c *cli.Context) error { 171 p.InitPluralClient() 172 return p.MarkSynced(c.Args().Get(0)) 173 } 174 175 func (p *Plural) handleResetInstallations(c *cli.Context) error { 176 p.InitPluralClient() 177 conf := config.Read() 178 if !confirm(fmt.Sprintf("Are you sure you want to reset installations for %s? This will also wipe all oidc providers and any other associated state in the plural api", conf.Email), "PLURAL_REPOS_RESET_CONFIRM") { 179 return nil 180 } 181 182 count, err := p.ResetInstallations() 183 if err != nil { 184 return api.GetErrorResponse(err, "ResetInstallations") 185 } 186 187 fmt.Printf("Deleted %d installations in app.plural.sh\n", count) 188 fmt.Println("(you can recreate these at any time and any running infrastructure is not affected, plural will simply no longer deliver upgrades)") 189 utils.Note("Now run `plural bundle install <repo> <bundle-name>` to install a new app \n") 190 return nil 191 }