Skip to content

Commit db22918

Browse files
committed
Add --reason flag to update-stack command
1 parent e225fcb commit db22918

File tree

6 files changed

+114
-41
lines changed

6 files changed

+114
-41
lines changed

actor/v7action/stack.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@ func (actor Actor) GetStacks(labelSelector string) ([]resources.Stack, Warnings,
4747
return stacks, Warnings(warnings), nil
4848
}
4949

50-
func (actor Actor) UpdateStack(stackGUID string, state string) (resources.Stack, Warnings, error) {
51-
stack, warnings, err := actor.CloudControllerClient.UpdateStack(stackGUID, state)
50+
func (actor Actor) UpdateStack(stackGUID string, state string, reason string) (resources.Stack, Warnings, error) {
51+
stack, warnings, err := actor.CloudControllerClient.UpdateStack(stackGUID, state, reason)
5252
if err != nil {
5353
return resources.Stack{}, Warnings(warnings), err
5454
}

api/cloudcontroller/ccv3/stack.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,19 @@ func (client *Client) GetStacks(query ...Query) ([]resources.Stack, Warnings, er
2222
return stacks, warnings, err
2323
}
2424

25-
// UpdateStack updates a stack's state.
26-
func (client *Client) UpdateStack(stackGUID string, state string) (resources.Stack, Warnings, error) {
25+
// UpdateStack updates a stack's state and optionally its state reason.
26+
func (client *Client) UpdateStack(stackGUID string, state string, reason string) (resources.Stack, Warnings, error) {
2727
var responseStack resources.Stack
2828

2929
type StackUpdate struct {
30-
State string `json:"state"`
30+
State string `json:"state"`
31+
StateReason string `json:"state_reason,omitempty"`
3132
}
3233

3334
_, warnings, err := client.MakeRequest(RequestParams{
3435
RequestName: internal.PatchStackRequest,
3536
URIParams: internal.Params{"stack_guid": stackGUID},
36-
RequestBody: StackUpdate{State: state},
37+
RequestBody: StackUpdate{State: state, StateReason: reason},
3738
ResponseBody: &responseStack,
3839
})
3940

api/cloudcontroller/ccv3/stack_test.go

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ var _ = Describe("Stacks", func() {
148148
var (
149149
stackGUID string
150150
state string
151+
reason string
151152
stack resources.Stack
152153
warnings Warnings
153154
err error
@@ -156,10 +157,11 @@ var _ = Describe("Stacks", func() {
156157
BeforeEach(func() {
157158
stackGUID = "some-stack-guid"
158159
state = "DEPRECATED"
160+
reason = ""
159161
})
160162

161163
JustBeforeEach(func() {
162-
stack, warnings, err = client.UpdateStack(stackGUID, state)
164+
stack, warnings, err = client.UpdateStack(stackGUID, state, reason)
163165
})
164166

165167
When("the request succeeds", func() {
@@ -192,6 +194,40 @@ var _ = Describe("Stacks", func() {
192194
})
193195
})
194196

197+
When("a reason is provided", func() {
198+
BeforeEach(func() {
199+
reason = "Use cflinuxfs4 instead"
200+
server.AppendHandlers(
201+
CombineHandlers(
202+
VerifyRequest(http.MethodPatch, "/v3/stacks/some-stack-guid"),
203+
VerifyJSONRepresenting(map[string]string{
204+
"state": "DEPRECATED",
205+
"state_reason": "Use cflinuxfs4 instead",
206+
}),
207+
RespondWith(http.StatusOK, `{
208+
"guid": "some-stack-guid",
209+
"name": "some-stack",
210+
"description": "some description",
211+
"state": "DEPRECATED",
212+
"state_reason": "Use cflinuxfs4 instead"
213+
}`, http.Header{"X-Cf-Warnings": {"this is a warning"}}),
214+
),
215+
)
216+
})
217+
218+
It("returns the updated stack with reason and warnings", func() {
219+
Expect(err).ToNot(HaveOccurred())
220+
Expect(warnings).To(ConsistOf("this is a warning"))
221+
Expect(stack).To(Equal(resources.Stack{
222+
GUID: "some-stack-guid",
223+
Name: "some-stack",
224+
Description: "some description",
225+
State: "DEPRECATED",
226+
StateReason: "Use cflinuxfs4 instead",
227+
}))
228+
})
229+
})
230+
195231
When("the cloud controller returns an error", func() {
196232
BeforeEach(func() {
197233
server.AppendHandlers(

command/v7/update_stack_command.go

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ type UpdateStackCommand struct {
1515

1616
RequiredArgs flag.StackName `positional-args:"yes"`
1717
State string `long:"state" description:"State to transition the stack to (active, restricted, deprecated, disabled)" required:"true"`
18-
usage interface{} `usage:"CF_NAME update-stack STACK_NAME [--state (active | restricted | deprecated | disabled)]\n\nEXAMPLES:\n CF_NAME update-stack cflinuxfs3 --state disabled"`
18+
Reason string `long:"reason" description:"Optional plain text describing the stack state change"`
19+
usage interface{} `usage:"CF_NAME update-stack STACK_NAME [--state (active | restricted | deprecated | disabled)] [--reason REASON]\n\nEXAMPLES:\n CF_NAME update-stack cflinuxfs3 --state disabled\n CF_NAME update-stack cflinuxfs3 --state deprecated --reason 'Use cflinuxfs4 instead'"`
1920
relatedCommands interface{} `related_commands:"stack, stacks"`
2021
}
2122

@@ -56,7 +57,7 @@ func (cmd UpdateStackCommand) Execute(args []string) error {
5657
}
5758

5859
// Update the stack
59-
updatedStack, warnings, err := cmd.Actor.UpdateStack(stack.GUID, stateValue)
60+
updatedStack, warnings, err := cmd.Actor.UpdateStack(stack.GUID, stateValue, cmd.Reason)
6061
cmd.UI.DisplayWarnings(warnings)
6162
if err != nil {
6263
return err
@@ -66,11 +67,18 @@ func (cmd UpdateStackCommand) Execute(args []string) error {
6667
cmd.UI.DisplayNewline()
6768

6869
// Display the updated stack info
69-
cmd.UI.DisplayKeyValueTable("", [][]string{
70+
displayTable := [][]string{
7071
{cmd.UI.TranslateText("name:"), updatedStack.Name},
7172
{cmd.UI.TranslateText("description:"), updatedStack.Description},
7273
{cmd.UI.TranslateText("state:"), updatedStack.State},
73-
}, 3)
74+
}
75+
76+
// Add reason if it's present
77+
if updatedStack.StateReason != "" {
78+
displayTable = append(displayTable, []string{cmd.UI.TranslateText("reason:"), updatedStack.StateReason})
79+
}
80+
81+
cmd.UI.DisplayKeyValueTable("", displayTable, 3)
7482

7583
return nil
7684
}

command/v7/update_stack_command_test.go

Lines changed: 56 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -149,51 +149,78 @@ var _ = Describe("update-stack Command", func() {
149149
Expect(fakeActor.GetStackByNameArgsForCall(0)).To(Equal("some-stack"))
150150

151151
Expect(fakeActor.UpdateStackCallCount()).To(Equal(1))
152-
guid, state := fakeActor.UpdateStackArgsForCall(0)
152+
guid, state, reason := fakeActor.UpdateStackArgsForCall(0)
153153
Expect(guid).To(Equal("stack-guid"))
154154
Expect(state).To(Equal(resources.StackStateDeprecated))
155+
Expect(reason).To(Equal(""))
155156
})
156157
})
157158
})
158159
})
159160

160-
Context("when state values are provided in different cases", func() {
161-
It("accepts 'active' and capitalizes it", func() {
162-
cmd.State = "active"
163-
fakeActor.GetStackByNameReturns(resources.Stack{GUID: "guid"}, v7action.Warnings{}, nil)
164-
fakeActor.UpdateStackReturns(resources.Stack{Name: "some-stack", State: resources.StackStateActive}, v7action.Warnings{}, nil)
161+
Context("when state values are provided in different cases", func() {
162+
It("accepts 'active' and capitalizes it", func() {
163+
cmd.State = "active"
164+
fakeActor.GetStackByNameReturns(resources.Stack{GUID: "guid"}, v7action.Warnings{}, nil)
165+
fakeActor.UpdateStackReturns(resources.Stack{Name: "some-stack", State: resources.StackStateActive}, v7action.Warnings{}, nil)
165166

166-
executeErr = cmd.Execute(args)
167+
executeErr = cmd.Execute(args)
167168

168-
Expect(executeErr).ToNot(HaveOccurred())
169-
_, state := fakeActor.UpdateStackArgsForCall(0)
170-
Expect(state).To(Equal(resources.StackStateActive))
171-
})
169+
Expect(executeErr).ToNot(HaveOccurred())
170+
_, state, _ := fakeActor.UpdateStackArgsForCall(0)
171+
Expect(state).To(Equal(resources.StackStateActive))
172+
})
172173

173-
It("accepts 'RESTRICTED' and keeps it capitalized", func() {
174-
cmd.State = "RESTRICTED"
175-
fakeActor.GetStackByNameReturns(resources.Stack{GUID: "guid"}, v7action.Warnings{}, nil)
176-
fakeActor.UpdateStackReturns(resources.Stack{Name: "some-stack", State: resources.StackStateRestricted}, v7action.Warnings{}, nil)
174+
It("accepts 'RESTRICTED' and keeps it capitalized", func() {
175+
cmd.State = "RESTRICTED"
176+
fakeActor.GetStackByNameReturns(resources.Stack{GUID: "guid"}, v7action.Warnings{}, nil)
177+
fakeActor.UpdateStackReturns(resources.Stack{Name: "some-stack", State: resources.StackStateRestricted}, v7action.Warnings{}, nil)
177178

178-
executeErr = cmd.Execute(args)
179+
executeErr = cmd.Execute(args)
179180

180-
Expect(executeErr).ToNot(HaveOccurred())
181-
_, state := fakeActor.UpdateStackArgsForCall(0)
182-
Expect(state).To(Equal(resources.StackStateRestricted))
183-
})
181+
Expect(executeErr).ToNot(HaveOccurred())
182+
_, state, _ := fakeActor.UpdateStackArgsForCall(0)
183+
Expect(state).To(Equal(resources.StackStateRestricted))
184+
})
184185

185-
It("accepts 'Disabled' and capitalizes it", func() {
186-
cmd.State = "Disabled"
187-
fakeActor.GetStackByNameReturns(resources.Stack{GUID: "guid"}, v7action.Warnings{}, nil)
188-
fakeActor.UpdateStackReturns(resources.Stack{Name: "some-stack", State: resources.StackStateDisabled}, v7action.Warnings{}, nil)
186+
It("accepts 'Disabled' and capitalizes it", func() {
187+
cmd.State = "Disabled"
188+
fakeActor.GetStackByNameReturns(resources.Stack{GUID: "guid"}, v7action.Warnings{}, nil)
189+
fakeActor.UpdateStackReturns(resources.Stack{Name: "some-stack", State: resources.StackStateDisabled}, v7action.Warnings{}, nil)
189190

190-
executeErr = cmd.Execute(args)
191+
executeErr = cmd.Execute(args)
191192

192-
Expect(executeErr).ToNot(HaveOccurred())
193-
_, state := fakeActor.UpdateStackArgsForCall(0)
194-
Expect(state).To(Equal(resources.StackStateDisabled))
195-
})
193+
Expect(executeErr).ToNot(HaveOccurred())
194+
_, state, _ := fakeActor.UpdateStackArgsForCall(0)
195+
Expect(state).To(Equal(resources.StackStateDisabled))
196196
})
197197
})
198+
199+
Context("when the reason flag is provided", func() {
200+
BeforeEach(func() {
201+
cmd.State = "deprecated"
202+
cmd.Reason = "Use cflinuxfs4 instead"
203+
fakeActor.GetStackByNameReturns(resources.Stack{GUID: "guid"}, v7action.Warnings{}, nil)
204+
fakeActor.UpdateStackReturns(resources.Stack{
205+
Name: "some-stack",
206+
Description: "some description",
207+
State: resources.StackStateDeprecated,
208+
StateReason: "Use cflinuxfs4 instead",
209+
}, v7action.Warnings{}, nil)
210+
})
211+
212+
It("passes the reason to the actor and displays it", func() {
213+
executeErr = cmd.Execute(args)
214+
215+
Expect(executeErr).ToNot(HaveOccurred())
216+
217+
Expect(fakeActor.UpdateStackCallCount()).To(Equal(1))
218+
_, _, reason := fakeActor.UpdateStackArgsForCall(0)
219+
Expect(reason).To(Equal("Use cflinuxfs4 instead"))
220+
221+
Expect(testUI.Out).To(Say(`reason:\s+Use cflinuxfs4 instead`))
222+
})
223+
})
224+
})
198225
})
199226

integration/v7/isolated/update_stack_command_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,10 @@ var _ = Describe("update-stack command", func() {
4444
Eventually(session).Should(Say(`NAME:`))
4545
Eventually(session).Should(Say(`update-stack - Transition a stack between the defined states`))
4646
Eventually(session).Should(Say(`USAGE:`))
47-
Eventually(session).Should(Say(`cf update-stack STACK_NAME \[--state \(active \| restricted \| deprecated \| disabled\)\]`))
47+
Eventually(session).Should(Say(`cf update-stack STACK_NAME \[--state \(active \| restricted \| deprecated \| disabled\)\] \[--reason REASON\]`))
4848
Eventually(session).Should(Say(`EXAMPLES:`))
4949
Eventually(session).Should(Say(`cf update-stack cflinuxfs3 --state disabled`))
50+
Eventually(session).Should(Say(`cf update-stack cflinuxfs3 --state deprecated --reason 'Use cflinuxfs4 instead'`))
5051
Eventually(session).Should(Say(`OPTIONS:`))
5152
Eventually(session).Should(Say(`--state\s+State to transition the stack to`))
5253
Eventually(session).Should(Say(`SEE ALSO:`))

0 commit comments

Comments
 (0)