Skip to content

Commit b40e7d3

Browse files
committed
Allow removing all user owners, group owners and labels of an application using the application-update command
1 parent 9765b4f commit b40e7d3

File tree

9 files changed

+171
-129
lines changed

9 files changed

+171
-129
lines changed
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package application
2+
3+
import (
4+
"github.com/jfrog/jfrog-cli-application/apptrust/commands"
5+
"github.com/jfrog/jfrog-cli-application/apptrust/commands/utils"
6+
"github.com/jfrog/jfrog-cli-application/apptrust/model"
7+
"github.com/jfrog/jfrog-cli-core/v2/plugins/components"
8+
)
9+
10+
func populateApplicationFromFlags(ctx *components.Context, descriptor *model.AppDescriptor) error {
11+
descriptor.ApplicationName = ctx.GetStringFlagValue(commands.ApplicationNameFlag)
12+
13+
if ctx.IsFlagSet(commands.DescriptionFlag) {
14+
description := ctx.GetStringFlagValue(commands.DescriptionFlag)
15+
descriptor.Description = &description
16+
}
17+
18+
if ctx.IsFlagSet(commands.BusinessCriticalityFlag) {
19+
businessCriticalityStr := ctx.GetStringFlagValue(commands.BusinessCriticalityFlag)
20+
businessCriticality, err := utils.ValidateEnumFlag(
21+
commands.BusinessCriticalityFlag,
22+
businessCriticalityStr,
23+
model.BusinessCriticalityUnspecified,
24+
model.BusinessCriticalityValues)
25+
if err != nil {
26+
return err
27+
}
28+
descriptor.BusinessCriticality = &businessCriticality
29+
}
30+
31+
if ctx.IsFlagSet(commands.MaturityLevelFlag) {
32+
maturityLevelStr := ctx.GetStringFlagValue(commands.MaturityLevelFlag)
33+
maturityLevel, err := utils.ValidateEnumFlag(
34+
commands.MaturityLevelFlag,
35+
maturityLevelStr,
36+
model.MaturityLevelUnspecified,
37+
model.MaturityLevelValues)
38+
if err != nil {
39+
return err
40+
}
41+
descriptor.MaturityLevel = &maturityLevel
42+
}
43+
44+
if ctx.IsFlagSet(commands.LabelsFlag) {
45+
labelsMap, err := utils.ParseMapFlag(ctx.GetStringFlagValue(commands.LabelsFlag))
46+
if err != nil {
47+
return err
48+
}
49+
descriptor.Labels = &labelsMap
50+
}
51+
52+
if ctx.IsFlagSet(commands.UserOwnersFlag) {
53+
userOwners := utils.ParseSliceFlag(ctx.GetStringFlagValue(commands.UserOwnersFlag))
54+
descriptor.UserOwners = &userOwners
55+
}
56+
57+
if ctx.IsFlagSet(commands.GroupOwnersFlag) {
58+
groupOwners := utils.ParseSliceFlag(ctx.GetStringFlagValue(commands.GroupOwnersFlag))
59+
descriptor.GroupOwners = &groupOwners
60+
}
61+
62+
return nil
63+
}

apptrust/commands/application/create_app_cmd.go

Lines changed: 4 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -69,51 +69,21 @@ func (cac *createAppCommand) buildRequestPayload(ctx *components.Context) (*mode
6969
}
7070

7171
func (cac *createAppCommand) buildFromFlags(ctx *components.Context) (*model.AppDescriptor, error) {
72-
applicationName := ctx.GetStringFlagValue(commands.ApplicationNameFlag)
73-
7472
project := ctx.GetStringFlagValue(commands.ProjectFlag)
7573
if project == "" {
7674
return nil, errorutils.CheckErrorf("--%s is mandatory", commands.ProjectFlag)
7775
}
7876

79-
businessCriticalityStr := ctx.GetStringFlagValue(commands.BusinessCriticalityFlag)
80-
businessCriticality, err := utils.ValidateEnumFlag(
81-
commands.BusinessCriticalityFlag,
82-
businessCriticalityStr,
83-
model.BusinessCriticalityUnspecified,
84-
model.BusinessCriticalityValues)
85-
if err != nil {
86-
return nil, err
87-
}
88-
89-
maturityLevelStr := ctx.GetStringFlagValue(commands.MaturityLevelFlag)
90-
maturityLevel, err := utils.ValidateEnumFlag(
91-
commands.MaturityLevelFlag,
92-
maturityLevelStr,
93-
model.MaturityLevelUnspecified,
94-
model.MaturityLevelValues)
95-
if err != nil {
96-
return nil, err
77+
descriptor := &model.AppDescriptor{
78+
ProjectKey: project,
9779
}
9880

99-
description := ctx.GetStringFlagValue(commands.DescriptionFlag)
100-
userOwners := utils.ParseSliceFlag(ctx.GetStringFlagValue(commands.UserOwnersFlag))
101-
groupOwners := utils.ParseSliceFlag(ctx.GetStringFlagValue(commands.GroupOwnersFlag))
102-
labelsMap, err := utils.ParseMapFlag(ctx.GetStringFlagValue(commands.LabelsFlag))
81+
err := populateApplicationFromFlags(ctx, descriptor)
10382
if err != nil {
10483
return nil, err
10584
}
10685

107-
return &model.AppDescriptor{
108-
ApplicationName: applicationName,
109-
Description: description,
110-
ProjectKey: project,
111-
MaturityLevel: maturityLevel,
112-
BusinessCriticality: businessCriticality,
113-
Labels: labelsMap,
114-
UserOwners: userOwners,
115-
GroupOwners: groupOwners,
116-
}, nil
86+
return descriptor, nil
11787
}
11888

11989
func (cac *createAppCommand) loadFromSpec(ctx *components.Context) (*model.AppDescriptor, error) {

apptrust/commands/application/create_app_cmd_test.go

Lines changed: 66 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,18 @@ func TestCreateAppCommand_Run_Flags(t *testing.T) {
1919
ctrl := gomock.NewController(t)
2020
defer ctrl.Finish()
2121

22+
description := "Test application"
23+
businessCriticality := "high"
24+
maturityLevel := "production"
25+
2226
ctx := &components.Context{
2327
Arguments: []string{"app-key"},
2428
}
2529
ctx.AddStringFlag("application-name", "test-app")
2630
ctx.AddStringFlag("project", "test-project")
27-
ctx.AddStringFlag("desc", "Test application")
31+
ctx.AddStringFlag("desc", description)
2832
ctx.AddStringFlag("business-criticality", "high")
29-
ctx.AddStringFlag("maturity-level", "production")
33+
ctx.AddStringFlag("maturity-level", maturityLevel)
3034
ctx.AddStringFlag("labels", "env=prod;region=us-east")
3135
ctx.AddStringFlag("user-owners", "john.doe;jane.smith")
3236
ctx.AddStringFlag("group-owners", "devops;security")
@@ -36,15 +40,15 @@ func TestCreateAppCommand_Run_Flags(t *testing.T) {
3640
ApplicationKey: "app-key",
3741
ApplicationName: "test-app",
3842
ProjectKey: "test-project",
39-
Description: "Test application",
40-
BusinessCriticality: "high",
41-
MaturityLevel: "production",
42-
Labels: map[string]string{
43+
Description: &description,
44+
BusinessCriticality: &businessCriticality,
45+
MaturityLevel: &maturityLevel,
46+
Labels: &map[string]string{
4347
"env": "prod",
4448
"region": "us-east",
4549
},
46-
UserOwners: []string{"john.doe", "jane.smith"},
47-
GroupOwners: []string{"devops", "security"},
50+
UserOwners: &[]string{"john.doe", "jane.smith"},
51+
GroupOwners: &[]string{"devops", "security"},
4852
}
4953

5054
mockAppService := mockapps.NewMockApplicationService(ctrl)
@@ -125,6 +129,52 @@ func TestCreateAppCommand_MissingProjectFlag(t *testing.T) {
125129
assert.Contains(t, err.Error(), "--project is mandatory")
126130
}
127131

132+
func TestCreateAppCommand_Run_FullSpecFile(t *testing.T) {
133+
ctrl := gomock.NewController(t)
134+
defer ctrl.Finish()
135+
136+
ctx := &components.Context{
137+
Arguments: []string{"app-full"},
138+
}
139+
ctx.AddStringFlag("url", "https://example.com")
140+
ctx.AddStringFlag("spec", "./testfiles/full-spec.json")
141+
142+
expectedDescription := "A comprehensive test application"
143+
expectedMaturityLevel := "production"
144+
expectedBusinessCriticality := "high"
145+
expectedPayload := &model.AppDescriptor{
146+
ApplicationKey: "app-full",
147+
ApplicationName: "test-app-full",
148+
ProjectKey: "test-project",
149+
Description: &expectedDescription,
150+
MaturityLevel: &expectedMaturityLevel,
151+
BusinessCriticality: &expectedBusinessCriticality,
152+
Labels: &map[string]string{
153+
"environment": "production",
154+
"region": "us-east-1",
155+
"team": "devops",
156+
},
157+
UserOwners: &[]string{"john.doe", "jane.smith"},
158+
GroupOwners: &[]string{"devops-team", "security-team"},
159+
}
160+
161+
var actualPayload *model.AppDescriptor
162+
mockAppService := mockapps.NewMockApplicationService(ctrl)
163+
mockAppService.EXPECT().CreateApplication(gomock.Any(), gomock.Any()).
164+
DoAndReturn(func(_ interface{}, req *model.AppDescriptor) error {
165+
actualPayload = req
166+
return nil
167+
}).Times(1)
168+
169+
cmd := &createAppCommand{
170+
applicationService: mockAppService,
171+
}
172+
173+
err := cmd.prepareAndRunCommand(ctx)
174+
assert.NoError(t, err)
175+
assert.Equal(t, expectedPayload, actualPayload)
176+
}
177+
128178
func TestCreateAppCommand_Run_SpecFile(t *testing.T) {
129179
tests := []struct {
130180
name string
@@ -144,26 +194,6 @@ func TestCreateAppCommand_Run_SpecFile(t *testing.T) {
144194
ProjectKey: "test-project",
145195
},
146196
},
147-
{
148-
name: "full spec file",
149-
specPath: "./testfiles/full-spec.json",
150-
args: []string{"app-full"},
151-
expectsPayload: &model.AppDescriptor{
152-
ApplicationKey: "app-full",
153-
ApplicationName: "test-app-full",
154-
ProjectKey: "test-project",
155-
Description: "A comprehensive test application",
156-
MaturityLevel: "production",
157-
BusinessCriticality: "high",
158-
Labels: map[string]string{
159-
"environment": "production",
160-
"region": "us-east-1",
161-
"team": "devops",
162-
},
163-
UserOwners: []string{"john.doe", "jane.smith"},
164-
GroupOwners: []string{"devops-team", "security-team"},
165-
},
166-
},
167197
{
168198
name: "invalid spec file",
169199
specPath: "./testfiles/invalid-spec.json",
@@ -193,7 +223,6 @@ func TestCreateAppCommand_Run_SpecFile(t *testing.T) {
193223
ApplicationKey: "command-line-app-key",
194224
ApplicationName: "test-app",
195225
ProjectKey: "test-project",
196-
Description: "A test application with application_key that should be ignored",
197226
},
198227
},
199228
}
@@ -241,14 +270,18 @@ func TestCreateAppCommand_Run_SpecVars(t *testing.T) {
241270
ctrl := gomock.NewController(t)
242271
defer ctrl.Finish()
243272

273+
expectedDescription := "A test application for production"
274+
expectedMaturityLevel := "production"
275+
expectedBusinessCriticality := "high"
276+
244277
expectedPayload := &model.AppDescriptor{
245278
ApplicationKey: "app-with-vars",
246279
ApplicationName: "test-app",
247280
ProjectKey: "test-project",
248-
Description: "A test application for production",
249-
MaturityLevel: "production",
250-
BusinessCriticality: "high",
251-
Labels: map[string]string{
281+
Description: &expectedDescription,
282+
MaturityLevel: &expectedMaturityLevel,
283+
BusinessCriticality: &expectedBusinessCriticality,
284+
Labels: &map[string]string{
252285
"environment": "production",
253286
"region": "us-east-1",
254287
},
Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
{
22
"application_key": "ignored-app-key",
33
"project_key": "test-project",
4-
"application_name": "test-app",
5-
"description": "A test application with application_key that should be ignored"
6-
}
4+
"application_name": "test-app"
5+
}

apptrust/commands/application/update_app_cmd.go

Lines changed: 4 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -40,46 +40,17 @@ func (uac *updateAppCommand) CommandName() string {
4040

4141
func (uac *updateAppCommand) buildRequestPayload(ctx *components.Context) (*model.AppDescriptor, error) {
4242
applicationKey := ctx.Arguments[0]
43-
applicationName := ctx.GetStringFlagValue(commands.ApplicationNameFlag)
44-
45-
businessCriticalityStr := ctx.GetStringFlagValue(commands.BusinessCriticalityFlag)
46-
businessCriticality, err := utils.ValidateEnumFlag(
47-
commands.BusinessCriticalityFlag,
48-
businessCriticalityStr,
49-
"",
50-
model.BusinessCriticalityValues)
51-
if err != nil {
52-
return nil, err
53-
}
5443

55-
maturityLevelStr := ctx.GetStringFlagValue(commands.MaturityLevelFlag)
56-
maturityLevel, err := utils.ValidateEnumFlag(
57-
commands.MaturityLevelFlag,
58-
maturityLevelStr,
59-
model.MaturityLevelUnspecified,
60-
model.MaturityLevelValues)
61-
if err != nil {
62-
return nil, err
44+
descriptor := &model.AppDescriptor{
45+
ApplicationKey: applicationKey,
6346
}
6447

65-
description := ctx.GetStringFlagValue(commands.DescriptionFlag)
66-
userOwners := utils.ParseSliceFlag(ctx.GetStringFlagValue(commands.UserOwnersFlag))
67-
groupOwners := utils.ParseSliceFlag(ctx.GetStringFlagValue(commands.GroupOwnersFlag))
68-
labelsMap, err := utils.ParseMapFlag(ctx.GetStringFlagValue(commands.LabelsFlag))
48+
err := populateApplicationFromFlags(ctx, descriptor)
6949
if err != nil {
7050
return nil, err
7151
}
7252

73-
return &model.AppDescriptor{
74-
ApplicationKey: applicationKey,
75-
ApplicationName: applicationName,
76-
Description: description,
77-
MaturityLevel: maturityLevel,
78-
BusinessCriticality: businessCriticality,
79-
Labels: labelsMap,
80-
UserOwners: userOwners,
81-
GroupOwners: groupOwners,
82-
}, nil
53+
return descriptor, nil
8354
}
8455

8556
func (uac *updateAppCommand) prepareAndRunCommand(ctx *components.Context) error {

apptrust/commands/application/update_app_cmd_test.go

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,21 @@ func TestUpdateAppCommand_Run(t *testing.T) {
2121

2222
serverDetails := &config.ServerDetails{Url: "https://example.com"}
2323
appKey := "app-key"
24+
description := "Updated description"
25+
maturityLevel := "production"
26+
businessCriticality := "high"
2427
requestPayload := &model.AppDescriptor{
2528
ApplicationKey: appKey,
2629
ApplicationName: "app-name",
27-
Description: "Updated description",
28-
MaturityLevel: "production",
29-
BusinessCriticality: "high",
30-
Labels: map[string]string{
30+
Description: &description,
31+
MaturityLevel: &maturityLevel,
32+
BusinessCriticality: &businessCriticality,
33+
Labels: &map[string]string{
3134
"environment": "production",
3235
"region": "us-east",
3336
},
34-
UserOwners: []string{"JohnD", "Dave Rice"},
35-
GroupOwners: []string{"DevOps"},
37+
UserOwners: &[]string{"JohnD", "Dave Rice"},
38+
GroupOwners: &[]string{"DevOps"},
3639
}
3740

3841
mockAppService := mockapps.NewMockApplicationService(ctrl)
@@ -54,18 +57,21 @@ func TestUpdateAppCommand_Run_Error(t *testing.T) {
5457

5558
serverDetails := &config.ServerDetails{Url: "https://example.com"}
5659
appKey := "app-key"
60+
description := "Updated description"
61+
maturityLevel := "production"
62+
businessCriticality := "high"
5763
requestPayload := &model.AppDescriptor{
5864
ApplicationKey: appKey,
5965
ApplicationName: "app-name",
60-
Description: "Updated description",
61-
MaturityLevel: "production",
62-
BusinessCriticality: "high",
63-
Labels: map[string]string{
66+
Description: &description,
67+
MaturityLevel: &maturityLevel,
68+
BusinessCriticality: &businessCriticality,
69+
Labels: &map[string]string{
6470
"environment": "production",
6571
"region": "us-east",
6672
},
67-
UserOwners: []string{"JohnD", "Dave Rice"},
68-
GroupOwners: []string{"DevOps"},
73+
UserOwners: &[]string{"JohnD", "Dave Rice"},
74+
GroupOwners: &[]string{"DevOps"},
6975
}
7076

7177
mockAppService := mockapps.NewMockApplicationService(ctrl)

0 commit comments

Comments
 (0)