octopus-serverspec-extensions 0.15.5 → 0.17.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.
- checksums.yaml +4 -4
- data/docs/authentication.md +45 -0
- data/docs/octopus_deploy_account.md +37 -0
- data/docs/octopus_deploy_doc_template.md +17 -0
- data/docs/octopus_deploy_environment.md +33 -0
- data/docs/octopus_deploy_project_group.md +31 -0
- data/docs/octopus_deploy_smtp_config.md +39 -0
- data/docs/octopus_deploy_space.md +32 -0
- data/docs/octopus_deploy_team.md +26 -0
- data/docs/octopus_deploy_tentacle.md +41 -0
- data/docs/octopus_deploy_upgrade_config.md +34 -0
- data/docs/octopus_deploy_user.md +34 -0
- data/docs/octopus_deploy_worker.md +39 -0
- data/docs/octopus_deploy_worker_pool.md +26 -0
- data/lib/octopus_serverspec_extensions.rb +70 -0
- data/lib/octopus_serverspec_extensions/matcher/allow_dynamic_infrastructure.rb +13 -0
- data/lib/octopus_serverspec_extensions/matcher/use_guided_failure.rb +13 -0
- data/lib/octopus_serverspec_extensions/type/octopus_deploy_account.rb +72 -61
- data/lib/octopus_serverspec_extensions/type/octopus_deploy_environment.rb +70 -11
- data/lib/octopus_serverspec_extensions/type/octopus_deploy_project_group.rb +77 -52
- data/lib/octopus_serverspec_extensions/type/octopus_deploy_smtp_config.rb +109 -0
- data/lib/octopus_serverspec_extensions/type/octopus_deploy_space.rb +92 -0
- data/lib/octopus_serverspec_extensions/type/octopus_deploy_team.rb +82 -0
- data/lib/octopus_serverspec_extensions/type/octopus_deploy_tentacle.rb +7 -8
- data/lib/octopus_serverspec_extensions/type/octopus_deploy_upgrade_config.rb +112 -0
- data/lib/octopus_serverspec_extensions/type/octopus_deploy_user.rb +111 -0
- data/lib/octopus_serverspec_extensions/type/octopus_deploy_worker.rb +173 -0
- data/lib/octopus_serverspec_extensions/type/octopus_deploy_worker_pool.rb +33 -3
- data/lib/octopus_serverspec_extensions/version.rb +1 -1
- metadata +25 -3
@@ -0,0 +1,109 @@
|
|
1
|
+
require 'serverspec/type/base'
|
2
|
+
require 'net/http'
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module Serverspec::Type
|
6
|
+
class OctopusDeploySmtpConfig < Base
|
7
|
+
@serverUrl = nil
|
8
|
+
@apiKey = nil
|
9
|
+
@smtpConfig = nil
|
10
|
+
|
11
|
+
def initialize(*url_and_api_key)
|
12
|
+
serverUrl, apiKey = get_octopus_creds(url_and_api_key)
|
13
|
+
|
14
|
+
@name = "Octopus Deploy SMTP Config #{serverUrl}"
|
15
|
+
@runner = Specinfra::Runner
|
16
|
+
@serverUrl = serverUrl
|
17
|
+
@apiKey = apiKey
|
18
|
+
|
19
|
+
if serverUrl.nil?
|
20
|
+
serverUrl = get_env_var('OCTOPUS_CLI_SERVER').chomp('/') # removes trailing slash if present
|
21
|
+
end
|
22
|
+
|
23
|
+
if apiKey.nil?
|
24
|
+
apiKey = get_env_var('OCTOPUS_CLI_API_KEY')
|
25
|
+
end
|
26
|
+
|
27
|
+
# is it still nil?
|
28
|
+
if serverUrl.nil?
|
29
|
+
raise "'serverUrl' was not provided. Unable to connect to Octopus server to validate configuration."
|
30
|
+
end
|
31
|
+
if apiKey.nil?
|
32
|
+
raise "'apiKey' was not provided. Unable to connect to Octopus server to validate configuration."
|
33
|
+
end
|
34
|
+
|
35
|
+
@smtpConfig = get_smtp_config_via_api(serverUrl, apiKey)
|
36
|
+
end
|
37
|
+
|
38
|
+
def configured?
|
39
|
+
url = "#{@serverUrl}/api/smtpconfiguration/isconfigured?api-key=#{@apiKey}"
|
40
|
+
begin
|
41
|
+
resp = Net::HTTP.get_response(URI.parse(url))
|
42
|
+
body = JSON.parse(resp.body)
|
43
|
+
smtp = body unless body.nil?
|
44
|
+
rescue => e
|
45
|
+
raise "get_smtp_config_via_api: Unable to connect to #{url}: #{e}"
|
46
|
+
end
|
47
|
+
|
48
|
+
smtp["IsConfigured"]
|
49
|
+
end
|
50
|
+
|
51
|
+
def using_ssl?
|
52
|
+
false if @smtpConfig.nil?
|
53
|
+
@smtpConfig["EnableSsl"]
|
54
|
+
end
|
55
|
+
|
56
|
+
def on_port?(port_number)
|
57
|
+
false if @smtpConfig.nil?
|
58
|
+
@smtpConfig["SmtpPort"] == port_number
|
59
|
+
end
|
60
|
+
|
61
|
+
def on_host?(hostname)
|
62
|
+
false if @smtpConfig.nil?
|
63
|
+
@smtpConfig["SmtpHost"] == hostname
|
64
|
+
end
|
65
|
+
|
66
|
+
def using_credentials?(username)
|
67
|
+
# we can't test the password, but we can check the username
|
68
|
+
false if @smtpConfig.nil?
|
69
|
+
@smtpConfig["SmtpLogin"] == username && @smtpConfig["SmtpPassword"]["HasValue"]
|
70
|
+
end
|
71
|
+
|
72
|
+
def has_from_address?(from_address)
|
73
|
+
false if @smtpConfig.nil?
|
74
|
+
@smtpConfig["SendEmailFrom"] == from_address
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# module-level constructors/entrypoints
|
79
|
+
|
80
|
+
def octopus_deploy_smtp_config(*url_and_api_key)
|
81
|
+
serverUrl, apiKey = get_octopus_creds(url_and_api_key)
|
82
|
+
OctopusDeploySmtpConfig.new(serverUrl, apiKey)
|
83
|
+
end
|
84
|
+
|
85
|
+
def octopus_smtp_config(*url_and_api_key)
|
86
|
+
serverUrl, apiKey = get_octopus_creds(url_and_api_key)
|
87
|
+
octopus_deploy_smtp_config(serverUrl, apiKey)
|
88
|
+
end
|
89
|
+
|
90
|
+
private
|
91
|
+
|
92
|
+
def get_smtp_config_via_api(serverUrl, apiKey)
|
93
|
+
smtp = nil
|
94
|
+
|
95
|
+
url = "#{serverUrl}/api/smtpconfiguration?api-key=#{apiKey}"
|
96
|
+
|
97
|
+
begin
|
98
|
+
resp = Net::HTTP.get_response(URI.parse(url))
|
99
|
+
body = JSON.parse(resp.body)
|
100
|
+
smtp = body unless body.nil?
|
101
|
+
rescue => e
|
102
|
+
raise "get_smtp_config_via_api: Unable to connect to #{url}: #{e}"
|
103
|
+
end
|
104
|
+
|
105
|
+
smtp
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
include Serverspec::Type
|
@@ -0,0 +1,92 @@
|
|
1
|
+
require 'serverspec/type/base'
|
2
|
+
require 'net/http'
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module Serverspec::Type
|
6
|
+
class OctopusDeploySpace < Base
|
7
|
+
@serverUrl = nil
|
8
|
+
@apiKey = nil
|
9
|
+
@spaceName = nil
|
10
|
+
@space = nil
|
11
|
+
|
12
|
+
def initialize(*url_and_api_key, space_name)
|
13
|
+
serverUrl, apiKey = get_octopus_creds(url_and_api_key)
|
14
|
+
|
15
|
+
@name = "Octopus Deploy Space #{space_name}"
|
16
|
+
@runner = Specinfra::Runner
|
17
|
+
@serverUrl = serverUrl
|
18
|
+
@apiKey = apiKey
|
19
|
+
|
20
|
+
if space_name.nil?
|
21
|
+
raise "'space_name' was not included. Cannot contact server to validate space."
|
22
|
+
end
|
23
|
+
|
24
|
+
@spaceName = space_name
|
25
|
+
end
|
26
|
+
|
27
|
+
def exists?
|
28
|
+
load_resource_if_nil
|
29
|
+
@space.nil? == false
|
30
|
+
end
|
31
|
+
|
32
|
+
def default?
|
33
|
+
load_resource_if_nil
|
34
|
+
false if @space.nil?
|
35
|
+
@space['IsDefault'] == true
|
36
|
+
end
|
37
|
+
|
38
|
+
def has_running_task_queue?
|
39
|
+
load_resource_if_nil
|
40
|
+
false if @space.nil?
|
41
|
+
@space['TaskQueueStopped'] == false
|
42
|
+
end
|
43
|
+
|
44
|
+
def has_description?(description)
|
45
|
+
load_resource_if_nil
|
46
|
+
false if @space.nil?
|
47
|
+
@space['Description'] == description
|
48
|
+
end
|
49
|
+
|
50
|
+
def load_resource_if_nil
|
51
|
+
if @space.nil?
|
52
|
+
@space = get_space_via_api
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# module-level constructors/entrypoints
|
58
|
+
|
59
|
+
def octopus_deploy_space(*url_and_api_key, space_name)
|
60
|
+
serverUrl, apiKey = get_octopus_creds(url_and_api_key)
|
61
|
+
OctopusDeploySpace.new(serverUrl, apiKey, space_name)
|
62
|
+
end
|
63
|
+
|
64
|
+
def octopus_space(*url_and_api_key, space_name)
|
65
|
+
serverUrl, apiKey = get_octopus_creds(url_and_api_key)
|
66
|
+
OctopusDeploySpace.new(serverUrl, apiKey, space_name)
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
def get_space_via_api
|
72
|
+
space = nil
|
73
|
+
|
74
|
+
@serverSupportsSpaces = check_supports_spaces(@serverUrl)
|
75
|
+
|
76
|
+
unless @serverSupportsSpaces
|
77
|
+
raise "Server does not support Spaces"
|
78
|
+
end
|
79
|
+
|
80
|
+
url = "#{@serverUrl}/api/Spaces/all?api-key=#{@apiKey}"
|
81
|
+
|
82
|
+
begin
|
83
|
+
resp = Net::HTTP.get_response(URI.parse(url))
|
84
|
+
body = JSON.parse(resp.body)
|
85
|
+
space = body.select {|i| i['Name'] == @spaceName }.first unless body.nil?
|
86
|
+
rescue => e
|
87
|
+
raise "get_account_via_api: Unable to connect to #{url}: #{e}"
|
88
|
+
end
|
89
|
+
|
90
|
+
space
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'serverspec/type/base'
|
2
|
+
require 'net/http'
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module Serverspec::Type
|
6
|
+
class OctopusDeployTeam < Base
|
7
|
+
@team_name = nil
|
8
|
+
@serverUrl = nil
|
9
|
+
@apiKey = nil
|
10
|
+
@serverSupportsSpaces = false
|
11
|
+
@team = nil
|
12
|
+
@spaceId = nil
|
13
|
+
|
14
|
+
def initialize(*url_and_api_key, team_name)
|
15
|
+
serverUrl,apiKey = get_octopus_creds(url_and_api_key)
|
16
|
+
|
17
|
+
@team_name = team_name
|
18
|
+
|
19
|
+
@name = "Octopus Deploy User Account #{serverUrl}"
|
20
|
+
@runner = Specinfra::Runner
|
21
|
+
@serverUrl = serverUrl
|
22
|
+
@apiKey = apiKey
|
23
|
+
|
24
|
+
if team_name.nil?
|
25
|
+
raise "'team_name' was not provided"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def exists?
|
30
|
+
load_resource_if_nil
|
31
|
+
@team != nil?
|
32
|
+
end
|
33
|
+
|
34
|
+
def in_space(space_name)
|
35
|
+
# allows us to tag .in_space() onto the end of the resource. as in
|
36
|
+
# describe octopus_account("account name").in_space("MyNewSpace") do
|
37
|
+
@spaceId = get_space_id?(space_name)
|
38
|
+
if @team_name.nil?
|
39
|
+
raise "'team_name' was not provided. Unable to connect to Octopus server to validate configuration."
|
40
|
+
end
|
41
|
+
self
|
42
|
+
end
|
43
|
+
|
44
|
+
def load_resource_if_nil
|
45
|
+
if @team.nil?
|
46
|
+
@team = get_team_via_api(@serverUrl, @apiKey, @team_name)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def octopus_deploy_team(*url_and_api_key, team_name)
|
52
|
+
serverUrl,apiKey = get_octopus_creds(url_and_api_key)
|
53
|
+
OctopusDeployTeam.new(serverUrl, apiKey, team_name)
|
54
|
+
end
|
55
|
+
|
56
|
+
def octopus_team(*url_and_api_key, team_name)
|
57
|
+
serverUrl,apiKey = get_octopus_creds(url_and_api_key)
|
58
|
+
OctopusDeployTeam.new(serverUrl, apiKey, team_name)
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
def get_team_via_api(serverUrl, apiKey, team_name)
|
64
|
+
team = nil
|
65
|
+
|
66
|
+
url = "#{serverUrl}/api#{@spaceFragment}/teams/all?api-key=#{apiKey}"
|
67
|
+
|
68
|
+
begin
|
69
|
+
resp = Net::HTTP.get_response(URI.parse(url))
|
70
|
+
body = JSON.parse(resp.body)
|
71
|
+
teams = body unless body.nil?
|
72
|
+
team = teams.select {|i| i['Name'] == team_name }.first unless teams.nil?
|
73
|
+
rescue => e
|
74
|
+
raise "get_team_via_api: Unable to connect to #{url}: #{e}"
|
75
|
+
end
|
76
|
+
|
77
|
+
team
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
include Serverspec::Type
|
@@ -20,12 +20,10 @@ module Serverspec::Type
|
|
20
20
|
@spaceId = spaceId
|
21
21
|
|
22
22
|
if (serverUrl.nil?)
|
23
|
-
|
24
|
-
return
|
23
|
+
raise "'serverUrl' was not provided. Unable to connect to Octopus server to validate configuration."
|
25
24
|
end
|
26
25
|
if (apiKey.nil?)
|
27
|
-
|
28
|
-
return
|
26
|
+
raise "'apiKey' was not provided. Unable to connect to Octopus server to validate configuration."
|
29
27
|
end
|
30
28
|
|
31
29
|
if (exists?)
|
@@ -43,7 +41,7 @@ module Serverspec::Type
|
|
43
41
|
|
44
42
|
@machine = get_machine_via_api(serverUrl, apiKey, thumbprint)
|
45
43
|
else
|
46
|
-
|
44
|
+
raise "tentacle.exe does not exist"
|
47
45
|
end
|
48
46
|
end
|
49
47
|
|
@@ -77,7 +75,7 @@ module Serverspec::Type
|
|
77
75
|
def in_space?(space_name)
|
78
76
|
return false if @machine.nil?
|
79
77
|
return false if @serverSupportsSpaces
|
80
|
-
url = "#{@serverUrl}/api
|
78
|
+
url = "#{@serverUrl}/api/spaces/all?api-key=#{@apiKey}"
|
81
79
|
resp = Net::HTTP.get_response(URI.parse(url))
|
82
80
|
spaces = JSON.parse(resp.body)
|
83
81
|
space_id = spaces.select {|e| e["Name"] == space_name}.first["Id"]
|
@@ -121,6 +119,7 @@ module Serverspec::Type
|
|
121
119
|
|
122
120
|
def has_endpoint?(uri)
|
123
121
|
return false if @machine.nil?
|
122
|
+
return false if @machine["Uri"].nil? # polling tentacles have null endpoint. catch that.
|
124
123
|
puts "Expected uri '#{uri}' for Tentacle #{@name}, but got '#{@machine["Uri"]}'" unless (@machine["Uri"].casecmp(uri) == 0)
|
125
124
|
@machine["Uri"].casecmp(uri) == 0
|
126
125
|
end
|
@@ -130,13 +129,13 @@ module Serverspec::Type
|
|
130
129
|
@machine["TenantedDeploymentParticipation"] == mode
|
131
130
|
end
|
132
131
|
|
133
|
-
def
|
132
|
+
def listening?
|
134
133
|
return false if @machine.nil?
|
135
134
|
puts "Expected CommunicationStyle 'TentaclePassive' for Tentacle #{@name}, but got '#{@machine["Endpoint"]["CommunicationStyle"]}'" if (@machine["Endpoint"]["CommunicationStyle"] != "TentaclePassive")
|
136
135
|
@machine["Endpoint"]["CommunicationStyle"] == "TentaclePassive"
|
137
136
|
end
|
138
137
|
|
139
|
-
def
|
138
|
+
def polling?
|
140
139
|
return false if @machine.nil?
|
141
140
|
puts "Expected CommunicationStyle 'TentacleActive' for Tentacle #{@name}, but got '#{@machine["Endpoint"]["CommunicationStyle"]}'" if (@machine["Endpoint"]["CommunicationStyle"] != "TentacleActive")
|
142
141
|
@machine["Endpoint"]["CommunicationStyle"] == "TentacleActive"
|
@@ -0,0 +1,112 @@
|
|
1
|
+
require 'serverspec/type/base'
|
2
|
+
require 'net/http'
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module Serverspec::Type
|
6
|
+
class OctopusDeployUpgradeConfig < Base
|
7
|
+
@serverUrl = nil
|
8
|
+
@apiKey = nil
|
9
|
+
@upgradeConfig = nil
|
10
|
+
|
11
|
+
@NotificationModes = ['AlwaysShow', 'ShowOnlyMajorMinor', 'NeverShow']
|
12
|
+
|
13
|
+
def initialize(*url_and_api_key)
|
14
|
+
serverUrl, apiKey = get_octopus_creds(url_and_api_key)
|
15
|
+
|
16
|
+
@name = "Octopus Deploy Upgrade Config #{serverUrl}"
|
17
|
+
@runner = Specinfra::Runner
|
18
|
+
@serverUrl = serverUrl
|
19
|
+
@apiKey = apiKey
|
20
|
+
|
21
|
+
# is it still nil?
|
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
|
+
@upgradeConfig = get_upgrade_config_via_api(serverUrl, apiKey)
|
30
|
+
end
|
31
|
+
|
32
|
+
def has_notification_mode?(mode)
|
33
|
+
false if @upgradeConfig.nil?
|
34
|
+
@upgradeConfig['NotificationMode'] == mode
|
35
|
+
end
|
36
|
+
|
37
|
+
def never_show_notifications?
|
38
|
+
false if @upgradeConfig.nil?
|
39
|
+
has_notification_mode?('NeverShow')
|
40
|
+
end
|
41
|
+
|
42
|
+
def always_show_notifications?
|
43
|
+
false if @upgradeConfig.nil?
|
44
|
+
has_notification_mode?('AlwaysShow')
|
45
|
+
end
|
46
|
+
|
47
|
+
def show_major_minor_notifications?
|
48
|
+
false if @upgradeConfig.nil?
|
49
|
+
has_notification_mode?('ShowOnlyMajorMinor')
|
50
|
+
end
|
51
|
+
|
52
|
+
def include_statistics?
|
53
|
+
false if @upgradeConfig.nil?
|
54
|
+
@upgradeConfig['IncludeStatistics'] == true
|
55
|
+
end
|
56
|
+
|
57
|
+
def allow_checking?
|
58
|
+
false if @upgradeConfig.nil?
|
59
|
+
@upgradeConfig['AllowChecking'] == true
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# module-level constructors/entrypoints
|
64
|
+
|
65
|
+
def octopus_deploy_upgrade_config(*url_and_api_key)
|
66
|
+
serverUrl, apiKey = get_octopus_creds(url_and_api_key)
|
67
|
+
OctopusDeployUpgradeConfig.new(serverUrl, apiKey)
|
68
|
+
end
|
69
|
+
|
70
|
+
def octopus_upgrade_config(*url_and_api_key)
|
71
|
+
serverUrl, apiKey = get_octopus_creds(url_and_api_key)
|
72
|
+
octopus_deploy_upgrade_config(serverUrl, apiKey)
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
def get_upgrade_config_endpoint(serverUrl)
|
78
|
+
endpoint = nil
|
79
|
+
|
80
|
+
url = "#{serverUrl}/api/"
|
81
|
+
|
82
|
+
begin
|
83
|
+
resp = Net::HTTP.get_response(URI.parse(url))
|
84
|
+
body = JSON.parse(resp.body)
|
85
|
+
json = body unless body.nil?
|
86
|
+
endpoint = json['Links']['UpgradeConfiguration']
|
87
|
+
rescue => e
|
88
|
+
raise "get_upgrade_config_endpoint: Unable to connect to #{url}: #{e}"
|
89
|
+
end
|
90
|
+
|
91
|
+
endpoint
|
92
|
+
end
|
93
|
+
|
94
|
+
def get_upgrade_config_via_api(serverUrl, apiKey)
|
95
|
+
smtp = nil
|
96
|
+
|
97
|
+
stem = get_upgrade_config_endpoint(serverUrl)
|
98
|
+
url = "#{serverUrl}#{stem}?api-key=#{apiKey}"
|
99
|
+
|
100
|
+
begin
|
101
|
+
resp = Net::HTTP.get_response(URI.parse(url))
|
102
|
+
body = JSON.parse(resp.body)
|
103
|
+
smtp = body unless body.nil?
|
104
|
+
rescue => e
|
105
|
+
raise "get_upgrade_config_via_api: Unable to connect to #{url}: #{e}"
|
106
|
+
end
|
107
|
+
|
108
|
+
smtp
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
include Serverspec::Type
|