octopus-serverspec-extensions 0.18.1 → 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +14 -14
  3. data/.rspec +2 -2
  4. data/.travis.yml +5 -5
  5. data/Gemfile +4 -4
  6. data/LICENSE.txt +12 -12
  7. data/README.md +39 -39
  8. data/Rakefile +6 -6
  9. data/bin/console +14 -14
  10. data/bin/setup +8 -8
  11. data/docs/authentication.md +45 -45
  12. data/docs/octopus_deploy_account.md +37 -37
  13. data/docs/octopus_deploy_doc_template.md +16 -16
  14. data/docs/octopus_deploy_environment.md +32 -32
  15. data/docs/octopus_deploy_project_group.md +30 -30
  16. data/docs/octopus_deploy_smtp_config.md +39 -39
  17. data/docs/octopus_deploy_space.md +32 -32
  18. data/docs/octopus_deploy_team.md +25 -25
  19. data/docs/octopus_deploy_tentacle.md +40 -40
  20. data/docs/octopus_deploy_upgrade_config.md +33 -33
  21. data/docs/octopus_deploy_user.md +33 -33
  22. data/docs/octopus_deploy_worker.md +38 -38
  23. data/docs/octopus_deploy_worker_pool.md +25 -25
  24. data/lib/octopus_serverspec_extensions.rb +85 -85
  25. data/lib/octopus_serverspec_extensions/matcher/allow_dynamic_infrastructure.rb +12 -12
  26. data/lib/octopus_serverspec_extensions/matcher/have_linux_line_endings.rb +13 -13
  27. data/lib/octopus_serverspec_extensions/matcher/have_version.rb +36 -36
  28. data/lib/octopus_serverspec_extensions/matcher/have_windows_line_endings.rb +13 -13
  29. data/lib/octopus_serverspec_extensions/matcher/run_under_account.rb +17 -17
  30. data/lib/octopus_serverspec_extensions/matcher/use_guided_failure.rb +12 -12
  31. data/lib/octopus_serverspec_extensions/type/chocolatey_package.rb +33 -33
  32. data/lib/octopus_serverspec_extensions/type/java_property_file.rb +28 -28
  33. data/lib/octopus_serverspec_extensions/type/npm_package.rb +36 -36
  34. data/lib/octopus_serverspec_extensions/type/octopus_deploy_account.rb +176 -176
  35. data/lib/octopus_serverspec_extensions/type/octopus_deploy_environment.rb +117 -117
  36. data/lib/octopus_serverspec_extensions/type/octopus_deploy_project_group.rb +127 -127
  37. data/lib/octopus_serverspec_extensions/type/octopus_deploy_smtp_config.rb +109 -109
  38. data/lib/octopus_serverspec_extensions/type/octopus_deploy_space.rb +92 -92
  39. data/lib/octopus_serverspec_extensions/type/octopus_deploy_team.rb +81 -81
  40. data/lib/octopus_serverspec_extensions/type/octopus_deploy_tentacle.rb +208 -208
  41. data/lib/octopus_serverspec_extensions/type/octopus_deploy_upgrade_config.rb +112 -112
  42. data/lib/octopus_serverspec_extensions/type/octopus_deploy_user.rb +110 -110
  43. data/lib/octopus_serverspec_extensions/type/octopus_deploy_worker.rb +173 -173
  44. data/lib/octopus_serverspec_extensions/type/octopus_deploy_worker_pool.rb +88 -88
  45. data/lib/octopus_serverspec_extensions/type/windows_dsc.rb +37 -37
  46. data/lib/octopus_serverspec_extensions/type/windows_firewall.rb +32 -32
  47. data/lib/octopus_serverspec_extensions/type/windows_scheduled_task.rb +33 -33
  48. data/lib/octopus_serverspec_extensions/version.rb +3 -3
  49. data/octopus-serverspec-extensions.gemspec +34 -34
  50. metadata +15 -16
@@ -1,111 +1,111 @@
1
- require 'serverspec/type/base'
2
- require 'net/http'
3
- require 'json'
4
-
5
- module Serverspec::Type
6
- class OctopusDeployUser < Base
7
- @serverUrl = nil
8
- @apiKey = nil
9
- @userAccount = nil
10
-
11
- def initialize(*url_and_api_key, userName)
12
- serverUrl, apiKey = get_octopus_creds(url_and_api_key)
13
-
14
- @name = "Octopus Deploy User Account #{userName}"
15
- @runner = Specinfra::Runner
16
- @serverUrl = serverUrl
17
- @apiKey = apiKey
18
-
19
- # is our auth info still nil?
20
- if (serverUrl.nil?)
21
- raise "'serverUrl' was not provided. Unable to connect to Octopus server to validate configuration."
22
- end
23
- if (apiKey.nil?)
24
- raise "'apiKey' was not provided. Unable to connect to Octopus server to validate configuration."
25
- end
26
-
27
- if(userName.nil?)
28
- raise "'userName' was not provided"
29
- end
30
-
31
- @userAccount = get_user_via_api(serverUrl, apiKey, userName)
32
- end
33
-
34
- def service_account?
35
- return false if @userAccount.nil?
36
- @userAccount['IsService'] == true
37
- end
38
-
39
- def exists?
40
- (!@userAccount.nil?) && (@userAccount != [])
41
- end
42
-
43
- def active?
44
- return false if @userAccount.nil?
45
- @userAccount['IsActive'] == true
46
- end
47
-
48
- def has_email?(email)
49
- return false if @userAccount.nil?
50
- @userAccount['EmailAddress'] == email
51
- end
52
-
53
- def has_display_name?(name)
54
- return false if @userAccount.nil?
55
- @userAccount['DisplayName'] == name
56
- end
57
-
58
- def has_api_key?(purpose)
59
- return false if @userAccount.nil?
60
-
61
- user_api_key = nil
62
- user_id = @userAccount['Id']
63
- url = "#{@serverUrl}/api/users/#{user_id}/apikeys?api-key=#{@apiKey}&take=9999"
64
-
65
- begin
66
- resp = Net::HTTP.get_response(URI.parse(url))
67
- body = JSON.parse(resp.body)
68
- keys = body unless body.nil?
69
- user_api_key = keys['Items'].select {|i| i['Purpose'] == purpose }.first unless keys.nil?
70
-
71
- rescue => e
72
- raise "has_api_key: Unable to connect to #{url}: #{e}"
73
- end
74
-
75
- !user_api_key.nil?
76
- end
77
- end
78
-
79
- # module-level constructors/entrypoints
80
-
81
- def octopus_deploy_user(*url_and_api_key, user_name)
82
- serverUrl, apiKey = get_octopus_creds(url_and_api_key)
83
- OctopusDeployUser.new(serverUrl, apiKey, user_name)
84
- end
85
-
86
- def octopus_user(*url_and_api_key, user_name)
87
- serverUrl, apiKey = get_octopus_creds(url_and_api_key)
88
- octopus_deploy_user(serverUrl, apiKey, user_name)
89
- end
90
-
91
- private
92
-
93
- def get_user_via_api(serverUrl, apiKey, user_name)
94
- user = nil
95
-
96
- url = "#{serverUrl}/api/users/all?api-key=#{apiKey}"
97
-
98
- begin
99
- resp = Net::HTTP.get_response(URI.parse(url))
100
- body = JSON.parse(resp.body)
101
- users = body unless body.nil?
102
- user = users.select {|i| i['Username'] == user_name }.first unless users.nil?
103
- rescue => e
104
- raise "get_user_via_api: Unable to connect to #{url}: #{e}"
105
- end
106
-
107
- user
108
- end
109
- end
110
-
1
+ require 'serverspec/type/base'
2
+ require 'net/http'
3
+ require 'json'
4
+
5
+ module Serverspec::Type
6
+ class OctopusDeployUser < Base
7
+ @serverUrl = nil
8
+ @apiKey = nil
9
+ @userAccount = nil
10
+
11
+ def initialize(*url_and_api_key, userName)
12
+ serverUrl, apiKey = get_octopus_creds(url_and_api_key)
13
+
14
+ @name = "Octopus Deploy User Account #{userName}"
15
+ @runner = Specinfra::Runner
16
+ @serverUrl = serverUrl
17
+ @apiKey = apiKey
18
+
19
+ # is our auth info still nil?
20
+ if (serverUrl.nil?)
21
+ raise "'serverUrl' was not provided. Unable to connect to Octopus server to validate configuration."
22
+ end
23
+ if (apiKey.nil?)
24
+ raise "'apiKey' was not provided. Unable to connect to Octopus server to validate configuration."
25
+ end
26
+
27
+ if(userName.nil?)
28
+ raise "'userName' was not provided"
29
+ end
30
+
31
+ @userAccount = get_user_via_api(serverUrl, apiKey, userName)
32
+ end
33
+
34
+ def service_account?
35
+ return false if @userAccount.nil?
36
+ @userAccount['IsService'] == true
37
+ end
38
+
39
+ def exists?
40
+ (!@userAccount.nil?) && (@userAccount != [])
41
+ end
42
+
43
+ def active?
44
+ return false if @userAccount.nil?
45
+ @userAccount['IsActive'] == true
46
+ end
47
+
48
+ def has_email?(email)
49
+ return false if @userAccount.nil?
50
+ @userAccount['EmailAddress'] == email
51
+ end
52
+
53
+ def has_display_name?(name)
54
+ return false if @userAccount.nil?
55
+ @userAccount['DisplayName'] == name
56
+ end
57
+
58
+ def has_api_key?(purpose)
59
+ return false if @userAccount.nil?
60
+
61
+ user_api_key = nil
62
+ user_id = @userAccount['Id']
63
+ url = "#{@serverUrl}/api/users/#{user_id}/apikeys?api-key=#{@apiKey}&take=9999"
64
+
65
+ begin
66
+ resp = Net::HTTP.get_response(URI.parse(url))
67
+ body = JSON.parse(resp.body)
68
+ keys = body unless body.nil?
69
+ user_api_key = keys['Items'].select {|i| i['Purpose'] == purpose }.first unless keys.nil?
70
+
71
+ rescue => e
72
+ raise "has_api_key: Unable to connect to #{url}: #{e}"
73
+ end
74
+
75
+ !user_api_key.nil?
76
+ end
77
+ end
78
+
79
+ # module-level constructors/entrypoints
80
+
81
+ def octopus_deploy_user(*url_and_api_key, user_name)
82
+ serverUrl, apiKey = get_octopus_creds(url_and_api_key)
83
+ OctopusDeployUser.new(serverUrl, apiKey, user_name)
84
+ end
85
+
86
+ def octopus_user(*url_and_api_key, user_name)
87
+ serverUrl, apiKey = get_octopus_creds(url_and_api_key)
88
+ octopus_deploy_user(serverUrl, apiKey, user_name)
89
+ end
90
+
91
+ private
92
+
93
+ def get_user_via_api(serverUrl, apiKey, user_name)
94
+ user = nil
95
+
96
+ url = "#{serverUrl}/api/users/all?api-key=#{apiKey}"
97
+
98
+ begin
99
+ resp = Net::HTTP.get_response(URI.parse(url))
100
+ body = JSON.parse(resp.body)
101
+ users = body unless body.nil?
102
+ user = users.select {|i| i['Username'] == user_name }.first unless users.nil?
103
+ rescue => e
104
+ raise "get_user_via_api: Unable to connect to #{url}: #{e}"
105
+ end
106
+
107
+ user
108
+ end
109
+ end
110
+
111
111
  include Serverspec::Type
@@ -1,173 +1,173 @@
1
- require 'serverspec'
2
- require 'serverspec/type/base'
3
- require 'net/http'
4
- require 'json'
5
-
6
- module Serverspec::Type
7
- class OctopusDeployWorker < Base
8
- @worker = nil
9
- @serverUrl = nil
10
- @apiKey = nil
11
- @serverSupportsSpaces = nil
12
- @spaceId = nil
13
- @spaceFragment = ""
14
-
15
- def initialize(serverUrl, apiKey, instance, spaceId = 'Spaces-1')
16
- @name = "Octopus Deploy Worker #{instance}"
17
- @runner = Specinfra::Runner
18
- @serverUrl = serverUrl
19
- @apiKey = apiKey
20
- @spaceId = spaceId
21
-
22
- if (serverUrl.nil?)
23
- raise "'serverUrl' was not provided. Unable to connect to Octopus server to validate configuration."
24
- end
25
- if (apiKey.nil?)
26
- raise "'apiKey' was not provided. Unable to connect to Octopus server to validate configuration."
27
- end
28
-
29
- if (exists?)
30
- thumbprint = `"c:\\program files\\Octopus Deploy\\Tentacle\\Tentacle.exe" show-thumbprint --console --nologo --instance #{instance}`
31
- thumbprint = thumbprint.gsub('==== ShowThumbprintCommand starting ====', '').strip
32
- thumbprint = thumbprint.gsub('The thumbprint of this Tentacle is: ', '').strip
33
- thumbprint = thumbprint.gsub('==== ShowThumbprintCommand completed ====', '').strip
34
- thumbprint = thumbprint.gsub('==== ShowThumbprintCommand ====', '').strip
35
-
36
- @serverSupportsSpaces = check_supports_spaces(serverUrl)
37
-
38
- if (@serverSupportsSpaces)
39
- @spaceFragment = "#{@spaceId}/"
40
- end
41
-
42
- @worker = get_worker_via_api(serverUrl, apiKey, thumbprint)
43
- else
44
- puts "tentacle.exe does not exist"
45
- end
46
- end
47
-
48
- def registered_with_the_server?
49
- !@worker.nil?
50
- end
51
-
52
- def online?
53
- return nil if @worker.nil?
54
- @worker = poll_until_worker_has_completed_healthcheck(@serverUrl, @apiKey, @worker["Thumbprint"])
55
- status = @worker['Status']
56
- if ("#{status}" == "")
57
- status = @worker['HealthStatus'] if "#{status}" == ""
58
- puts "Expected status 'Healthy|HasWarnings' for Worker #{@name}, but got '#{status}'" if (status != "Healthy" && status != "HasWarnings")
59
- status == "Healthy" || status == "HasWarnings"
60
- else
61
- puts "Expected status 'Online|CalamariNeedsUpgrade|NeedsUpgrade' for Worker #{@name}, but got '#{status}'" if (status != "Online" && status != "CalamariNeedsUpgrade" && status != "NeedsUpgrade")
62
- status == "Online" || status == "CalamariNeedsUpgrade" || status == "NeedsUpgrade"
63
- end
64
- end
65
-
66
- def in_space?(space_name)
67
- return false if @worker.nil?
68
- return false if @serverSupportsSpaces
69
- url = "#{@serverUrl}/api/spaces/all?api-key=#{@apiKey}"
70
- resp = Net::HTTP.get_response(URI.parse(url))
71
- spaces = JSON.parse(resp.body)
72
- space_id = spaces.select {|e| e["Name"] == space_name}.first["Id"]
73
- @worker["SpaceId"] == space_id
74
- end
75
-
76
- def has_policy?(policy_name)
77
- return false if @worker.nil?
78
- url = "#{@serverUrl}/api/#{@spaceFragment}machinepolicies/all?api-key=#{@apiKey}"
79
- resp = Net::HTTP.get_response(URI.parse(url))
80
- policies = JSON.parse(resp.body)
81
- policy_id = policies.select {|e| e["Name"] == policy_name}.first["Id"]
82
- @worker["MachinePolicyId"] == policy_id
83
- end
84
-
85
- def has_display_name?(name)
86
- return false if @worker.nil?
87
- @worker["Name"] == name
88
- end
89
-
90
- def has_endpoint?(uri)
91
- return false if @worker.nil?
92
- return false if @worker["Uri"].nil? # polling tentacles have null endpoint. catch that.
93
- puts "Expected uri '#{uri}' for Worker #{@name}, but got '#{@worker["Uri"]}'" unless (@worker["Uri"].casecmp(uri) == 0)
94
- @worker["Uri"].casecmp(uri) == 0
95
- end
96
-
97
- def listening_worker?
98
- return false if @worker.nil?
99
- puts "Expected CommunicationStyle 'TentaclePassive' for Tentacle #{@name}, but got '#{@worker["Endpoint"]["CommunicationStyle"]}'" if (@worker["Endpoint"]["CommunicationStyle"] != "TentaclePassive")
100
- @worker["Endpoint"]["CommunicationStyle"] == "TentaclePassive"
101
- end
102
-
103
- def polling_worker?
104
- return false if @worker.nil?
105
- puts "Expected CommunicationStyle 'TentacleActive' for Tentacle #{@name}, but got '#{@worker["Endpoint"]["CommunicationStyle"]}'" if (@worker["Endpoint"]["CommunicationStyle"] != "TentacleActive")
106
- @worker["Endpoint"]["CommunicationStyle"] == "TentacleActive"
107
- end
108
-
109
- def exists?
110
- ::File.exists?("c:\\program files\\Octopus Deploy\\Tentacle\\Tentacle.exe")
111
- end
112
- end
113
-
114
- def octopus_deploy_worker(serverUrl, apiKey, instance)
115
- OctopusDeployWorker.new(serverUrl, apiKey, instance)
116
- end
117
-
118
- private
119
-
120
- def check_supports_spaces(serverUrl)
121
- begin
122
- resp = Net::HTTP.get_response(URI.parse("#{serverUrl}/api/"))
123
- body = JSON.parse(resp.body)
124
- version = body['Version']
125
- return Gem::Version.new(version) > Gem::Version.new('2019.0.0')
126
- rescue => e
127
- puts "Unable to connect to #{serverUrl}: #{e}"
128
- end
129
-
130
- return false
131
- end
132
-
133
- def poll_until_worker_has_completed_healthcheck(serverUrl, apiKey, thumbprint)
134
- worker = nil
135
- url = "#{serverUrl}/api/#{@spaceFragment}workers/all?api-key=#{apiKey}"
136
-
137
- now = Time.now
138
- counter = 1
139
- loop do
140
- worker = get_worker_via_api(serverUrl, apiKey, thumbprint)
141
-
142
- break if worker.nil?
143
- break if counter > 10
144
- break if !worker_healthcheck_outstanding(worker)
145
- puts "Machine health check for #{worker["Name"]} has not yet completed. Waiting 5 seconds to try again."
146
- counter += 1
147
- sleep 5
148
- end
149
-
150
- worker
151
- end
152
-
153
- def worker_healthcheck_outstanding(worker)
154
- worker["StatusSummary"] == "This machine was recently added. Please perform a health check."
155
- end
156
-
157
- def get_worker_via_api(serverUrl, apiKey, thumbprint)
158
- worker = nil
159
- url = "#{serverUrl}/api/#{@spaceFragment}workers/all?api-key=#{apiKey}"
160
-
161
- begin
162
- resp = Net::HTTP.get_response(URI.parse(url))
163
- body = JSON.parse(resp.body)
164
- worker = body.select {|e| e["Thumbprint"] == thumbprint}.first unless body.nil?
165
- rescue => e
166
- puts "Unable to connect to #{url}: #{e}"
167
- end
168
-
169
- worker
170
- end
171
- end
172
-
173
- include Serverspec::Type
1
+ require 'serverspec'
2
+ require 'serverspec/type/base'
3
+ require 'net/http'
4
+ require 'json'
5
+
6
+ module Serverspec::Type
7
+ class OctopusDeployWorker < Base
8
+ @worker = nil
9
+ @serverUrl = nil
10
+ @apiKey = nil
11
+ @serverSupportsSpaces = nil
12
+ @spaceId = nil
13
+ @spaceFragment = ""
14
+
15
+ def initialize(serverUrl, apiKey, instance, spaceId = 'Spaces-1')
16
+ @name = "Octopus Deploy Worker #{instance}"
17
+ @runner = Specinfra::Runner
18
+ @serverUrl = serverUrl
19
+ @apiKey = apiKey
20
+ @spaceId = spaceId
21
+
22
+ if (serverUrl.nil?)
23
+ raise "'serverUrl' was not provided. Unable to connect to Octopus server to validate configuration."
24
+ end
25
+ if (apiKey.nil?)
26
+ raise "'apiKey' was not provided. Unable to connect to Octopus server to validate configuration."
27
+ end
28
+
29
+ if (exists?)
30
+ thumbprint = `"c:\\program files\\Octopus Deploy\\Tentacle\\Tentacle.exe" show-thumbprint --console --nologo --instance #{instance}`
31
+ thumbprint = thumbprint.gsub('==== ShowThumbprintCommand starting ====', '').strip
32
+ thumbprint = thumbprint.gsub('The thumbprint of this Tentacle is: ', '').strip
33
+ thumbprint = thumbprint.gsub('==== ShowThumbprintCommand completed ====', '').strip
34
+ thumbprint = thumbprint.gsub('==== ShowThumbprintCommand ====', '').strip
35
+
36
+ @serverSupportsSpaces = check_supports_spaces(serverUrl)
37
+
38
+ if (@serverSupportsSpaces)
39
+ @spaceFragment = "#{@spaceId}/"
40
+ end
41
+
42
+ @worker = get_worker_via_api(serverUrl, apiKey, thumbprint)
43
+ else
44
+ puts "tentacle.exe does not exist"
45
+ end
46
+ end
47
+
48
+ def registered_with_the_server?
49
+ !@worker.nil?
50
+ end
51
+
52
+ def online?
53
+ return nil if @worker.nil?
54
+ @worker = poll_until_worker_has_completed_healthcheck(@serverUrl, @apiKey, @worker["Thumbprint"])
55
+ status = @worker['Status']
56
+ if ("#{status}" == "")
57
+ status = @worker['HealthStatus'] if "#{status}" == ""
58
+ puts "Expected status 'Healthy|HasWarnings' for Worker #{@name}, but got '#{status}'" if (status != "Healthy" && status != "HasWarnings")
59
+ status == "Healthy" || status == "HasWarnings"
60
+ else
61
+ puts "Expected status 'Online|CalamariNeedsUpgrade|NeedsUpgrade' for Worker #{@name}, but got '#{status}'" if (status != "Online" && status != "CalamariNeedsUpgrade" && status != "NeedsUpgrade")
62
+ status == "Online" || status == "CalamariNeedsUpgrade" || status == "NeedsUpgrade"
63
+ end
64
+ end
65
+
66
+ def in_space?(space_name)
67
+ return false if @worker.nil?
68
+ return false if @serverSupportsSpaces
69
+ url = "#{@serverUrl}/api/spaces/all?api-key=#{@apiKey}"
70
+ resp = Net::HTTP.get_response(URI.parse(url))
71
+ spaces = JSON.parse(resp.body)
72
+ space_id = spaces.select {|e| e["Name"] == space_name}.first["Id"]
73
+ @worker["SpaceId"] == space_id
74
+ end
75
+
76
+ def has_policy?(policy_name)
77
+ return false if @worker.nil?
78
+ url = "#{@serverUrl}/api/#{@spaceFragment}machinepolicies/all?api-key=#{@apiKey}"
79
+ resp = Net::HTTP.get_response(URI.parse(url))
80
+ policies = JSON.parse(resp.body)
81
+ policy_id = policies.select {|e| e["Name"] == policy_name}.first["Id"]
82
+ @worker["MachinePolicyId"] == policy_id
83
+ end
84
+
85
+ def has_display_name?(name)
86
+ return false if @worker.nil?
87
+ @worker["Name"] == name
88
+ end
89
+
90
+ def has_endpoint?(uri)
91
+ return false if @worker.nil?
92
+ return false if @worker["Uri"].nil? # polling tentacles have null endpoint. catch that.
93
+ puts "Expected uri '#{uri}' for Worker #{@name}, but got '#{@worker["Uri"]}'" unless (@worker["Uri"].casecmp(uri) == 0)
94
+ @worker["Uri"].casecmp(uri) == 0
95
+ end
96
+
97
+ def listening_worker?
98
+ return false if @worker.nil?
99
+ puts "Expected CommunicationStyle 'TentaclePassive' for Tentacle #{@name}, but got '#{@worker["Endpoint"]["CommunicationStyle"]}'" if (@worker["Endpoint"]["CommunicationStyle"] != "TentaclePassive")
100
+ @worker["Endpoint"]["CommunicationStyle"] == "TentaclePassive"
101
+ end
102
+
103
+ def polling_worker?
104
+ return false if @worker.nil?
105
+ puts "Expected CommunicationStyle 'TentacleActive' for Tentacle #{@name}, but got '#{@worker["Endpoint"]["CommunicationStyle"]}'" if (@worker["Endpoint"]["CommunicationStyle"] != "TentacleActive")
106
+ @worker["Endpoint"]["CommunicationStyle"] == "TentacleActive"
107
+ end
108
+
109
+ def exists?
110
+ ::File.exists?("c:\\program files\\Octopus Deploy\\Tentacle\\Tentacle.exe")
111
+ end
112
+ end
113
+
114
+ def octopus_deploy_worker(serverUrl, apiKey, instance)
115
+ OctopusDeployWorker.new(serverUrl, apiKey, instance)
116
+ end
117
+
118
+ private
119
+
120
+ def check_supports_spaces(serverUrl)
121
+ begin
122
+ resp = Net::HTTP.get_response(URI.parse("#{serverUrl}/api/"))
123
+ body = JSON.parse(resp.body)
124
+ version = body['Version']
125
+ return Gem::Version.new(version) > Gem::Version.new('2019.0.0')
126
+ rescue => e
127
+ puts "Unable to connect to #{serverUrl}: #{e}"
128
+ end
129
+
130
+ return false
131
+ end
132
+
133
+ def poll_until_worker_has_completed_healthcheck(serverUrl, apiKey, thumbprint)
134
+ worker = nil
135
+ url = "#{serverUrl}/api/#{@spaceFragment}workers/all?api-key=#{apiKey}"
136
+
137
+ now = Time.now
138
+ counter = 1
139
+ loop do
140
+ worker = get_worker_via_api(serverUrl, apiKey, thumbprint)
141
+
142
+ break if worker.nil?
143
+ break if counter > 10
144
+ break if !worker_healthcheck_outstanding(worker)
145
+ puts "Machine health check for #{worker["Name"]} has not yet completed. Waiting 5 seconds to try again."
146
+ counter += 1
147
+ sleep 5
148
+ end
149
+
150
+ worker
151
+ end
152
+
153
+ def worker_healthcheck_outstanding(worker)
154
+ worker["StatusSummary"] == "This machine was recently added. Please perform a health check."
155
+ end
156
+
157
+ def get_worker_via_api(serverUrl, apiKey, thumbprint)
158
+ worker = nil
159
+ url = "#{serverUrl}/api/#{@spaceFragment}workers/all?api-key=#{apiKey}"
160
+
161
+ begin
162
+ resp = Net::HTTP.get_response(URI.parse(url))
163
+ body = JSON.parse(resp.body)
164
+ worker = body.select {|e| e["Thumbprint"] == thumbprint}.first unless body.nil?
165
+ rescue => e
166
+ puts "Unable to connect to #{url}: #{e}"
167
+ end
168
+
169
+ worker
170
+ end
171
+ end
172
+
173
+ include Serverspec::Type