octopus-serverspec-extensions 0.14.0 → 0.15.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,29 +1,29 @@
1
- require 'serverspec'
2
- require 'serverspec/type/base'
3
-
4
- module Serverspec::Type
5
- class JavaPropertyFile < Base
6
-
7
- def initialize(name)
8
- @name = name
9
- @runner = Specinfra::Runner
10
- end
11
-
12
- def has_property?(propertyName, propertyValue)
13
- properties = {}
14
- IO.foreach(@name) do |line|
15
- if (!line.start_with?('#'))
16
- properties[$1.strip] = $2 if line =~ /([^=]*)=(.*)/
17
- end
18
- end
19
-
20
- properties[propertyName] == propertyValue
21
- end
22
- end
23
-
24
- def java_property_file(name)
25
- JavaPropertyFile.new(name)
26
- end
27
- end
28
-
1
+ require 'serverspec'
2
+ require 'serverspec/type/base'
3
+
4
+ module Serverspec::Type
5
+ class JavaPropertyFile < Base
6
+
7
+ def initialize(name)
8
+ @name = name
9
+ @runner = Specinfra::Runner
10
+ end
11
+
12
+ def has_property?(propertyName, propertyValue)
13
+ properties = {}
14
+ IO.foreach(@name) do |line|
15
+ if (!line.start_with?('#'))
16
+ properties[$1.strip] = $2 if line =~ /([^=]*)=(.*)/
17
+ end
18
+ end
19
+
20
+ properties[propertyName] == propertyValue
21
+ end
22
+ end
23
+
24
+ def java_property_file(name)
25
+ JavaPropertyFile.new(name)
26
+ end
27
+ end
28
+
29
29
  include Serverspec::Type
@@ -1,37 +1,37 @@
1
- require 'serverspec'
2
- require 'serverspec/type/base'
3
-
4
- module Serverspec::Type
5
- class NpmPackage < Base
6
-
7
- def initialize(name)
8
- @name = name
9
- @runner = Specinfra::Runner
10
- end
11
-
12
- def installed?(provider, version)
13
- command_result = @runner.run_command("npm list -g #{name}")
14
-
15
- software = command_result.stdout.split("\n").each_with_object({}) do |s, h|
16
- if s.include? "@"
17
- package_name, package_version = s.split('@')
18
- package_name = package_name.gsub(/.*? /, '')
19
- h[String(package_name).strip.downcase] = String(package_version).strip.downcase
20
- end
21
- h
22
- end
23
-
24
- if (version.nil?)
25
- !software[name.downcase].nil?
26
- else
27
- software[name.downcase] == version
28
- end
29
- end
30
- end
31
-
32
- def npm_package(name)
33
- NpmPackage.new(name)
34
- end
35
- end
36
-
1
+ require 'serverspec'
2
+ require 'serverspec/type/base'
3
+
4
+ module Serverspec::Type
5
+ class NpmPackage < Base
6
+
7
+ def initialize(name)
8
+ @name = name
9
+ @runner = Specinfra::Runner
10
+ end
11
+
12
+ def installed?(provider, version)
13
+ command_result = @runner.run_command("npm list -g #{name}")
14
+
15
+ software = command_result.stdout.split("\n").each_with_object({}) do |s, h|
16
+ if s.include? "@"
17
+ package_name, package_version = s.split('@')
18
+ package_name = package_name.gsub(/.*? /, '')
19
+ h[String(package_name).strip.downcase] = String(package_version).strip.downcase
20
+ end
21
+ h
22
+ end
23
+
24
+ if (version.nil?)
25
+ !software[name.downcase].nil?
26
+ else
27
+ software[name.downcase] == version
28
+ end
29
+ end
30
+ end
31
+
32
+ def npm_package(name)
33
+ NpmPackage.new(name)
34
+ end
35
+ end
36
+
37
37
  include Serverspec::Type
@@ -1,57 +1,58 @@
1
- require 'serverspec'
2
- require 'serverspec/type/base'
3
- require 'net/http'
4
- require 'json'
5
-
6
- module Serverspec::Type
7
- class OctopusDeployEnvironment < Base
8
- @environment = nil
9
- @serverUrl = nil
10
- @apiKey = nil
11
-
12
- def initialize(serverUrl, apiKey, environment_name)
13
- @name = "Octopus Deploy Environment #{environment_name}"
14
- @runner = Specinfra::Runner
15
- @serverUrl = serverUrl
16
- @apiKey = apiKey
17
-
18
- if (serverUrl.nil?)
19
- puts "'serverUrl' was not provided. Unable to connect to Octopus server to validate configuration."
20
- return
21
- end
22
- if (apiKey.nil?)
23
- puts "'apiKey' was not provided. Unable to connect to Octopus server to validate configuration."
24
- return
25
- end
26
-
27
- @environment = get_environment_via_api(serverUrl, apiKey, environment_name)
28
- end
29
-
30
- def exists?
31
- !@environment.nil?
32
- end
33
- end
34
-
35
- def octopus_deploy_environment(serverUrl, apiKey, environment_name)
36
- OctopusDeployEnvironment.new(serverUrl, apiKey, environment_name)
37
- end
38
-
39
- private
40
-
41
- def get_environment_via_api(serverUrl, apiKey, environment_name)
42
- environment = nil
43
- url = "#{serverUrl}/api/environments?name=#{environment_name}&api-key=#{apiKey}"
44
-
45
- begin
46
- resp = Net::HTTP.get_response(URI.parse(url))
47
- body = JSON.parse(resp.body)
48
- environment = body['Items'].first unless body.nil?
49
- rescue => e
50
- puts "Unable to connect to #{url}: #{e}"
51
- end
52
-
53
- environment
54
- end
55
- end
56
-
57
- 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 OctopusDeployEnvironment < Base
8
+ @environment = nil
9
+ @serverUrl = nil
10
+ @apiKey = nil
11
+
12
+ def initialize(serverUrl, apiKey, environment_name)
13
+ @name = "Octopus Deploy Environment #{environment_name}"
14
+ @runner = Specinfra::Runner
15
+ @serverUrl = serverUrl
16
+ @apiKey = apiKey
17
+
18
+ if (serverUrl.nil?)
19
+ raise "'serverUrl' was not provided. Unable to connect to Octopus server to validate configuration."
20
+ end
21
+ if (apiKey.nil?)
22
+ raise "'apiKey' was not provided. Unable to connect to Octopus server to validate configuration."
23
+ end
24
+ if (environment_name.nil?)
25
+ raise "'environment_name' was not provided. Unable to connect to Octopus server to validate configuration."
26
+ end
27
+
28
+ @environment = get_environment_via_api(serverUrl, apiKey, environment_name)
29
+ end
30
+
31
+ def exists?
32
+ (!@environment.nil?) && (@environment != [])
33
+ end
34
+ end
35
+
36
+ def octopus_deploy_environment(serverUrl, apiKey, environment_name)
37
+ OctopusDeployEnvironment.new(serverUrl, apiKey, environment_name)
38
+ end
39
+
40
+ private
41
+
42
+ def get_environment_via_api(serverUrl, apiKey, environment_name)
43
+ environment = nil
44
+ url = "#{serverUrl}/api/environments?name=#{environment_name}&api-key=#{apiKey}"
45
+
46
+ begin
47
+ resp = Net::HTTP.get_response(URI.parse(url))
48
+ body = JSON.parse(resp.body)
49
+ environment = body['Items'].first unless body.nil?
50
+ rescue => e
51
+ raise "Unable to connect to #{url}: #{e}"
52
+ end
53
+
54
+ environment
55
+ end
56
+ end
57
+
58
+ include Serverspec::Type
@@ -1,171 +1,204 @@
1
- require 'serverspec'
2
- require 'serverspec/type/base'
3
- require 'net/http'
4
- require 'json'
5
-
6
- module Serverspec::Type
7
- class OctopusDeployTentacle < Base
8
- @machine = nil
9
- @serverUrl = nil
10
- @apiKey = nil
11
-
12
- def initialize(serverUrl, apiKey, instance)
13
- @name = "Octopus Deploy Tentacle #{instance}"
14
- @runner = Specinfra::Runner
15
- @serverUrl = serverUrl
16
- @apiKey = apiKey
17
-
18
- if (serverUrl.nil?)
19
- puts "'serverUrl' was not provided. Unable to connect to Octopus server to validate configuration."
20
- return
21
- end
22
- if (apiKey.nil?)
23
- puts "'apiKey' was not provided. Unable to connect to Octopus server to validate configuration."
24
- return
25
- end
26
-
27
- if (exists?)
28
- thumbprint = `"c:\\program files\\Octopus Deploy\\Tentacle\\Tentacle.exe" show-thumbprint --console --nologo --instance #{instance}`
29
- thumbprint = thumbprint.gsub('==== ShowThumbprintCommand starting ====', '').strip
30
- thumbprint = thumbprint.gsub('The thumbprint of this Tentacle is: ', '').strip
31
- thumbprint = thumbprint.gsub('==== ShowThumbprintCommand completed ====', '').strip
32
- thumbprint = thumbprint.gsub('==== ShowThumbprintCommand ====', '').strip
33
-
34
- @machine = get_machine_via_api(serverUrl, apiKey, thumbprint)
35
- else
36
- puts "tentacle.exe does not exist"
37
- end
38
- end
39
-
40
- def registered_with_the_server?
41
- !@machine.nil?
42
- end
43
-
44
- def online?
45
- return nil if @machine.nil?
46
- @machine = poll_until_machine_has_completed_healthcheck(@serverUrl, @apiKey, @machine["Thumbprint"])
47
- status = @machine['Status']
48
- if ("#{status}" == "")
49
- status = @machine['HealthStatus'] if "#{status}" == ""
50
- puts "Expected status 'Healthy|HasWarnings' for Tentacle #{@name}, but got '#{status}'" if (status != "Healthy" && status != "HasWarnings")
51
- status == "Healthy" || status == "HasWarnings"
52
- else
53
- puts "Expected status 'Online|CalamariNeedsUpgrade|NeedsUpgrade' for Tentacle #{@name}, but got '#{status}'" if (status != "Online" && status != "CalamariNeedsUpgrade" && status != "NeedsUpgrade")
54
- status == "Online" || status == "CalamariNeedsUpgrade" || status == "NeedsUpgrade"
55
- end
56
- end
57
-
58
- def in_environment?(environment_name)
59
- return false if @machine.nil?
60
- url = "#{@serverUrl}/api/environments/all?api-key=#{@apiKey}"
61
- resp = Net::HTTP.get_response(URI.parse(url))
62
- environments = JSON.parse(resp.body)
63
- environment_id = environments.select {|e| e["Name"] == environment_name}.first["Id"]
64
- !@machine["EnvironmentIds"].select {|e| e == environment_id}.empty?
65
- end
66
-
67
- def has_tenant?(tenant_name)
68
- return false if @machine.nil?
69
- url = "#{@serverUrl}/api/tenants/all?api-key=#{@apiKey}"
70
- resp = Net::HTTP.get_response(URI.parse(url))
71
- tenants = JSON.parse(resp.body)
72
- tenant_id = tenants.select {|e| e["Name"] == tenant_name}.first["Id"]
73
- !@machine["TenantIds"].select {|e| e == tenant_id}.empty?
74
- end
75
-
76
- def has_tenant_tag?(tag_set, tag)
77
- return false if @machine.nil?
78
- tenant_tags = @machine["TenantTags"]
79
- !tenant_tags.select {|e| e == "#{tag_set}/#{tag}"}.empty?
80
- end
81
-
82
- def has_policy?(policy_name)
83
- return false if @machine.nil?
84
- url = "#{@serverUrl}/api/machinepolicies/all?api-key=#{@apiKey}"
85
- resp = Net::HTTP.get_response(URI.parse(url))
86
- policies = JSON.parse(resp.body)
87
- policy_id = policies.select {|e| e["Name"] == policy_name}.first["Id"]
88
- @machine["MachinePolicyId"] == policy_id
89
- end
90
-
91
- def has_role?(role_name)
92
- return false if @machine.nil?
93
- roles = @machine["Roles"]
94
- !roles.select {|e| e == role_name}.empty?
95
- end
96
-
97
- def has_display_name?(name)
98
- return false if @machine.nil?
99
- @machine["Name"] == name
100
- end
101
-
102
- def has_endpoint?(uri)
103
- return false if @machine.nil?
104
- puts "Expected uri '#{uri}' for Tentacle #{@name}, but got '#{@machine["Uri"]}'" unless (@machine["Uri"].casecmp(uri) == 0)
105
- @machine["Uri"].casecmp(uri) == 0
106
- end
107
-
108
- def listening_tentacle?
109
- return false if @machine.nil?
110
- puts "Expected CommunicationStyle 'TentaclePassive' for Tentacle #{@name}, but got '#{@machine["Endpoint"]["CommunicationStyle"]}'" if (@machine["Endpoint"]["CommunicationStyle"] != "TentaclePassive")
111
- @machine["Endpoint"]["CommunicationStyle"] == "TentaclePassive"
112
- end
113
-
114
- def polling_tentacle?
115
- return false if @machine.nil?
116
- puts "Expected CommunicationStyle 'TentacleActive' for Tentacle #{@name}, but got '#{@machine["Endpoint"]["CommunicationStyle"]}'" if (@machine["Endpoint"]["CommunicationStyle"] != "TentacleActive")
117
- @machine["Endpoint"]["CommunicationStyle"] == "TentacleActive"
118
- end
119
-
120
- def exists?
121
- ::File.exists?("c:\\program files\\Octopus Deploy\\Tentacle\\Tentacle.exe")
122
- end
123
- end
124
-
125
- def octopus_deploy_tentacle(serverUrl, apiKey, instance)
126
- OctopusDeployTentacle.new(serverUrl, apiKey, instance)
127
- end
128
-
129
- private
130
-
131
- def poll_until_machine_has_completed_healthcheck(serverUrl, apiKey, thumbprint)
132
- machine = nil
133
- url = "#{serverUrl}/api/machines/all?api-key=#{apiKey}"
134
-
135
- now = Time.now
136
- counter = 1
137
- loop do
138
- machine = get_machine_via_api(serverUrl, apiKey, thumbprint)
139
-
140
- break if machine.nil?
141
- break if counter > 10
142
- break if !machine_healthcheck_outstanding(machine)
143
- puts "Machine health check for #{machine["Name"]} has not yet completed. Waiting 5 seconds to try again."
144
- counter += 1
145
- sleep 5
146
- end
147
-
148
- machine
149
- end
150
-
151
- def machine_healthcheck_outstanding(machine)
152
- machine["StatusSummary"] == "This machine was recently added. Please perform a health check."
153
- end
154
-
155
- def get_machine_via_api(serverUrl, apiKey, thumbprint)
156
- machine = nil
157
- url = "#{serverUrl}/api/machines/all?api-key=#{apiKey}"
158
-
159
- begin
160
- resp = Net::HTTP.get_response(URI.parse(url))
161
- body = JSON.parse(resp.body)
162
- machine = body.select {|e| e["Thumbprint"] == thumbprint}.first unless body.nil?
163
- rescue => e
164
- puts "Unable to connect to #{url}: #{e}"
165
- end
166
-
167
- machine
168
- end
169
- end
170
-
171
- 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 OctopusDeployTentacle < Base
8
+ @machine = 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 Tentacle #{instance}"
17
+ @runner = Specinfra::Runner
18
+ @serverUrl = serverUrl
19
+ @apiKey = apiKey
20
+ @spaceId = spaceId
21
+
22
+ if (serverUrl.nil?)
23
+ puts "'serverUrl' was not provided. Unable to connect to Octopus server to validate configuration."
24
+ return
25
+ end
26
+ if (apiKey.nil?)
27
+ puts "'apiKey' was not provided. Unable to connect to Octopus server to validate configuration."
28
+ return
29
+ end
30
+
31
+ if (exists?)
32
+ thumbprint = `"c:\\program files\\Octopus Deploy\\Tentacle\\Tentacle.exe" show-thumbprint --console --nologo --instance #{instance}`
33
+ thumbprint = thumbprint.gsub('==== ShowThumbprintCommand starting ====', '').strip
34
+ thumbprint = thumbprint.gsub('The thumbprint of this Tentacle is: ', '').strip
35
+ thumbprint = thumbprint.gsub('==== ShowThumbprintCommand completed ====', '').strip
36
+ thumbprint = thumbprint.gsub('==== ShowThumbprintCommand ====', '').strip
37
+
38
+ @serverSupportsSpaces = check_supports_spaces(serverUrl)
39
+
40
+ if (@serverSupportsSpaces)
41
+ @spaceFragment = "#{@spaceId}/"
42
+ end
43
+
44
+ @machine = get_machine_via_api(serverUrl, apiKey, thumbprint)
45
+ else
46
+ puts "tentacle.exe does not exist"
47
+ end
48
+ end
49
+
50
+ def registered_with_the_server?
51
+ !@machine.nil?
52
+ end
53
+
54
+ def online?
55
+ return nil if @machine.nil?
56
+ @machine = poll_until_machine_has_completed_healthcheck(@serverUrl, @apiKey, @machine["Thumbprint"])
57
+ status = @machine['Status']
58
+ if ("#{status}" == "")
59
+ status = @machine['HealthStatus'] if "#{status}" == ""
60
+ puts "Expected status 'Healthy|HasWarnings' for Tentacle #{@name}, but got '#{status}'" if (status != "Healthy" && status != "HasWarnings")
61
+ status == "Healthy" || status == "HasWarnings"
62
+ else
63
+ puts "Expected status 'Online|CalamariNeedsUpgrade|NeedsUpgrade' for Tentacle #{@name}, but got '#{status}'" if (status != "Online" && status != "CalamariNeedsUpgrade" && status != "NeedsUpgrade")
64
+ status == "Online" || status == "CalamariNeedsUpgrade" || status == "NeedsUpgrade"
65
+ end
66
+ end
67
+
68
+ def in_environment?(environment_name)
69
+ return false if @machine.nil?
70
+ url = "#{@serverUrl}/api/#{spaceFragment}environments/all?api-key=#{@apiKey}"
71
+ resp = Net::HTTP.get_response(URI.parse(url))
72
+ environments = JSON.parse(resp.body)
73
+ environment_id = environments.select {|e| e["Name"] == environment_name}.first["Id"]
74
+ !@machine["EnvironmentIds"].select {|e| e == environment_id}.empty?
75
+ end
76
+
77
+ def in_space?(space_name)
78
+ return false if @machine.nil?
79
+ return false if @serverSupportsSpaces
80
+ url = "#{@serverUrl}/api/#{spaceFragment}spaces/all?api-key=#{@apiKey}"
81
+ resp = Net::HTTP.get_response(URI.parse(url))
82
+ spaces = JSON.parse(resp.body)
83
+ space_id = spaces.select {|e| e["Name"] == space_name}.first["Id"]
84
+ @machine["SpaceId"] == space_id
85
+ end
86
+
87
+ def has_tenant?(tenant_name)
88
+ return false if @machine.nil?
89
+ url = "#{@serverUrl}/api/#{spaceFragment}tenants/all?api-key=#{@apiKey}"
90
+ resp = Net::HTTP.get_response(URI.parse(url))
91
+ tenants = JSON.parse(resp.body)
92
+ tenant_id = tenants.select {|e| e["Name"] == tenant_name}.first["Id"]
93
+ !@machine["TenantIds"].select {|e| e == tenant_id}.empty?
94
+ end
95
+
96
+ def has_tenant_tag?(tag_set, tag)
97
+ return false if @machine.nil?
98
+ tenant_tags = @machine["TenantTags"]
99
+ !tenant_tags.select {|e| e == "#{tag_set}/#{tag}"}.empty?
100
+ end
101
+
102
+ def has_policy?(policy_name)
103
+ return false if @machine.nil?
104
+ url = "#{@serverUrl}/api/#{spaceFragment}machinepolicies/all?api-key=#{@apiKey}"
105
+ resp = Net::HTTP.get_response(URI.parse(url))
106
+ policies = JSON.parse(resp.body)
107
+ policy_id = policies.select {|e| e["Name"] == policy_name}.first["Id"]
108
+ @machine["MachinePolicyId"] == policy_id
109
+ end
110
+
111
+ def has_role?(role_name)
112
+ return false if @machine.nil?
113
+ roles = @machine["Roles"]
114
+ !roles.select {|e| e == role_name}.empty?
115
+ end
116
+
117
+ def has_display_name?(name)
118
+ return false if @machine.nil?
119
+ @machine["Name"] == name
120
+ end
121
+
122
+ def has_endpoint?(uri)
123
+ return false if @machine.nil?
124
+ puts "Expected uri '#{uri}' for Tentacle #{@name}, but got '#{@machine["Uri"]}'" unless (@machine["Uri"].casecmp(uri) == 0)
125
+ @machine["Uri"].casecmp(uri) == 0
126
+ end
127
+
128
+ def listening_tentacle?
129
+ return false if @machine.nil?
130
+ puts "Expected CommunicationStyle 'TentaclePassive' for Tentacle #{@name}, but got '#{@machine["Endpoint"]["CommunicationStyle"]}'" if (@machine["Endpoint"]["CommunicationStyle"] != "TentaclePassive")
131
+ @machine["Endpoint"]["CommunicationStyle"] == "TentaclePassive"
132
+ end
133
+
134
+ def polling_tentacle?
135
+ return false if @machine.nil?
136
+ puts "Expected CommunicationStyle 'TentacleActive' for Tentacle #{@name}, but got '#{@machine["Endpoint"]["CommunicationStyle"]}'" if (@machine["Endpoint"]["CommunicationStyle"] != "TentacleActive")
137
+ @machine["Endpoint"]["CommunicationStyle"] == "TentacleActive"
138
+ end
139
+
140
+ def exists?
141
+ ::File.exists?("c:\\program files\\Octopus Deploy\\Tentacle\\Tentacle.exe")
142
+ end
143
+ end
144
+
145
+ def octopus_deploy_tentacle(serverUrl, apiKey, instance)
146
+ OctopusDeployTentacle.new(serverUrl, apiKey, instance)
147
+ end
148
+
149
+ private
150
+
151
+ def check_supports_spaces(serverUrl)
152
+ begin
153
+ resp = Net::HTTP.get_response(URI.parse("#{serverUrl}/api/"))
154
+ body = JSON.parse(resp.body)
155
+ version = body['Version']
156
+ return Gem::Version.new(version) > Gem::Version.new('2019.0.0')
157
+ rescue => e
158
+ puts "Unable to connect to #{serverUrl}: #{e}"
159
+ end
160
+
161
+ return false
162
+ end
163
+
164
+ def poll_until_machine_has_completed_healthcheck(serverUrl, apiKey, thumbprint)
165
+ machine = nil
166
+ url = "#{serverUrl}/api/#{spaceFragment}machines/all?api-key=#{apiKey}"
167
+
168
+ now = Time.now
169
+ counter = 1
170
+ loop do
171
+ machine = get_machine_via_api(serverUrl, apiKey, thumbprint)
172
+
173
+ break if machine.nil?
174
+ break if counter > 10
175
+ break if !machine_healthcheck_outstanding(machine)
176
+ puts "Machine health check for #{machine["Name"]} has not yet completed. Waiting 5 seconds to try again."
177
+ counter += 1
178
+ sleep 5
179
+ end
180
+
181
+ machine
182
+ end
183
+
184
+ def machine_healthcheck_outstanding(machine)
185
+ machine["StatusSummary"] == "This machine was recently added. Please perform a health check."
186
+ end
187
+
188
+ def get_machine_via_api(serverUrl, apiKey, thumbprint)
189
+ machine = nil
190
+ url = "#{serverUrl}/api/#{spaceFragment}machines/all?api-key=#{apiKey}"
191
+
192
+ begin
193
+ resp = Net::HTTP.get_response(URI.parse(url))
194
+ body = JSON.parse(resp.body)
195
+ machine = body.select {|e| e["Thumbprint"] == thumbprint}.first unless body.nil?
196
+ rescue => e
197
+ puts "Unable to connect to #{url}: #{e}"
198
+ end
199
+
200
+ machine
201
+ end
202
+ end
203
+
204
+ include Serverspec::Type