automate_soup 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +15 -0
- data/.rspec +2 -0
- data/.travis.yml +5 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +21 -0
- data/README.md +128 -0
- data/Rakefile +10 -0
- data/automate_soup.gemspec +31 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/docs/AutomateSoup.html +2566 -0
- data/docs/AutomateSoup/API.html +1174 -0
- data/docs/AutomateSoup/Change.html +892 -0
- data/docs/AutomateSoup/Credentials.html +452 -0
- data/docs/AutomateSoup/Rest.html +321 -0
- data/docs/AutomateSoup/Stage.html +428 -0
- data/docs/AutomateSoup/Topic.html +530 -0
- data/docs/_index.html +166 -0
- data/docs/class_list.html +51 -0
- data/docs/coverage/.last_run.json +5 -0
- data/docs/coverage/.resultset.json +145 -0
- data/docs/coverage/.resultset.json.lock +0 -0
- data/docs/coverage/assets/0.10.2/application.css +799 -0
- data/docs/coverage/assets/0.10.2/application.js +1707 -0
- data/docs/coverage/assets/0.10.2/colorbox/border.png +0 -0
- data/docs/coverage/assets/0.10.2/colorbox/controls.png +0 -0
- data/docs/coverage/assets/0.10.2/colorbox/loading.gif +0 -0
- data/docs/coverage/assets/0.10.2/colorbox/loading_background.png +0 -0
- data/docs/coverage/assets/0.10.2/favicon_green.png +0 -0
- data/docs/coverage/assets/0.10.2/favicon_red.png +0 -0
- data/docs/coverage/assets/0.10.2/favicon_yellow.png +0 -0
- data/docs/coverage/assets/0.10.2/loading.gif +0 -0
- data/docs/coverage/assets/0.10.2/magnify.png +0 -0
- data/docs/coverage/assets/0.10.2/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
- data/docs/coverage/assets/0.10.2/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
- data/docs/coverage/assets/0.10.2/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
- data/docs/coverage/assets/0.10.2/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/docs/coverage/assets/0.10.2/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
- data/docs/coverage/assets/0.10.2/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
- data/docs/coverage/assets/0.10.2/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
- data/docs/coverage/assets/0.10.2/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
- data/docs/coverage/assets/0.10.2/smoothness/images/ui-icons_222222_256x240.png +0 -0
- data/docs/coverage/assets/0.10.2/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
- data/docs/coverage/assets/0.10.2/smoothness/images/ui-icons_454545_256x240.png +0 -0
- data/docs/coverage/assets/0.10.2/smoothness/images/ui-icons_888888_256x240.png +0 -0
- data/docs/coverage/assets/0.10.2/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
- data/docs/coverage/index.html +968 -0
- data/docs/css/common.css +1 -0
- data/docs/css/full_list.css +58 -0
- data/docs/css/style.css +492 -0
- data/docs/file.README.html +211 -0
- data/docs/file_list.html +56 -0
- data/docs/frames.html +17 -0
- data/docs/index.html +211 -0
- data/docs/js/app.js +248 -0
- data/docs/js/full_list.js +216 -0
- data/docs/js/jquery.js +4 -0
- data/docs/method_list.html +395 -0
- data/docs/top-level-namespace.html +110 -0
- data/lib/automate_soup.rb +264 -0
- data/lib/automate_soup/api.rb +112 -0
- data/lib/automate_soup/change.rb +105 -0
- data/lib/automate_soup/credentials.rb +16 -0
- data/lib/automate_soup/rest.rb +40 -0
- data/lib/automate_soup/stage.rb +25 -0
- data/lib/automate_soup/version.rb +3 -0
- metadata +195 -0
@@ -0,0 +1,264 @@
|
|
1
|
+
require 'automate_soup/api'
|
2
|
+
require 'automate_soup/credentials'
|
3
|
+
require 'automate_soup/rest'
|
4
|
+
require 'automate_soup/stage'
|
5
|
+
require 'automate_soup/change'
|
6
|
+
require 'automate_soup/version'
|
7
|
+
require 'ostruct'
|
8
|
+
|
9
|
+
##
|
10
|
+
# Top level module
|
11
|
+
#
|
12
|
+
module AutomateSoup
|
13
|
+
class << self
|
14
|
+
attr_accessor :url, :credentials, :api, :enterprise, :organization, :project, :pipeline
|
15
|
+
|
16
|
+
##
|
17
|
+
# Setup Automate Soup client.
|
18
|
+
#
|
19
|
+
# @option url [String] The Chef Automate URL.
|
20
|
+
# @option username [String] The Chef Automate username.
|
21
|
+
# @option token [String] The Chef Automate user token.
|
22
|
+
# @option password [String] The Chef Automate user password.
|
23
|
+
#
|
24
|
+
def setup(
|
25
|
+
url: nil,
|
26
|
+
username: nil,
|
27
|
+
token: nil,
|
28
|
+
password: nil,
|
29
|
+
enterprise: 'default',
|
30
|
+
organization: nil,
|
31
|
+
project: nil,
|
32
|
+
pipeline: nil
|
33
|
+
)
|
34
|
+
@url = url
|
35
|
+
@credentials = if token
|
36
|
+
token_credentials(username, token)
|
37
|
+
else
|
38
|
+
password_credentials(username, password)
|
39
|
+
end
|
40
|
+
@api = AutomateSoup::API.new(self)
|
41
|
+
@enterprise = enterprise
|
42
|
+
@organization = organization
|
43
|
+
@project = project
|
44
|
+
@pipeline = pipeline
|
45
|
+
self
|
46
|
+
end
|
47
|
+
|
48
|
+
##
|
49
|
+
# Check the status of Automate
|
50
|
+
#
|
51
|
+
def status
|
52
|
+
o = @api.status
|
53
|
+
OpenStruct.new o
|
54
|
+
end
|
55
|
+
|
56
|
+
##
|
57
|
+
# Fetch all organizations under an enterprise
|
58
|
+
#
|
59
|
+
def orgs(enterprise = 'default')
|
60
|
+
@api.orgs enterprise
|
61
|
+
end
|
62
|
+
|
63
|
+
##
|
64
|
+
# Fetch all projects under an enterprise, organization pair
|
65
|
+
#
|
66
|
+
def projects(enterprise: 'default', organization: nil)
|
67
|
+
@api.projects(enterprise: enterprise, organization: organization)
|
68
|
+
end
|
69
|
+
|
70
|
+
##
|
71
|
+
# Fetch all pipelines of a project under an enterprise, organization pair
|
72
|
+
#
|
73
|
+
def pipelines(enterprise: 'default', organization: nil, project: nil)
|
74
|
+
@api.pipelines(enterprise: enterprise, organization: organization, project: project)
|
75
|
+
end
|
76
|
+
|
77
|
+
##
|
78
|
+
# Fetch a pipeline of a project under an enterprise, organization pair.
|
79
|
+
#
|
80
|
+
def pipeline(enterprise: 'default', organization: nil, project: nil, pipeline: nil)
|
81
|
+
arr = []
|
82
|
+
@api.pipeline(enterprise: enterprise, organization: organization, project: project, pipeline: pipeline).each do |o|
|
83
|
+
arr << OpenStruct.new(o)
|
84
|
+
end
|
85
|
+
arr
|
86
|
+
end
|
87
|
+
|
88
|
+
##
|
89
|
+
# Filters out the topics from the pipelines changes .
|
90
|
+
#
|
91
|
+
# @option enterprise [String] the enterprise to fetch org from, defaults to
|
92
|
+
# default.
|
93
|
+
# @option organization [String] the organization to fetch from.
|
94
|
+
# @option project [String] the project to fetch from.
|
95
|
+
# @option pipeline [String] the pipeline to fetch from.
|
96
|
+
#
|
97
|
+
def pipeline_topics(enterprise: 'default', organization: nil, project: nil, pipeline: nil)
|
98
|
+
self.pipeline(
|
99
|
+
enterprise: enterprise,
|
100
|
+
organization: organization,
|
101
|
+
project: project,
|
102
|
+
pipeline: pipeline
|
103
|
+
).map { |p| p.topic }
|
104
|
+
end
|
105
|
+
|
106
|
+
##
|
107
|
+
# Find a change by topic.
|
108
|
+
#
|
109
|
+
# @option enterprise [String] the enterprise to fetch org from, defaults to
|
110
|
+
# default.
|
111
|
+
# @option organization [String] the organization to fetch from.
|
112
|
+
# @option project [String] the project to fetch from.
|
113
|
+
# @option pipeline [String] the pipeline to fetch from.
|
114
|
+
# @option topic [String] the topic to fetch a change from.
|
115
|
+
#
|
116
|
+
def change_by_topic(enterprise: @enterprise, organization: @organization, project: @project, pipeline: @pipeline, topic: nil)
|
117
|
+
o = self.pipeline(
|
118
|
+
enterprise: enterprise,
|
119
|
+
organization: organization,
|
120
|
+
project: project,
|
121
|
+
pipeline: pipeline
|
122
|
+
).select { |p| p.topic.eql?(topic) }.first
|
123
|
+
AutomateSoup::Change.new o
|
124
|
+
end
|
125
|
+
|
126
|
+
##
|
127
|
+
# Approve a change by change topic.
|
128
|
+
#
|
129
|
+
# @option enterprise [String] the enterprise to fetch org from, defaults to
|
130
|
+
# default.
|
131
|
+
# @option organization [String] the organization to fetch from.
|
132
|
+
# @option project [String] the project to fetch from.
|
133
|
+
# @option pipeline [String] the pipeline to fetch from.
|
134
|
+
# @option topic [String] the change topic to approve
|
135
|
+
# @option wait [Boolean] to wait for the approval stages to complete.
|
136
|
+
# @option timeout [Integer] the time in seconds to wait between requests defaults
|
137
|
+
# to 10
|
138
|
+
# @option retries [Integer] the amount of retries to make, defaults to 5
|
139
|
+
#
|
140
|
+
def approve_change(enterprise: @enterprise, organization: @organization, project: @project, pipeline: @pipeline, topic: nil, wait: false, timeout: 10, retries: 5)
|
141
|
+
o = self.change_by_topic(
|
142
|
+
enterprise: enterprise,
|
143
|
+
organization: organization,
|
144
|
+
project: project,
|
145
|
+
pipeline: pipeline,
|
146
|
+
topic: topic
|
147
|
+
)
|
148
|
+
if wait && !o.approvable? && !o.deliverable?
|
149
|
+
times = 1
|
150
|
+
while times <= retries
|
151
|
+
o = self.change_by_topic(
|
152
|
+
enterprise: enterprise,
|
153
|
+
organization: organization,
|
154
|
+
project: project,
|
155
|
+
pipeline: pipeline,
|
156
|
+
topic: topic
|
157
|
+
)
|
158
|
+
break if o.approvable?
|
159
|
+
return false if o.current_stage.failed?
|
160
|
+
puts "Stage #{o.current_stage.stage}: #{o.current_stage.status} retries #{times}/#{retries}"
|
161
|
+
sleep timeout
|
162
|
+
times += 1
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
o.approve
|
167
|
+
return true if !wait && o.deliverable?
|
168
|
+
times = 1
|
169
|
+
while times <= retries
|
170
|
+
o = self.change_by_topic(
|
171
|
+
enterprise: enterprise,
|
172
|
+
organization: organization,
|
173
|
+
project: project,
|
174
|
+
pipeline: pipeline,
|
175
|
+
topic: topic
|
176
|
+
)
|
177
|
+
break if o.deliverable?
|
178
|
+
return false if o.current_stage.failed?
|
179
|
+
puts "Stage #{o.current_stage.stage}: #{o.current_stage.status} retries #{times}/#{retries}"
|
180
|
+
times += 1
|
181
|
+
sleep timeout
|
182
|
+
end
|
183
|
+
true
|
184
|
+
end
|
185
|
+
|
186
|
+
|
187
|
+
##
|
188
|
+
# Delivery a change by a topic
|
189
|
+
#
|
190
|
+
# @option enterprise [String] the enterprise to fetch org from, defaults to
|
191
|
+
# default.
|
192
|
+
# @option organization [String] the organization to fetch from.
|
193
|
+
# @option project [String] the project to fetch from.
|
194
|
+
# @option pipeline [String] the pipeline to fetch from.
|
195
|
+
# @option topic [String] the change topic to approve
|
196
|
+
# @option wait [Boolean] to wait for the approval stages to complete.
|
197
|
+
# @option timeout [Integer] the time in seconds to wait between requests defaults
|
198
|
+
# to 10
|
199
|
+
# @option retries [Integer] the amount of retries to make, defaults to 5
|
200
|
+
#
|
201
|
+
def deliver_change(enterprise: @enterprise, organization: @organization, project: @project, pipeline: @pipeline, topic: nil, wait: false, timeout: 10, retries: 5)
|
202
|
+
o = self.change_by_topic(
|
203
|
+
enterprise: enterprise,
|
204
|
+
organization: organization,
|
205
|
+
project: project,
|
206
|
+
pipeline: pipeline,
|
207
|
+
topic: topic
|
208
|
+
)
|
209
|
+
return false if !o.deliverable?
|
210
|
+
if wait && !o.deliverable?
|
211
|
+
times = 1
|
212
|
+
while times <= retries
|
213
|
+
o = self.change_by_topic(
|
214
|
+
enterprise: enterprise,
|
215
|
+
organization: organization,
|
216
|
+
project: project,
|
217
|
+
pipeline: pipeline,
|
218
|
+
topic: topic
|
219
|
+
)
|
220
|
+
break if o.deliverable?
|
221
|
+
return false if o.current_stage.failed?
|
222
|
+
puts "Stage #{o.current_stage.stage}: #{o.current_stage.status} retries #{times}/#{retries}"
|
223
|
+
sleep timeout
|
224
|
+
times += 1
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
o.deliver
|
229
|
+
return true if !wait && o.delivered?
|
230
|
+
times = 1
|
231
|
+
while times <= retries
|
232
|
+
o = self.change_by_topic(
|
233
|
+
enterprise: enterprise,
|
234
|
+
organization: organization,
|
235
|
+
project: project,
|
236
|
+
pipeline: pipeline,
|
237
|
+
topic: topic
|
238
|
+
)
|
239
|
+
break if o.delivered?
|
240
|
+
return false if o.current_stage.failed?
|
241
|
+
puts "Stage #{o.current_stage.stage}: #{o.current_stage.status} retries #{times}/#{retries}"
|
242
|
+
times += 1
|
243
|
+
sleep timeout
|
244
|
+
end
|
245
|
+
true
|
246
|
+
end
|
247
|
+
|
248
|
+
private
|
249
|
+
|
250
|
+
def password_credentials(username, password)
|
251
|
+
AutomateSoup::Credentials.new(
|
252
|
+
username: username,
|
253
|
+
password: password
|
254
|
+
)
|
255
|
+
end
|
256
|
+
|
257
|
+
def token_credentials(username, token)
|
258
|
+
AutomateSoup::Credentials.new(
|
259
|
+
username: username,
|
260
|
+
token: token
|
261
|
+
)
|
262
|
+
end
|
263
|
+
end
|
264
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
module AutomateSoup
|
2
|
+
##
|
3
|
+
# API class to interact with chef automate
|
4
|
+
class API
|
5
|
+
def initialize(soup)
|
6
|
+
@soup = soup
|
7
|
+
end
|
8
|
+
|
9
|
+
##
|
10
|
+
# Get the status of the Automate API
|
11
|
+
#
|
12
|
+
def status
|
13
|
+
AutomateSoup::Rest.get(
|
14
|
+
url: "#{@soup.url}/api/_status",
|
15
|
+
username: @soup.credentials.username,
|
16
|
+
token: @soup.credentials.token
|
17
|
+
)
|
18
|
+
end
|
19
|
+
|
20
|
+
##
|
21
|
+
# Get the organizations given the enterprise.
|
22
|
+
#
|
23
|
+
# @param enterprise [String] the enterprise to fetch orgs from, defaults to
|
24
|
+
# default.
|
25
|
+
#
|
26
|
+
def orgs(enterprise = 'default')
|
27
|
+
@hash = AutomateSoup::Rest.get(
|
28
|
+
url: "#{@soup.url}/api/v0/e/#{enterprise}/orgs",
|
29
|
+
username: @soup.credentials.username,
|
30
|
+
token: @soup.credentials.token
|
31
|
+
)
|
32
|
+
raise "Failed to fetch orgs under enterprise #{enterprise}" unless @hash['orgs']
|
33
|
+
@hash['orgs']
|
34
|
+
end
|
35
|
+
|
36
|
+
##
|
37
|
+
# Get the projects under and organization given the enterprise.
|
38
|
+
#
|
39
|
+
# @option enterprise [String] the enterprise to fetch org from, defaults to
|
40
|
+
# default.
|
41
|
+
# @option organization [String] the organization to fetch projects from.
|
42
|
+
#
|
43
|
+
def projects(enterprise: 'default', organization: nil)
|
44
|
+
@hash = AutomateSoup::Rest.get(
|
45
|
+
url: "#{@soup.url}/api/v0/e/#{enterprise}/orgs/#{organization}/projects",
|
46
|
+
username: @soup.credentials.username,
|
47
|
+
token: @soup.credentials.token
|
48
|
+
)
|
49
|
+
|
50
|
+
rescue JSON::ParserError
|
51
|
+
raise "Failed to fetch projects under organization #{organization} enterprise #{enterprise}"
|
52
|
+
end
|
53
|
+
|
54
|
+
##
|
55
|
+
# Fetch a project under an enterprise, organization pair
|
56
|
+
#
|
57
|
+
# @option enterprise [String] the enterprise to fetch org from, defaults to
|
58
|
+
# default.
|
59
|
+
# @option organization [String] the organization to fetch projects from.
|
60
|
+
# @option project [String] the organization to fetch projects from.
|
61
|
+
#
|
62
|
+
def project(enterprise: 'default', organization: nil, project: nil)
|
63
|
+
@hash = AutomateSoup::Rest.get(
|
64
|
+
url: "#{@soup.url}/api/v0/e/#{enterprise}/orgs/#{organization}/projects/#{project}/pipelines",
|
65
|
+
username: @soup.credentials.username,
|
66
|
+
token: @soup.credentials.token
|
67
|
+
)
|
68
|
+
|
69
|
+
rescue JSON::ParserError
|
70
|
+
raise "Failed to fetch projects under organization #{organization} enterprise #{enterprise}"
|
71
|
+
end
|
72
|
+
|
73
|
+
##
|
74
|
+
# Fetch all project pipelines under an enterprise, organization pair
|
75
|
+
#
|
76
|
+
# @option enterprise [String] the enterprise to fetch org from, defaults to
|
77
|
+
# default.
|
78
|
+
# @option organization [String] the organization to fetch pipelines from.
|
79
|
+
# @option project [String] the project to fetch pipelines from.
|
80
|
+
#
|
81
|
+
def pipelines(enterprise: 'default', organization: nil, project: nil)
|
82
|
+
@hash = AutomateSoup::Rest.get(
|
83
|
+
url: "#{@soup.url}/api/v0/e/#{enterprise}/orgs/#{organization}/projects/#{project}/pipelines",
|
84
|
+
username: @soup.credentials.username,
|
85
|
+
token: @soup.credentials.token
|
86
|
+
)
|
87
|
+
@hash['pipelines']
|
88
|
+
|
89
|
+
rescue JSON::ParserError
|
90
|
+
raise "Failed to fetch pipelines under organization #{organization} enterprise #{enterprise}"
|
91
|
+
end
|
92
|
+
|
93
|
+
##
|
94
|
+
# Fetch a projects pipeline under an enterprise, organization pair
|
95
|
+
#
|
96
|
+
# @option enterprise [String] the enterprise to fetch org from, defaults to
|
97
|
+
# default.
|
98
|
+
# @option organization [String] the organization to fetch from.
|
99
|
+
# @option project [String] the project to fetch from.
|
100
|
+
# @option pipeline [String] the pipeline to fetch from.
|
101
|
+
#
|
102
|
+
def pipeline(enterprise: 'default', organization: nil, project: nil, pipeline: nil)
|
103
|
+
@hash = AutomateSoup::Rest.get(
|
104
|
+
url: "#{@soup.url}/api/v0/e/#{enterprise}/orgs/#{organization}/projects/#{project}/changes?pipeline=#{pipeline}&limit=25",
|
105
|
+
username: @soup.credentials.username,
|
106
|
+
token: @soup.credentials.token
|
107
|
+
)
|
108
|
+
rescue JSON::ParserError
|
109
|
+
raise "Failed to fetch pipelines under organization #{organization} enterprise #{enterprise}"
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
|
3
|
+
module AutomateSoup
|
4
|
+
##
|
5
|
+
# Class to represent operations on a change.
|
6
|
+
#
|
7
|
+
class Change
|
8
|
+
def initialize(hash)
|
9
|
+
@source = OpenStruct.new hash
|
10
|
+
end
|
11
|
+
|
12
|
+
##
|
13
|
+
# Delegate method missing to the underlying OpenStruct
|
14
|
+
#
|
15
|
+
def method_missing(method, *args, &block)
|
16
|
+
@source.send(method, *args, &block)
|
17
|
+
end
|
18
|
+
|
19
|
+
##
|
20
|
+
# Determing the current stage of the change.
|
21
|
+
# @return [AutomateSoup::Stage] the current stage.
|
22
|
+
def current_stage
|
23
|
+
Stage.new @source.stages.last
|
24
|
+
end
|
25
|
+
|
26
|
+
##
|
27
|
+
# Wrapper for the _links property on the struct
|
28
|
+
#
|
29
|
+
def links
|
30
|
+
@source._links
|
31
|
+
end
|
32
|
+
|
33
|
+
##
|
34
|
+
# Determine if the change has been delivered successfully.
|
35
|
+
#
|
36
|
+
# @return [Boolean] if this change is delivered
|
37
|
+
def delivered?
|
38
|
+
(current_stage.stage.eql?('delivered') &&
|
39
|
+
current_stage.status.eql?('passed') &&
|
40
|
+
!AutomateSoup.url.nil? &&
|
41
|
+
!AutomateSoup.credentials.nil?)
|
42
|
+
end
|
43
|
+
|
44
|
+
##
|
45
|
+
# Determine if the change is deliverable.
|
46
|
+
#
|
47
|
+
# @return [Boolean] if this change is deliverable
|
48
|
+
def deliverable?
|
49
|
+
(current_stage.stage.eql?('acceptance') &&
|
50
|
+
current_stage.status.eql?('passed') &&
|
51
|
+
!AutomateSoup.url.nil? &&
|
52
|
+
!AutomateSoup.credentials.nil? &&
|
53
|
+
!links.nil? &&
|
54
|
+
!links['deliver'].nil? &&
|
55
|
+
!links['deliver']['href'].nil?)
|
56
|
+
end
|
57
|
+
|
58
|
+
##
|
59
|
+
# Determine if the change is approvable.
|
60
|
+
#
|
61
|
+
# @return [Boolean] if this change is approvable
|
62
|
+
def approvable?
|
63
|
+
(current_stage.stage.eql?('verify') &&
|
64
|
+
current_stage.status.eql?('passed') &&
|
65
|
+
!AutomateSoup.url.nil? &&
|
66
|
+
!AutomateSoup.credentials.nil? &&
|
67
|
+
!links.nil? &&
|
68
|
+
!links['approve'].nil? &&
|
69
|
+
!links['approve']['href'].nil?)
|
70
|
+
end
|
71
|
+
|
72
|
+
##
|
73
|
+
# Approve this change.
|
74
|
+
def approve
|
75
|
+
return nil if current_stage.stage != 'verify'
|
76
|
+
raise 'Must run AutomateSoup.setup first' if AutomateSoup.url.nil? || AutomateSoup.credentials.nil?
|
77
|
+
raise 'Approve link not available' if links.nil? || links['approve'].nil? || links['approve']['href'].nil?
|
78
|
+
url = "#{AutomateSoup.url}#{links['approve']['href']}"
|
79
|
+
res = AutomateSoup::Rest.post(
|
80
|
+
url: url,
|
81
|
+
username: AutomateSoup.credentials.username,
|
82
|
+
token: AutomateSoup.credentials.token
|
83
|
+
)
|
84
|
+
raise "Failed to approve change: #{res.code}" if res.code != '204'
|
85
|
+
true
|
86
|
+
end
|
87
|
+
|
88
|
+
##
|
89
|
+
# Deliver this change.
|
90
|
+
def deliver
|
91
|
+
raise 'Must approve change first' if current_stage.stage.eql? 'verify'
|
92
|
+
return nil if current_stage.stage != 'acceptance'
|
93
|
+
raise 'Must run AutomateSoup.setup first' if AutomateSoup.url.nil? || AutomateSoup.credentials.nil?
|
94
|
+
raise 'Deliver link not available' if links.nil? || links['deliver'].nil? || links['deliver']['href'].nil?
|
95
|
+
url = "#{AutomateSoup.url}#{links['deliver']['href']}"
|
96
|
+
res = AutomateSoup::Rest.post(
|
97
|
+
url: url,
|
98
|
+
username: AutomateSoup.credentials.username,
|
99
|
+
token: AutomateSoup.credentials.token
|
100
|
+
)
|
101
|
+
raise "Failed to deliver change: #{res.code}" if res.code != '204'
|
102
|
+
true
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|