From 82899f98379ac9eb2a3a9a4f6505c57415d1cbe8 Mon Sep 17 00:00:00 2001 From: Spike Curtis Date: Thu, 25 Aug 2022 14:51:30 -0700 Subject: [PATCH] CLI: coder licensese delete Signed-off-by: Spike Curtis --- enterprise/cli/licenses.go | 30 ++++++++++++++++++++- enterprise/cli/licenses_test.go | 48 +++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+), 1 deletion(-) diff --git a/enterprise/cli/licenses.go b/enterprise/cli/licenses.go index 72c7c3d67e819..e1cc4992387ea 100644 --- a/enterprise/cli/licenses.go +++ b/enterprise/cli/licenses.go @@ -6,6 +6,7 @@ import ( "io" "os" "regexp" + "strconv" "strings" "github.com/spf13/cobra" @@ -20,13 +21,14 @@ var jwtRegexp = regexp.MustCompile(`^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_ func licenses() *cobra.Command { cmd := &cobra.Command{ - Short: "Add, remove, and list licenses", + Short: "Add, delete, and list licenses", Use: "licenses", Aliases: []string{"license"}, } cmd.AddCommand( licenseAdd(), licensesList(), + licenseDelete(), ) return cmd } @@ -142,3 +144,29 @@ func licensesList() *cobra.Command { } return cmd } + +func licenseDelete() *cobra.Command { + cmd := &cobra.Command{ + Use: "delete ", + Short: "Delete license by ID", + Aliases: []string{"del", "rm"}, + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + client, err := agpl.CreateClient(cmd) + if err != nil { + return err + } + id, err := strconv.ParseInt(args[0], 10, 32) + if err != nil { + return xerrors.Errorf("license ID must be an integer: %s", args[0]) + } + err = client.DeleteLicense(cmd.Context(), int32(id)) + if err != nil { + return err + } + _, _ = fmt.Fprintf(cmd.OutOrStdout(), "License with ID %d deleted\n", id) + return nil + }, + } + return cmd +} diff --git a/enterprise/cli/licenses_test.go b/enterprise/cli/licenses_test.go index 79cf1256997f6..92fa91da4a685 100644 --- a/enterprise/cli/licenses_test.go +++ b/enterprise/cli/licenses_test.go @@ -191,6 +191,48 @@ func TestLicensesListReal(t *testing.T) { }) } +func TestLicensesDeleteFake(t *testing.T) { + t.Parallel() + // We can't check a real license into the git repo, and can't patch out the keys from here, + // so instead we have to fake the HTTP interaction. + t.Run("Mainline", func(t *testing.T) { + t.Parallel() + ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong) + defer cancel() + cmd := setupFakeLicenseServerTest(t, "licenses", "delete", "55") + pty := attachPty(t, cmd) + errC := make(chan error) + go func() { + errC <- cmd.ExecuteContext(ctx) + }() + require.NoError(t, <-errC) + pty.ExpectMatch("License with ID 55 deleted") + }) +} + +func TestLicensesDeleteReal(t *testing.T) { + t.Parallel() + t.Run("Empty", func(t *testing.T) { + t.Parallel() + client := coderdtest.New(t, &coderdtest.Options{APIBuilder: coderd.NewEnterprise}) + coderdtest.CreateFirstUser(t, client) + cmd, root := clitest.NewWithSubcommands(t, cli.EnterpriseSubcommands(), + "licenses", "delete", "1") + clitest.SetupConfig(t, client, root) + ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong) + defer cancel() + errC := make(chan error) + go func() { + errC <- cmd.ExecuteContext(ctx) + }() + err := <-errC + var coderError *codersdk.Error + require.True(t, xerrors.As(err, &coderError)) + assert.Equal(t, 404, coderError.StatusCode()) + assert.Contains(t, "Unknown license ID", coderError.Message) + }) +} + func setupFakeLicenseServerTest(t *testing.T, args ...string) *cobra.Command { t.Helper() s := httptest.NewServer(newFakeLicenseAPI(t)) @@ -217,6 +259,7 @@ func newFakeLicenseAPI(t *testing.T) http.Handler { r.Post("/api/v2/licenses", a.postLicense) r.Get("/api/v2/licenses", a.licenses) r.Get("/api/v2/buildinfo", a.noop) + r.Delete("/api/v2/licenses/{id}", a.deleteLicense) return r } @@ -282,3 +325,8 @@ func (s *fakeLicenseAPI) licenses(rw http.ResponseWriter, _ *http.Request) { err := json.NewEncoder(rw).Encode(resp) assert.NoError(s.t, err) } + +func (s *fakeLicenseAPI) deleteLicense(rw http.ResponseWriter, r *http.Request) { + assert.Equal(s.t, "55", chi.URLParam(r, "id")) + rw.WriteHeader(200) +} pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy