Skip to content

Commit 61197b9

Browse files
gururajshLisa Burns
andauthored
cf revision command implementation [main] (#3341)
* Revision command implementation. Co-authored-by: Lisa Burns <[email protected]> Signed-off-by: Steve Taylor <[email protected]>
1 parent e8b087f commit 61197b9

21 files changed

+834
-40
lines changed

.github/workflows/golangci-lint.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ on:
2020
- "doc/**"
2121
- ".gitpod.yml"
2222
- "README.md"
23+
workflow_dispatch:
2324

2425
jobs:
2526
golangci:

actor/v7action/cloud_controller_client.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ type CloudControllerClient interface {
8484
GetDroplet(guid string) (resources.Droplet, ccv3.Warnings, error)
8585
GetDroplets(query ...ccv3.Query) ([]resources.Droplet, ccv3.Warnings, error)
8686
GetEnvironmentVariableGroup(group constant.EnvironmentVariableGroupName) (resources.EnvironmentVariables, ccv3.Warnings, error)
87+
GetEnvironmentVariablesByURL(url string) (resources.EnvironmentVariables, ccv3.Warnings, error)
8788
GetEvents(query ...ccv3.Query) ([]ccv3.Event, ccv3.Warnings, error)
8889
GetFeatureFlag(featureFlagName string) (resources.FeatureFlag, ccv3.Warnings, error)
8990
GetFeatureFlags() ([]resources.FeatureFlag, ccv3.Warnings, error)

actor/v7action/revisions.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,20 @@ func (actor Actor) GetRevisionByApplicationAndVersion(appGUID string, revisionVe
7676
return revisions[0], Warnings(warnings), nil
7777
}
7878

79+
func (actor Actor) GetEnvironmentVariableGroupByRevision(revision resources.Revision) (EnvironmentVariableGroup, bool, Warnings, error) {
80+
envVarApiLink, isPresent := revision.Links["environment_variables"]
81+
if !isPresent {
82+
return EnvironmentVariableGroup{}, isPresent, Warnings{"Unable to retrieve environment variables for revision."}, nil
83+
}
84+
85+
environmentVariables, warnings, err := actor.CloudControllerClient.GetEnvironmentVariablesByURL(envVarApiLink.HREF)
86+
if err != nil {
87+
return EnvironmentVariableGroup{}, false, Warnings(warnings), err
88+
}
89+
90+
return EnvironmentVariableGroup(environmentVariables), true, Warnings(warnings), nil
91+
}
92+
7993
func (actor Actor) setRevisionsDeployableByDropletStateForApp(appGUID string, revisions []resources.Revision) ([]resources.Revision, Warnings, error) {
8094
droplets, warnings, err := actor.CloudControllerClient.GetDroplets(
8195
ccv3.Query{Key: ccv3.AppGUIDFilter, Values: []string{appGUID}},

actor/v7action/revisions_test.go

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,13 @@ import (
55
"strconv"
66

77
"code.cloudfoundry.org/cli/actor/actionerror"
8+
"code.cloudfoundry.org/cli/actor/v7action"
89
. "code.cloudfoundry.org/cli/actor/v7action"
910
"code.cloudfoundry.org/cli/actor/v7action/v7actionfakes"
1011
"code.cloudfoundry.org/cli/api/cloudcontroller/ccv3"
1112
"code.cloudfoundry.org/cli/api/cloudcontroller/ccv3/constant"
1213
"code.cloudfoundry.org/cli/resources"
14+
"code.cloudfoundry.org/cli/types"
1315
. "github.com/onsi/ginkgo/v2"
1416
. "github.com/onsi/gomega"
1517
)
@@ -397,4 +399,81 @@ var _ = Describe("Revisions Actions", func() {
397399
})
398400
})
399401
})
402+
403+
Describe("GetEnvironmentVariableGroupByRevision", func() {
404+
var (
405+
actor *Actor
406+
environmentVariablesGroup v7action.EnvironmentVariableGroup
407+
executeErr error
408+
fakeCloudControllerClient *v7actionfakes.FakeCloudControllerClient
409+
fakeConfig *v7actionfakes.FakeConfig
410+
isPresent bool
411+
revision resources.Revision
412+
warnings Warnings
413+
)
414+
415+
BeforeEach(func() {
416+
fakeCloudControllerClient = new(v7actionfakes.FakeCloudControllerClient)
417+
fakeConfig = new(v7actionfakes.FakeConfig)
418+
actor = NewActor(fakeCloudControllerClient, fakeConfig, nil, nil, nil, nil)
419+
revision = resources.Revision{
420+
Links: resources.APILinks{
421+
"environment_variables": resources.APILink{
422+
HREF: "url",
423+
},
424+
},
425+
}
426+
fakeConfig.APIVersionReturns("3.86.0")
427+
})
428+
429+
JustBeforeEach(func() {
430+
environmentVariablesGroup, isPresent, warnings, executeErr = actor.GetEnvironmentVariableGroupByRevision(revision)
431+
})
432+
433+
When("the revision does not provide HREF", func() {
434+
BeforeEach(func() {
435+
revision = resources.Revision{}
436+
})
437+
438+
It("returns as not present", func() {
439+
Expect(executeErr).To(Not(HaveOccurred()))
440+
Expect(warnings).To(ConsistOf("Unable to retrieve environment variables for revision."))
441+
Expect(isPresent).To(Equal(false))
442+
})
443+
})
444+
445+
When("finding the environment variables fails", func() {
446+
BeforeEach(func() {
447+
fakeCloudControllerClient.GetEnvironmentVariablesByURLReturns(
448+
nil,
449+
ccv3.Warnings{"get-env-vars-warning-1"},
450+
errors.New("get-env-vars-error-1"),
451+
)
452+
})
453+
454+
It("returns an error and warnings", func() {
455+
Expect(executeErr).To(MatchError("get-env-vars-error-1"))
456+
Expect(warnings).To(ConsistOf("get-env-vars-warning-1"))
457+
})
458+
})
459+
460+
When("finding the environment variables succeeds", func() {
461+
BeforeEach(func() {
462+
fakeCloudControllerClient.GetEnvironmentVariablesByURLReturns(
463+
resources.EnvironmentVariables{"foo": *types.NewFilteredString("bar")},
464+
ccv3.Warnings{"get-env-vars-warning-1"},
465+
nil,
466+
)
467+
})
468+
469+
It("returns the environment variables and warnings", func() {
470+
Expect(executeErr).ToNot(HaveOccurred())
471+
Expect(fakeCloudControllerClient.GetEnvironmentVariablesByURLCallCount()).To(Equal(1))
472+
Expect(fakeCloudControllerClient.GetEnvironmentVariablesByURLArgsForCall(0)).To(Equal("url"))
473+
Expect(warnings).To(ConsistOf("get-env-vars-warning-1"))
474+
Expect(len(environmentVariablesGroup)).To(Equal(1))
475+
Expect(environmentVariablesGroup["foo"].Value).To(Equal("bar"))
476+
})
477+
})
478+
})
400479
})

actor/v7action/v7actionfakes/fake_cloud_controller_client.go

Lines changed: 84 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api/cloudcontroller/ccv3/revisions.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,14 @@ func (client *Client) GetApplicationRevisionsDeployed(appGUID string) ([]resourc
3535
})
3636
return revisions, warnings, err
3737
}
38+
39+
func (client *Client) GetEnvironmentVariablesByURL(url string) (resources.EnvironmentVariables, Warnings, error) {
40+
environmentVariables := make(resources.EnvironmentVariables)
41+
42+
_, warnings, err := client.MakeRequest(RequestParams{
43+
URL: url,
44+
ResponseBody: &environmentVariables,
45+
})
46+
47+
return environmentVariables, warnings, err
48+
}

api/cloudcontroller/ccv3/revisions_test.go

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"code.cloudfoundry.org/cli/api/cloudcontroller/ccv3/ccv3fakes"
99
"code.cloudfoundry.org/cli/api/cloudcontroller/ccv3/internal"
1010
"code.cloudfoundry.org/cli/resources"
11+
"code.cloudfoundry.org/cli/types"
1112
. "github.com/onsi/ginkgo/v2"
1213
. "github.com/onsi/gomega"
1314
)
@@ -133,4 +134,79 @@ var _ = Describe("Revisions", func() {
133134
})
134135
})
135136
})
137+
138+
Describe("GetEnvironmentVariablesByURL", func() {
139+
var (
140+
warnings Warnings
141+
executeErr error
142+
environmentVariables resources.EnvironmentVariables
143+
)
144+
145+
JustBeforeEach(func() {
146+
environmentVariables, warnings, executeErr = client.GetEnvironmentVariablesByURL("url")
147+
})
148+
149+
When("the cloud controller returns errors and warnings", func() {
150+
BeforeEach(func() {
151+
errors := []ccerror.V3Error{
152+
{
153+
Code: 10008,
154+
Detail: "The request is semantically invalid: command presence",
155+
Title: "CF-UnprocessableEntity",
156+
},
157+
{
158+
Code: 10010,
159+
Detail: "App not found",
160+
Title: "CF-ResourceNotFound",
161+
},
162+
}
163+
164+
requester.MakeRequestReturns(
165+
"url",
166+
Warnings{"this is a warning"},
167+
ccerror.MultiError{ResponseCode: http.StatusTeapot, Errors: errors},
168+
)
169+
})
170+
171+
It("returns the error and all warnings", func() {
172+
Expect(executeErr).To(MatchError(ccerror.MultiError{
173+
ResponseCode: http.StatusTeapot,
174+
Errors: []ccerror.V3Error{
175+
{
176+
Code: 10008,
177+
Detail: "The request is semantically invalid: command presence",
178+
Title: "CF-UnprocessableEntity",
179+
},
180+
{
181+
Code: 10010,
182+
Detail: "App not found",
183+
Title: "CF-ResourceNotFound",
184+
},
185+
},
186+
}))
187+
Expect(warnings).To(ConsistOf("this is a warning"))
188+
})
189+
})
190+
191+
When("revision exist", func() {
192+
BeforeEach(func() {
193+
requester.MakeRequestCalls(func(requestParams RequestParams) (JobURL, Warnings, error) {
194+
(*requestParams.ResponseBody.(*resources.EnvironmentVariables))["foo"] = *types.NewFilteredString("bar")
195+
return "url", Warnings{"this is a warning"}, nil
196+
})
197+
})
198+
199+
It("returns the environment variables and all warnings", func() {
200+
Expect(requester.MakeRequestCallCount()).To(Equal(1))
201+
actualParams := requester.MakeRequestArgsForCall(0)
202+
Expect(actualParams.URL).To(Equal("url"))
203+
204+
Expect(executeErr).NotTo(HaveOccurred())
205+
Expect(warnings).To(ConsistOf("this is a warning"))
206+
207+
Expect(len(environmentVariables)).To(Equal(1))
208+
Expect(environmentVariables["foo"].Value).To(Equal("bar"))
209+
})
210+
})
211+
})
136212
})

command/common/help_command.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,6 @@ func (cmd HelpCommand) displayHelpFooter(cmdInfo map[string]sharedaction.Command
136136
cmd.UI.DisplayNonWrappingTable(sharedaction.AllCommandsIndent, cmd.globalOptionsTableData(), 25)
137137

138138
cmd.UI.DisplayNewline()
139-
140-
cmd.displayCommandGroups(internal.ExperimentalHelpCategoryList, cmdInfo, 34)
141139
}
142140

143141
func (cmd HelpCommand) displayCommonCommands() {

command/common/internal/help_all_display.go

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ var HelpCategoryList = []HelpCategory{
1717
{"start", "stop", "restart", "stage-package", "restage", "restart-app-instance"},
1818
{"run-task", "task", "tasks", "terminate-task"},
1919
{"packages", "create-package"},
20-
{"revisions", "rollback"},
20+
{"revision", "revisions", "rollback"},
2121
{"droplets", "set-droplet", "download-droplet"},
2222
{"events", "logs"},
2323
{"env", "set-env", "unset-env"},
@@ -168,12 +168,3 @@ var HelpCategoryList = []HelpCategory{
168168
},
169169
},
170170
}
171-
172-
var ExperimentalHelpCategoryList = []HelpCategory{
173-
{
174-
CategoryName: "EXPERIMENTAL COMMANDS:",
175-
CommandList: [][]string{
176-
{"revision"},
177-
},
178-
},
179-
}

command/common/internal/help_all_display_test.go

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,16 +34,6 @@ var _ = Describe("test help all display", func() {
3434
}
3535
}
3636
}
37-
38-
for _, category := range internal.ExperimentalHelpCategoryList {
39-
for _, row := range category.CommandList {
40-
for _, command := range row {
41-
if command != "" {
42-
fromHelpAllDisplay = append(fromHelpAllDisplay, command)
43-
}
44-
}
45-
}
46-
}
4737
})
4838

4939
It("lists all commands from command list in at least one category", func() {

0 commit comments

Comments
 (0)