From a3c2a92a02c952dbafe00baf6af3c6970b396a4c Mon Sep 17 00:00:00 2001 From: Robi Nino Date: Sun, 17 Mar 2024 18:23:23 +0200 Subject: [PATCH] Artifactory Release Lifecycle Management - Support release bundles deletion locally and remotely (#2452) --- docs/lifecycle/deletelocal/help.go | 20 +++++++ docs/lifecycle/deleteremote/help.go | 15 +++++ go.mod | 4 +- go.sum | 8 +-- lifecycle/cli.go | 92 ++++++++++++++++++++++++++++- lifecycle_test.go | 2 +- utils/cliutils/commandsflags.go | 26 ++++---- 7 files changed, 147 insertions(+), 20 deletions(-) create mode 100644 docs/lifecycle/deletelocal/help.go create mode 100644 docs/lifecycle/deleteremote/help.go diff --git a/docs/lifecycle/deletelocal/help.go b/docs/lifecycle/deletelocal/help.go new file mode 100644 index 000000000..fe843fe4e --- /dev/null +++ b/docs/lifecycle/deletelocal/help.go @@ -0,0 +1,20 @@ +package deletelocal + +var Usage = []string{"rbdell [command options] ", + "rbdell [command options] "} + +func GetDescription() string { + return "Delete all release bundle promotions to an environment or delete a release bundle locally altogether." +} + +func GetArguments() string { + return ` release bundle name + Name of the Release Bundle to delete locally. + + release bundle version + Version of the Release Bundle to delete locally. + + environment + If provided, all promotions to this environment are deleted. + Otherwise, the release bundle is deleted locally with all its promotions.` +} diff --git a/docs/lifecycle/deleteremote/help.go b/docs/lifecycle/deleteremote/help.go new file mode 100644 index 000000000..9d0264873 --- /dev/null +++ b/docs/lifecycle/deleteremote/help.go @@ -0,0 +1,15 @@ +package deleteremote + +var Usage = []string{"rbdelr [command options] "} + +func GetDescription() string { + return "Delete a release bundle remotely." +} + +func GetArguments() string { + return ` release bundle name + Name of the Release Bundle to delete remotely. + + release bundle version + Version of the Release Bundle to delete remotely.` +} diff --git a/go.mod b/go.mod index 940abb3cf..722196ef6 100644 --- a/go.mod +++ b/go.mod @@ -130,9 +130,9 @@ require ( gopkg.in/yaml.v3 v3.0.1 // indirect ) -replace github.com/jfrog/jfrog-cli-core/v2 => github.com/jfrog/jfrog-cli-core/v2 v2.31.1-0.20240312151007-5979ebb571c7 +replace github.com/jfrog/jfrog-cli-core/v2 => github.com/jfrog/jfrog-cli-core/v2 v2.31.1-0.20240317161137-662abefabe8e -replace github.com/jfrog/jfrog-client-go => github.com/jfrog/jfrog-client-go v1.28.1-0.20240228121257-3414cc0ffcb6 +replace github.com/jfrog/jfrog-client-go => github.com/jfrog/jfrog-client-go v1.28.1-0.20240317160615-e419c2a9e723 replace github.com/jfrog/jfrog-cli-security => github.com/jfrog/jfrog-cli-security v1.0.4-0.20240303113253-d82ecc02d9eb diff --git a/go.sum b/go.sum index b08e4a0c6..191ccceb6 100644 --- a/go.sum +++ b/go.sum @@ -127,12 +127,12 @@ github.com/jfrog/gofrog v1.6.3 h1:F7He0+75HcgCe6SGTSHLFCBDxiE2Ja0tekvvcktW6wc= github.com/jfrog/gofrog v1.6.3/go.mod h1:SZ1EPJUruxrVGndOzHd+LTiwWYKMlHqhKD+eu+v5Hqg= github.com/jfrog/jfrog-apps-config v1.0.1 h1:mtv6k7g8A8BVhlHGlSveapqf4mJfonwvXYLipdsOFMY= github.com/jfrog/jfrog-apps-config v1.0.1/go.mod h1:8AIIr1oY9JuH5dylz2S6f8Ym2MaadPLR6noCBO4C22w= -github.com/jfrog/jfrog-cli-core/v2 v2.31.1-0.20240312151007-5979ebb571c7 h1:bqbrSRA2tONZqm1Y+tuuiCJaYIc9G8RZQHuWjXh9xA0= -github.com/jfrog/jfrog-cli-core/v2 v2.31.1-0.20240312151007-5979ebb571c7/go.mod h1:fTnA9KjwuMEWnqAFPPoLc6IzvYxD8SorqawESk74fP8= +github.com/jfrog/jfrog-cli-core/v2 v2.31.1-0.20240317161137-662abefabe8e h1:mmM8VzqO3Qc/bzvw4onPEoMV96QfOijnZpNMr8AOFEs= +github.com/jfrog/jfrog-cli-core/v2 v2.31.1-0.20240317161137-662abefabe8e/go.mod h1:EIVjqkE5U1AMpZMLhL814Xpxc5hOqbPxxGiXHeojg7A= github.com/jfrog/jfrog-cli-security v1.0.4-0.20240303113253-d82ecc02d9eb h1:JUqwNOqzwj+1oZQXY1p/xnnH97BEMfOKGG505vGVIe4= github.com/jfrog/jfrog-cli-security v1.0.4-0.20240303113253-d82ecc02d9eb/go.mod h1:pOqg/hGw6eHWNyLDHeOCyq/Ntuc+wLJTV2Z8XuwXspU= -github.com/jfrog/jfrog-client-go v1.28.1-0.20240228121257-3414cc0ffcb6 h1:W+79g2W3ARRhIZtBfG0t73fi4IlyiIRWwdm1tajOkkc= -github.com/jfrog/jfrog-client-go v1.28.1-0.20240228121257-3414cc0ffcb6/go.mod h1:WhVrqiqhSNFwj58/RQIrJEd28PHH1LTD4eWE0vBXv1o= +github.com/jfrog/jfrog-client-go v1.28.1-0.20240317160615-e419c2a9e723 h1:0N/fdI2PXLjdWZieh7ib+6gb87yw3x22V7t1YZJvWOA= +github.com/jfrog/jfrog-client-go v1.28.1-0.20240317160615-e419c2a9e723/go.mod h1:NB8tYFgkWtn+wHsKC+aYC75aLnS6yW81d8JAFTBxsi0= github.com/jszwec/csvutil v1.10.0 h1:upMDUxhQKqZ5ZDCs/wy+8Kib8rZR8I8lOR34yJkdqhI= github.com/jszwec/csvutil v1.10.0/go.mod h1:/E4ONrmGkwmWsk9ae9jpXnv9QT8pLHEPcCirMFhxG9I= github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= diff --git a/lifecycle/cli.go b/lifecycle/cli.go index a27268cb8..a29a01882 100644 --- a/lifecycle/cli.go +++ b/lifecycle/cli.go @@ -9,6 +9,8 @@ import ( coreConfig "github.com/jfrog/jfrog-cli-core/v2/utils/config" "github.com/jfrog/jfrog-cli/docs/common" rbCreate "github.com/jfrog/jfrog-cli/docs/lifecycle/create" + rbDeleteLocal "github.com/jfrog/jfrog-cli/docs/lifecycle/deletelocal" + rbDeleteRemote "github.com/jfrog/jfrog-cli/docs/lifecycle/deleteremote" rbDistribute "github.com/jfrog/jfrog-cli/docs/lifecycle/distribute" rbPromote "github.com/jfrog/jfrog-cli/docs/lifecycle/promote" "github.com/jfrog/jfrog-cli/utils/cliutils" @@ -59,6 +61,30 @@ func GetCommands() []cli.Command { Category: lcCategory, Action: distribute, }, + { + Name: "release-bundle-delete-local", + Aliases: []string{"rbdell"}, + Flags: cliutils.GetCommandFlags(cliutils.ReleaseBundleDeleteLocal), + Usage: rbDeleteLocal.GetDescription(), + HelpName: coreCommon.CreateUsage("rbdell", rbDeleteLocal.GetDescription(), rbDeleteLocal.Usage), + UsageText: rbDeleteLocal.GetArguments(), + ArgsUsage: common.CreateEnvVars(), + BashComplete: coreCommon.CreateBashCompletionFunc(), + Category: lcCategory, + Action: deleteLocal, + }, + { + Name: "release-bundle-delete-remote", + Aliases: []string{"rbdelr"}, + Flags: cliutils.GetCommandFlags(cliutils.ReleaseBundleDeleteRemote), + Usage: rbDeleteRemote.GetDescription(), + HelpName: coreCommon.CreateUsage("rbdelr", rbDeleteRemote.GetDescription(), rbDeleteRemote.Usage), + UsageText: rbDeleteRemote.GetArguments(), + ArgsUsage: common.CreateEnvVars(), + BashComplete: coreCommon.CreateBashCompletionFunc(), + Category: lcCategory, + Action: deleteRemote, + }, }) } @@ -118,11 +144,11 @@ func promote(c *cli.Context) error { return err } - createCmd := lifecycle.NewReleaseBundlePromoteCommand().SetServerDetails(lcDetails).SetReleaseBundleName(c.Args().Get(0)). + promoteCmd := lifecycle.NewReleaseBundlePromoteCommand().SetServerDetails(lcDetails).SetReleaseBundleName(c.Args().Get(0)). SetReleaseBundleVersion(c.Args().Get(1)).SetEnvironment(c.Args().Get(2)).SetSigningKeyName(c.String(cliutils.SigningKey)). SetSync(c.Bool(cliutils.Sync)).SetReleaseBundleProject(cliutils.GetProject(c)). SetIncludeReposPatterns(splitRepos(c, cliutils.IncludeRepos)).SetExcludeReposPatterns(splitRepos(c, cliutils.ExcludeRepos)) - return commands.Exec(createCmd) + return commands.Exec(promoteCmd) } func distribute(c *cli.Context) error { @@ -150,6 +176,68 @@ func distribute(c *cli.Context) error { return commands.Exec(distributeCmd) } +func deleteLocal(c *cli.Context) error { + if show, err := cliutils.ShowCmdHelpIfNeeded(c, c.Args()); show || err != nil { + return err + } + + if c.NArg() != 2 && c.NArg() != 3 { + return cliutils.WrongNumberOfArgumentsHandler(c) + } + + lcDetails, err := createLifecycleDetailsByFlags(c) + if err != nil { + return err + } + + environment := "" + if c.NArg() == 3 { + environment = c.Args().Get(2) + } + + deleteCmd := lifecycle.NewReleaseBundleDeleteCommand(). + SetServerDetails(lcDetails). + SetReleaseBundleName(c.Args().Get(0)). + SetReleaseBundleVersion(c.Args().Get(1)). + SetEnvironment(environment). + SetQuiet(cliutils.GetQuietValue(c)). + SetReleaseBundleProject(cliutils.GetProject(c)). + SetSync(c.Bool(cliutils.Sync)) + return commands.Exec(deleteCmd) +} + +func deleteRemote(c *cli.Context) error { + if show, err := cliutils.ShowCmdHelpIfNeeded(c, c.Args()); show || err != nil { + return err + } + + if c.NArg() != 2 { + return cliutils.WrongNumberOfArgumentsHandler(c) + } + + lcDetails, err := createLifecycleDetailsByFlags(c) + if err != nil { + return err + } + + distributionRules, maxWaitMinutes, _, err := distribution.InitReleaseBundleDistributeCmd(c) + if err != nil { + return err + } + + deleteCmd := lifecycle.NewReleaseBundleRemoteDeleteCommand(). + SetServerDetails(lcDetails). + SetReleaseBundleName(c.Args().Get(0)). + SetReleaseBundleVersion(c.Args().Get(1)). + SetDistributionRules(distributionRules). + SetDryRun(c.Bool("dry-run")). + SetMaxWaitMinutes(maxWaitMinutes). + SetQuiet(cliutils.GetQuietValue(c)). + SetReleaseBundleProject(cliutils.GetProject(c)). + SetSync(c.Bool(cliutils.Sync)) + return commands.Exec(deleteCmd) +} + func validateDistributeCommand(c *cli.Context) error { if err := distribution.ValidateReleaseBundleDistributeCmd(c); err != nil { return err diff --git a/lifecycle_test.go b/lifecycle_test.go index b25d75646..16d1f5634 100644 --- a/lifecycle_test.go +++ b/lifecycle_test.go @@ -204,7 +204,7 @@ func deleteReleaseBundle(t *testing.T, lcManager *lifecycle.LifecycleServicesMan ReleaseBundleVersion: rbVersion, } - assert.NoError(t, lcManager.DeleteReleaseBundle(rbDetails, services.CommonOptionalQueryParams{Async: false})) + assert.NoError(t, lcManager.DeleteReleaseBundleVersion(rbDetails, services.CommonOptionalQueryParams{Async: false})) // Wait after remote deleting. Can be removed once remote deleting supports sync. time.Sleep(5 * time.Second) } diff --git a/utils/cliutils/commandsflags.go b/utils/cliutils/commandsflags.go index c84752bdf..27a6b1831 100644 --- a/utils/cliutils/commandsflags.go +++ b/utils/cliutils/commandsflags.go @@ -118,9 +118,11 @@ const ( TransferInstall = "transfer-plugin-install" // Lifecycle commands keys - ReleaseBundleCreate = "release-bundle-create" - ReleaseBundlePromote = "release-bundle-promote" - ReleaseBundleDistribute = "release-bundle-distribute" + ReleaseBundleCreate = "release-bundle-create" + ReleaseBundlePromote = "release-bundle-promote" + ReleaseBundleDistribute = "release-bundle-distribute" + ReleaseBundleDeleteLocal = "release-bundle-delete-local" + ReleaseBundleDeleteRemote = "release-bundle-delete-remote" // Access Token Create commands keys AccessTokenCreate = "access-token-create" @@ -566,7 +568,6 @@ const ( // Unique lifecycle flags lifecyclePrefix = "lc-" - lcUrl = lifecyclePrefix + url lcSync = lifecyclePrefix + Sync lcProject = lifecyclePrefix + Project Builds = "builds" @@ -1626,10 +1627,6 @@ var flagsMap = map[string]cli.Flag{ Name: PreChecks, Usage: "[Default: false] Set to true to run pre-transfer checks.` `", }, - lcUrl: cli.StringFlag{ - Name: url, - Usage: "[Optional] JFrog platform URL.` `", - }, lcSync: cli.BoolFlag{ Name: Sync, Usage: "[Default: false] Set to true to run synchronously.` `", @@ -2003,15 +2000,22 @@ var commandFlags = map[string][]string{ installPluginVersion, InstallPluginSrcDir, InstallPluginHomeDir, }, ReleaseBundleCreate: { - lcUrl, user, password, accessToken, serverId, lcSigningKey, lcSync, lcProject, lcBuilds, lcReleaseBundles, + platformUrl, user, password, accessToken, serverId, lcSigningKey, lcSync, lcProject, lcBuilds, lcReleaseBundles, }, ReleaseBundlePromote: { - lcUrl, user, password, accessToken, serverId, lcSigningKey, lcSync, lcProject, lcIncludeRepos, lcExcludeRepos, + platformUrl, user, password, accessToken, serverId, lcSigningKey, lcSync, lcProject, lcIncludeRepos, lcExcludeRepos, }, ReleaseBundleDistribute: { - lcUrl, user, password, accessToken, serverId, lcDryRun, DistRules, site, city, countryCodes, + platformUrl, user, password, accessToken, serverId, lcDryRun, DistRules, site, city, countryCodes, InsecureTls, CreateRepo, lcPathMappingPattern, lcPathMappingTarget, }, + ReleaseBundleDeleteLocal: { + platformUrl, user, password, accessToken, serverId, deleteQuiet, lcSync, lcProject, + }, + ReleaseBundleDeleteRemote: { + platformUrl, user, password, accessToken, serverId, deleteQuiet, lcDryRun, DistRules, site, city, countryCodes, + lcSync, maxWaitMinutes, lcProject, + }, // Mission Control's commands McConfig: { mcUrl, mcAccessToken, mcInteractive,