Skip to content

Commit 2abfafb

Browse files
committed
Expose stack state through V3 API endpoints only
**V2 API endpoints must not expose or accept state parameter.** Signed-off-by: Rashed Kamal <[email protected]>
1 parent a863736 commit 2abfafb

File tree

13 files changed

+344
-23
lines changed

13 files changed

+344
-23
lines changed

app/actions/stack_create.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ class Error < ::StandardError
66
def create(message)
77
stack = VCAP::CloudController::Stack.create(
88
name: message.name,
9-
description: message.description
9+
description: message.description,
10+
state: message.state
1011
)
1112

1213
MetadataUpdate.update(stack, message)

app/actions/stack_update.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ def initialize
99

1010
def update(stack, message)
1111
stack.db.transaction do
12+
stack.update(state: message.state) if message.requested?(:state)
1213
MetadataUpdate.update(stack, message)
1314
end
1415
@logger.info("Finished updating metadata on stack #{stack.guid}")
Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,18 @@
11
require 'messages/metadata_base_message'
2+
require 'models/helpers/stack_states'
23

34
module VCAP::CloudController
45
class StackCreateMessage < MetadataBaseMessage
5-
register_allowed_keys %i[name description]
6+
register_allowed_keys %i[name description state]
67

78
validates :name, presence: true, length: { maximum: 250 }
89
validates :description, length: { maximum: 250 }
10+
validates :state, inclusion: { in: StackStates::VALID_STATES, message: "must be one of #{StackStates::VALID_STATES.join(', ')}" }, allow_nil: true
11+
12+
def state
13+
return @state if defined?(@state)
14+
15+
@state = requested?(:state) ? super : StackStates::DEFAULT_STATE
16+
end
917
end
1018
end
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
require 'messages/metadata_base_message'
2+
require 'models/helpers/stack_states'
23

34
module VCAP::CloudController
45
class StackUpdateMessage < MetadataBaseMessage
5-
register_allowed_keys []
6+
register_allowed_keys [:state]
67

78
validates_with NoAdditionalKeysValidator
9+
validates :state, inclusion: { in: StackStates::VALID_STATES, message: "must be one of #{StackStates::VALID_STATES.join(', ')}" }, allow_nil: true
810
end
911
end

app/models/helpers/stack_states.rb

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
module VCAP::CloudController
2+
class StackStates
3+
STACK_ACTIVE = 'ACTIVE'.freeze
4+
STACK_RESTRICTED = 'RESTRICTED'.freeze
5+
STACK_DEPRECATED = 'DEPRECATED'.freeze
6+
STACK_DISABLED = 'DISABLED'.freeze
7+
8+
DEFAULT_STATE = STACK_ACTIVE
9+
10+
VALID_STATES = [
11+
STACK_ACTIVE,
12+
STACK_RESTRICTED,
13+
STACK_DEPRECATED,
14+
STACK_DISABLED
15+
].freeze
16+
end
17+
end

app/models/runtime/stack.rb

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
require 'models/helpers/process_types'
22
require 'models/helpers/stack_config_file'
3+
require 'models/helpers/stack_states'
34

45
module VCAP::CloudController
56
class Stack < Sequel::Model
@@ -10,18 +11,6 @@ class MissingDefaultStackError < StandardError
1011
class AppsStillPresentError < StandardError
1112
end
1213

13-
STACK_ACTIVE = 'ACTIVE'.freeze
14-
STACK_RESTRICTED = 'RESTRICTED'.freeze
15-
STACK_DEPRECATED = 'DEPRECATED'.freeze
16-
STACK_DISABLED = 'DISABLED'.freeze
17-
18-
VALID_STATES = [
19-
STACK_ACTIVE,
20-
STACK_RESTRICTED,
21-
STACK_DEPRECATED,
22-
STACK_DISABLED
23-
].freeze
24-
2514
# NOTE: that "apps" here returns processes for v2 meta-reasons
2615
many_to_many :apps,
2716
class: 'VCAP::CloudController::ProcessModel',
@@ -55,7 +44,7 @@ def around_save
5544
def validate
5645
validates_presence :name
5746
validates_unique :name
58-
validates_includes VALID_STATES, :state, allow_nil: true
47+
validates_includes StackStates::VALID_STATES, :state, allow_nil: true
5948
end
6049

6150
def before_destroy
@@ -111,20 +100,21 @@ def self.populate_from_hash(hash)
111100
create(hash.slice('name', 'description', 'build_rootfs_image', 'run_rootfs_image'))
112101
end
113102
end
103+
114104
def active?
115-
state == STACK_ACTIVE
105+
state == StackStates::STACK_ACTIVE
116106
end
117107

118108
def deprecated?
119-
state == STACK_DEPRECATED
109+
state == StackStates::STACK_DEPRECATED
120110
end
121111

122112
def restricted?
123-
state == STACK_RESTRICTED
113+
state == StackStates::STACK_RESTRICTED
124114
end
125115

126116
def disabled?
127-
state == STACK_DISABLED
117+
state == StackStates::STACK_DISABLED
128118
end
129119

130120
def can_stage_new_app?

app/presenters/v3/stack_presenter.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ def to_hash
1212
updated_at: stack.updated_at,
1313
name: stack.name,
1414
description: stack.description,
15+
state: stack.state,
1516
run_rootfs_image: stack.run_rootfs_image,
1617
build_rootfs_image: stack.build_rootfs_image,
1718
default: stack.default?,

spec/migrations/20251117123719_add_state_to_stacks_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
run_migration
4040
%w[ACTIVE DEPRECATED RESTRICTED DISABLED].each do |state|
4141
expect do
42-
db[:stacks].insert(guid:SecureRandom.uuid, name: "stack-#{state.downcase}", description: "A #{state} stack", state: state)
42+
db[:stacks].insert(guid: SecureRandom.uuid, name: "stack-#{state.downcase}", description: "A #{state} stack", state: state)
4343
end.not_to raise_error
4444
expect(db[:stacks].first(name: "stack-#{state.downcase}")[:state]).to eq(state)
4545
end

spec/request/stacks_spec.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
'run_rootfs_image' => stack1.run_rootfs_image,
2727
'build_rootfs_image' => stack1.build_rootfs_image,
2828
'guid' => stack1.guid,
29+
'state' => 'ACTIVE',
2930
'default' => false,
3031
'metadata' => { 'labels' => {}, 'annotations' => {} },
3132
'created_at' => iso8601,
@@ -42,6 +43,7 @@
4243
'run_rootfs_image' => stack2.run_rootfs_image,
4344
'build_rootfs_image' => stack2.build_rootfs_image,
4445
'guid' => stack2.guid,
46+
'state' => 'ACTIVE',
4547
'default' => true,
4648
'metadata' => { 'labels' => {}, 'annotations' => {} },
4749
'created_at' => iso8601,
@@ -122,6 +124,7 @@
122124
'run_rootfs_image' => stack1.run_rootfs_image,
123125
'build_rootfs_image' => stack1.build_rootfs_image,
124126
'guid' => stack1.guid,
127+
'state' => 'ACTIVE',
125128
'default' => false,
126129
'metadata' => { 'labels' => {}, 'annotations' => {} },
127130
'created_at' => iso8601,
@@ -138,6 +141,7 @@
138141
'run_rootfs_image' => stack2.run_rootfs_image,
139142
'build_rootfs_image' => stack2.build_rootfs_image,
140143
'guid' => stack2.guid,
144+
'state' => 'ACTIVE',
141145
'default' => true,
142146
'metadata' => { 'labels' => {}, 'annotations' => {} },
143147
'created_at' => iso8601,
@@ -177,6 +181,7 @@
177181
'run_rootfs_image' => stack1.run_rootfs_image,
178182
'build_rootfs_image' => stack1.build_rootfs_image,
179183
'guid' => stack1.guid,
184+
'state' => 'ACTIVE',
180185
'default' => false,
181186
'metadata' => { 'labels' => {}, 'annotations' => {} },
182187
'created_at' => iso8601,
@@ -193,6 +198,7 @@
193198
'run_rootfs_image' => stack3.run_rootfs_image,
194199
'build_rootfs_image' => stack3.build_rootfs_image,
195200
'guid' => stack3.guid,
201+
'state' => 'ACTIVE',
196202
'default' => false,
197203
'metadata' => { 'labels' => {}, 'annotations' => {} },
198204
'created_at' => iso8601,
@@ -232,6 +238,7 @@
232238
'run_rootfs_image' => stack2.run_rootfs_image,
233239
'build_rootfs_image' => stack2.build_rootfs_image,
234240
'guid' => stack2.guid,
241+
'state' => 'ACTIVE',
235242
'default' => true,
236243
'metadata' => { 'labels' => {}, 'annotations' => {} },
237244
'created_at' => iso8601,
@@ -287,6 +294,7 @@
287294
'run_rootfs_image' => stack1.run_rootfs_image,
288295
'build_rootfs_image' => stack1.build_rootfs_image,
289296
'guid' => stack1.guid,
297+
'state' => 'ACTIVE',
290298
'default' => false,
291299
'metadata' => {
292300
'labels' => {
@@ -323,6 +331,7 @@
323331
'run_rootfs_image' => stack.run_rootfs_image,
324332
'build_rootfs_image' => stack.build_rootfs_image,
325333
'guid' => stack.guid,
334+
'state' => 'ACTIVE',
326335
'default' => false,
327336
'metadata' => { 'labels' => {}, 'annotations' => {} },
328337
'created_at' => iso8601,
@@ -670,6 +679,7 @@
670679
}
671680
},
672681
'guid' => created_stack.guid,
682+
'state' => 'ACTIVE',
673683
'created_at' => iso8601,
674684
'updated_at' => iso8601,
675685
'links' => {
@@ -734,6 +744,7 @@
734744
}
735745
},
736746
'guid' => stack.guid,
747+
'state' => 'ACTIVE',
737748
'created_at' => iso8601,
738749
'updated_at' => iso8601,
739750
'links' => {

0 commit comments

Comments
 (0)