Skip to content

Commit 8502d37

Browse files
committed
Commands for binding and unbinding packages to applications
1 parent 3e143c5 commit 8502d37

File tree

11 files changed

+271
-37
lines changed

11 files changed

+271
-37
lines changed

apptrust/commands/flags.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ const (
1313
PromoteAppVersion = "version-promote"
1414
DeleteAppVersion = "version-delete"
1515
PackageBind = "package-bind"
16+
PackageUnbind = "package-unbind"
1617
CreateApp = "app-create"
1718
UpdateApp = "app-update"
1819
DeleteApp = "app-delete"
@@ -106,6 +107,13 @@ var commandFlags = map[string][]string{
106107
serverId,
107108
},
108109

110+
PackageUnbind: {
111+
url,
112+
user,
113+
accessToken,
114+
serverId,
115+
},
116+
109117
Ping: {
110118
url,
111119
user,
@@ -147,6 +155,13 @@ var commandFlags = map[string][]string{
147155
SpecFlag,
148156
SpecVarsFlag,
149157
},
158+
159+
DeleteApp: {
160+
url,
161+
user,
162+
accessToken,
163+
serverId,
164+
},
150165
}
151166

152167
func GetCommandFlags(cmdKey string) []components.Flag {

apptrust/commands/package/bind_package_cmd.go

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -45,33 +45,19 @@ func (bp *bindPackageCommand) prepareAndRunCommand(ctx *components.Context) erro
4545
if err != nil {
4646
return err
4747
}
48-
bp.requestPayload, err = bp.buildRequestPayload(ctx)
48+
bp.requestPayload, err = BuildPackageRequestPayload(ctx)
4949
if err != nil {
5050
return err
5151
}
5252

5353
return commonCLiCommands.Exec(bp)
5454
}
5555

56-
func (bp *bindPackageCommand) buildRequestPayload(ctx *components.Context) (*model.BindPackageRequest, error) {
57-
applicationKey := ctx.Arguments[0]
58-
packageType := ctx.Arguments[1]
59-
packageName := ctx.Arguments[2]
60-
packageVersion := ctx.Arguments[3]
61-
62-
return &model.BindPackageRequest{
63-
ApplicationKey: applicationKey,
64-
Type: packageType,
65-
Name: packageName,
66-
Version: packageVersion,
67-
}, nil
68-
}
69-
7056
func GetBindPackageCommand(appContext app.Context) components.Command {
7157
cmd := &bindPackageCommand{packageService: appContext.GetPackageService()}
7258
return components.Command{
7359
Name: commands.PackageBind,
74-
Description: "Bind packages to an application version.",
60+
Description: "Bind packages to an application.",
7561
Aliases: []string{"pb"},
7662
Arguments: []components.Argument{
7763
{
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package packagecmds
2+
3+
import (
4+
"github.com/jfrog/jfrog-cli-application/apptrust/app"
5+
"github.com/jfrog/jfrog-cli-application/apptrust/commands"
6+
"github.com/jfrog/jfrog-cli-application/apptrust/commands/utils"
7+
"github.com/jfrog/jfrog-cli-application/apptrust/model"
8+
"github.com/jfrog/jfrog-cli-application/apptrust/service"
9+
"github.com/jfrog/jfrog-cli-application/apptrust/service/packages"
10+
commonCLiCommands "github.com/jfrog/jfrog-cli-core/v2/common/commands"
11+
pluginsCommon "github.com/jfrog/jfrog-cli-core/v2/plugins/common"
12+
"github.com/jfrog/jfrog-cli-core/v2/plugins/components"
13+
coreConfig "github.com/jfrog/jfrog-cli-core/v2/utils/config"
14+
)
15+
16+
type unbindPackageCommand struct {
17+
packageService packages.PackageService
18+
serverDetails *coreConfig.ServerDetails
19+
requestPayload *model.BindPackageRequest
20+
}
21+
22+
func (up *unbindPackageCommand) Run() error {
23+
ctx, err := service.NewContext(*up.serverDetails)
24+
if err != nil {
25+
return err
26+
}
27+
return up.packageService.UnbindPackage(ctx, up.requestPayload)
28+
}
29+
30+
func (up *unbindPackageCommand) ServerDetails() (*coreConfig.ServerDetails, error) {
31+
return up.serverDetails, nil
32+
}
33+
34+
func (up *unbindPackageCommand) CommandName() string {
35+
return commands.PackageUnbind
36+
}
37+
38+
func (up *unbindPackageCommand) prepareAndRunCommand(ctx *components.Context) error {
39+
if len(ctx.Arguments) != 4 {
40+
return pluginsCommon.WrongNumberOfArgumentsHandler(ctx)
41+
}
42+
43+
var err error
44+
up.serverDetails, err = utils.ServerDetailsByFlags(ctx)
45+
if err != nil {
46+
return err
47+
}
48+
up.requestPayload, err = BuildPackageRequestPayload(ctx)
49+
if err != nil {
50+
return err
51+
}
52+
53+
return commonCLiCommands.Exec(up)
54+
}
55+
56+
func GetUnbindPackageCommand(appContext app.Context) components.Command {
57+
cmd := &unbindPackageCommand{packageService: appContext.GetPackageService()}
58+
return components.Command{
59+
Name: commands.PackageUnbind,
60+
Description: "Unbind packages from an application.",
61+
Aliases: []string{"pu"},
62+
Arguments: []components.Argument{
63+
{
64+
Name: "application-key",
65+
Description: "The key of the application to unbind the package from.",
66+
},
67+
{
68+
Name: "package-type",
69+
Description: "Package type (e.g., npm, docker, maven, generic).",
70+
},
71+
{
72+
Name: "package-name",
73+
Description: "Package name.",
74+
},
75+
{
76+
Name: "package-version",
77+
Description: "Package version.",
78+
},
79+
},
80+
Flags: commands.GetCommandFlags(commands.PackageUnbind),
81+
Action: cmd.prepareAndRunCommand,
82+
}
83+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package packagecmds
2+
3+
import (
4+
"errors"
5+
"testing"
6+
7+
"github.com/jfrog/jfrog-cli-application/apptrust/model"
8+
mockpackages "github.com/jfrog/jfrog-cli-application/apptrust/service/packages/mocks"
9+
"github.com/jfrog/jfrog-cli-core/v2/utils/config"
10+
"github.com/stretchr/testify/assert"
11+
"go.uber.org/mock/gomock"
12+
)
13+
14+
func TestUnbindPackageCommand_Run(t *testing.T) {
15+
ctrl := gomock.NewController(t)
16+
defer ctrl.Finish()
17+
18+
serverDetails := &config.ServerDetails{Url: "https://example.com"}
19+
requestPayload := &model.BindPackageRequest{
20+
ApplicationKey: "app-key",
21+
Type: "npm",
22+
Name: "test-package",
23+
Version: "1.0.0",
24+
}
25+
26+
mockPackageService := mockpackages.NewMockPackageService(ctrl)
27+
mockPackageService.EXPECT().UnbindPackage(gomock.Any(), requestPayload).
28+
Return(nil).Times(1)
29+
30+
cmd := &unbindPackageCommand{
31+
packageService: mockPackageService,
32+
serverDetails: serverDetails,
33+
requestPayload: requestPayload,
34+
}
35+
36+
err := cmd.Run()
37+
assert.NoError(t, err)
38+
}
39+
40+
func TestUnbindPackageCommand_Run_Error(t *testing.T) {
41+
ctrl := gomock.NewController(t)
42+
defer ctrl.Finish()
43+
44+
serverDetails := &config.ServerDetails{Url: "https://example.com"}
45+
requestPayload := &model.BindPackageRequest{
46+
ApplicationKey: "app-key",
47+
Type: "npm",
48+
Name: "test-package",
49+
Version: "1.0.0",
50+
}
51+
52+
mockPackageService := mockpackages.NewMockPackageService(ctrl)
53+
mockPackageService.EXPECT().UnbindPackage(gomock.Any(), requestPayload).
54+
Return(errors.New("unbind error")).Times(1)
55+
56+
cmd := &unbindPackageCommand{
57+
packageService: mockPackageService,
58+
serverDetails: serverDetails,
59+
requestPayload: requestPayload,
60+
}
61+
62+
err := cmd.Run()
63+
assert.Error(t, err)
64+
assert.Equal(t, "unbind error", err.Error())
65+
}

apptrust/commands/package/utils.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package packagecmds
2+
3+
import (
4+
"github.com/jfrog/jfrog-cli-application/apptrust/model"
5+
"github.com/jfrog/jfrog-cli-core/v2/plugins/components"
6+
)
7+
8+
// BuildPackageRequestPayload creates a BindPackageRequest from command arguments.
9+
// This function is shared between bind and unbind package commands.
10+
// It expects the following arguments in order: <application_key> <package_type> <package_name> <package_version>.
11+
func BuildPackageRequestPayload(ctx *components.Context) (*model.BindPackageRequest, error) {
12+
applicationKey := ctx.Arguments[0]
13+
packageType := ctx.Arguments[1]
14+
packageName := ctx.Arguments[2]
15+
packageVersion := ctx.Arguments[3]
16+
17+
return &model.BindPackageRequest{
18+
ApplicationKey: applicationKey,
19+
Type: packageType,
20+
Name: packageName,
21+
Version: packageVersion,
22+
}, nil
23+
}

apptrust/http/http_client.go

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ type ApptrustHttpClient interface {
2626
Post(path string, requestBody interface{}) (resp *http.Response, body []byte, err error)
2727
Get(path string) (resp *http.Response, body []byte, err error)
2828
Patch(path string, requestBody interface{}) (resp *http.Response, body []byte, err error)
29-
Delete(path string) (resp *http.Response, body []byte, err error)
29+
Delete(path string, requestBody interface{}) (resp *http.Response, body []byte, err error)
3030
}
3131

3232
type apptrustHttpClient struct {
@@ -139,14 +139,22 @@ func (c *apptrustHttpClient) toJsonBytes(payload interface{}) ([]byte, error) {
139139
return jsonBytes, nil
140140
}
141141

142-
func (c *apptrustHttpClient) Delete(path string) (resp *http.Response, body []byte, err error) {
142+
func (c *apptrustHttpClient) Delete(path string, requestBody interface{}) (resp *http.Response, body []byte, err error) {
143143
url, err := utils.BuildUrl(c.serverDetails.Url, apptrustApiPath+path, nil)
144144
if err != nil {
145145
return nil, nil, err
146146
}
147147

148+
var requestContent []byte
149+
if requestBody != nil {
150+
requestContent, err = c.toJsonBytes(requestBody)
151+
if err != nil {
152+
return nil, nil, err
153+
}
154+
}
155+
148156
log.Debug("Sending DELETE request to:", url)
149-
return c.client.SendDelete(url, nil, c.getJsonHttpClientDetails())
157+
return c.client.SendDelete(url, requestContent, c.getJsonHttpClientDetails())
150158
}
151159

152160
func (c *apptrustHttpClient) getJsonHttpClientDetails() *httputils.HttpClientDetails {

apptrust/service/applications/application_service.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ func (as *applicationService) UpdateApplication(ctx service.Context, requestBody
5757

5858
func (as *applicationService) DeleteApplication(ctx service.Context, applicationKey string) error {
5959
endpoint := fmt.Sprintf("/v1/applications/%s", applicationKey)
60-
response, responseBody, err := ctx.GetHttpClient().Delete(endpoint)
60+
response, responseBody, err := ctx.GetHttpClient().Delete(endpoint, nil)
6161
if err != nil {
6262
return err
6363
}

apptrust/service/packages/package_service.go

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212

1313
type PackageService interface {
1414
BindPackage(ctx service.Context, request *model.BindPackageRequest) error
15+
UnbindPackage(ctx service.Context, request *model.BindPackageRequest) error
1516
}
1617

1718
type packageService struct{}
@@ -28,7 +29,22 @@ func (ps *packageService) BindPackage(ctx service.Context, request *model.BindPa
2829
}
2930

3031
if response.StatusCode != http.StatusCreated {
31-
return fmt.Errorf("failed to bind package. Status code: %d. \n%s",
32+
return fmt.Errorf("failed to bind package. Status code: %d.\n%s",
33+
response.StatusCode, responseBody)
34+
}
35+
36+
return nil
37+
}
38+
39+
func (ps *packageService) UnbindPackage(ctx service.Context, request *model.BindPackageRequest) error {
40+
endpoint := "/v1/package"
41+
response, responseBody, err := ctx.GetHttpClient().Delete(endpoint, request)
42+
if err != nil {
43+
return err
44+
}
45+
46+
if response.StatusCode != http.StatusNoContent {
47+
return fmt.Errorf("failed to unbind package. Status code: %d.\n%s",
3248
response.StatusCode, responseBody)
3349
}
3450

0 commit comments

Comments
 (0)