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.
Files changed (30) hide show
  1. checksums.yaml +4 -4
  2. data/docs/authentication.md +45 -0
  3. data/docs/octopus_deploy_account.md +37 -0
  4. data/docs/octopus_deploy_doc_template.md +17 -0
  5. data/docs/octopus_deploy_environment.md +33 -0
  6. data/docs/octopus_deploy_project_group.md +31 -0
  7. data/docs/octopus_deploy_smtp_config.md +39 -0
  8. data/docs/octopus_deploy_space.md +32 -0
  9. data/docs/octopus_deploy_team.md +26 -0
  10. data/docs/octopus_deploy_tentacle.md +41 -0
  11. data/docs/octopus_deploy_upgrade_config.md +34 -0
  12. data/docs/octopus_deploy_user.md +34 -0
  13. data/docs/octopus_deploy_worker.md +39 -0
  14. data/docs/octopus_deploy_worker_pool.md +26 -0
  15. data/lib/octopus_serverspec_extensions.rb +70 -0
  16. data/lib/octopus_serverspec_extensions/matcher/allow_dynamic_infrastructure.rb +13 -0
  17. data/lib/octopus_serverspec_extensions/matcher/use_guided_failure.rb +13 -0
  18. data/lib/octopus_serverspec_extensions/type/octopus_deploy_account.rb +72 -61
  19. data/lib/octopus_serverspec_extensions/type/octopus_deploy_environment.rb +70 -11
  20. data/lib/octopus_serverspec_extensions/type/octopus_deploy_project_group.rb +77 -52
  21. data/lib/octopus_serverspec_extensions/type/octopus_deploy_smtp_config.rb +109 -0
  22. data/lib/octopus_serverspec_extensions/type/octopus_deploy_space.rb +92 -0
  23. data/lib/octopus_serverspec_extensions/type/octopus_deploy_team.rb +82 -0
  24. data/lib/octopus_serverspec_extensions/type/octopus_deploy_tentacle.rb +7 -8
  25. data/lib/octopus_serverspec_extensions/type/octopus_deploy_upgrade_config.rb +112 -0
  26. data/lib/octopus_serverspec_extensions/type/octopus_deploy_user.rb +111 -0
  27. data/lib/octopus_serverspec_extensions/type/octopus_deploy_worker.rb +173 -0
  28. data/lib/octopus_serverspec_extensions/type/octopus_deploy_worker_pool.rb +33 -3
  29. data/lib/octopus_serverspec_extensions/version.rb +1 -1
  30. 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
- puts "'serverUrl' was not provided. Unable to connect to Octopus server to validate configuration."
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
- puts "'apiKey' was not provided. Unable to connect to Octopus server to validate configuration."
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
- puts "tentacle.exe does not exist"
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/#{@spaceFragment}spaces/all?api-key=#{@apiKey}"
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 listening_tentacle?
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 polling_tentacle?
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