serverspec-extra-types 0.3.3 → 0.4.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 (78) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -1
  3. data/.rspec +0 -0
  4. data/.rubocop.yml +0 -0
  5. data/.travis.yml +0 -0
  6. data/CODE_OF_CONDUCT.md +0 -0
  7. data/Gemfile +0 -0
  8. data/LICENSE.txt +0 -0
  9. data/README.md +657 -4
  10. data/Rakefile +0 -0
  11. data/bin/consul_gen.rb +115 -0
  12. data/bin/http_doc_gem.rb +67 -0
  13. data/http_matchers.md +1771 -0
  14. data/lib/serverspec_extra_types.rb +0 -0
  15. data/lib/serverspec_extra_types/helpers/properties.rb +0 -0
  16. data/lib/serverspec_extra_types/matchers.rb +4 -0
  17. data/lib/serverspec_extra_types/matchers/allowed_to_run_anything.rb +38 -0
  18. data/lib/serverspec_extra_types/matchers/allowed_to_run_command.rb +40 -0
  19. data/lib/serverspec_extra_types/matchers/be_a_manager_node.rb +0 -0
  20. data/lib/serverspec_extra_types/matchers/be_a_worker_node.rb +0 -0
  21. data/lib/serverspec_extra_types/matchers/be_active.rb +0 -0
  22. data/lib/serverspec_extra_types/matchers/configure_queue.rb +0 -0
  23. data/lib/serverspec_extra_types/matchers/have_count.rb +0 -0
  24. data/lib/serverspec_extra_types/matchers/have_domain_name.rb +0 -0
  25. data/lib/serverspec_extra_types/matchers/have_engine_version.rb +0 -0
  26. data/lib/serverspec_extra_types/matchers/have_environment_variable.rb +0 -0
  27. data/lib/serverspec_extra_types/matchers/have_ha_mode.rb +0 -0
  28. data/lib/serverspec_extra_types/matchers/have_ha_nodes.rb +0 -0
  29. data/lib/serverspec_extra_types/matchers/have_ha_sync_mode.rb +0 -0
  30. data/lib/serverspec_extra_types/matchers/have_host.rb +0 -0
  31. data/lib/serverspec_extra_types/matchers/have_hostname.rb +0 -0
  32. data/lib/serverspec_extra_types/matchers/have_image.rb +4 -0
  33. data/lib/serverspec_extra_types/matchers/have_image_sha.rb +0 -0
  34. data/lib/serverspec_extra_types/matchers/have_label.rb +0 -0
  35. data/lib/serverspec_extra_types/matchers/have_mount.rb +0 -0
  36. data/lib/serverspec_extra_types/matchers/have_network.rb +0 -0
  37. data/lib/serverspec_extra_types/matchers/have_placement_constraint.rb +0 -0
  38. data/lib/serverspec_extra_types/matchers/have_replica_count.rb +0 -0
  39. data/lib/serverspec_extra_types/matchers/have_restart_limit.rb +0 -0
  40. data/lib/serverspec_extra_types/matchers/have_restart_policy.rb +0 -0
  41. data/lib/serverspec_extra_types/matchers/have_user.rb +0 -0
  42. data/lib/serverspec_extra_types/matchers/have_vhost.rb +0 -0
  43. data/lib/serverspec_extra_types/matchers/http_1xx.rb +0 -0
  44. data/lib/serverspec_extra_types/matchers/http_2xx.rb +0 -0
  45. data/lib/serverspec_extra_types/matchers/http_3xx.rb +0 -0
  46. data/lib/serverspec_extra_types/matchers/http_4xx.rb +0 -0
  47. data/lib/serverspec_extra_types/matchers/http_5xx.rb +0 -0
  48. data/lib/serverspec_extra_types/matchers/include_regex.rb +0 -0
  49. data/lib/serverspec_extra_types/matchers/map_port.rb +0 -0
  50. data/lib/serverspec_extra_types/matchers/mirror_all.rb +0 -0
  51. data/lib/serverspec_extra_types/matchers/publish_all_ports.rb +0 -0
  52. data/lib/serverspec_extra_types/matchers/read_from_queue.rb +0 -0
  53. data/lib/serverspec_extra_types/matchers/url_matchers.rb +0 -0
  54. data/lib/serverspec_extra_types/matchers/write_to_queue.rb +0 -0
  55. data/lib/serverspec_extra_types/types.rb +2 -1
  56. data/lib/serverspec_extra_types/types/api_base.rb +10 -1
  57. data/lib/serverspec_extra_types/types/consul_base.rb +6 -2
  58. data/lib/serverspec_extra_types/types/consul_node.rb +21 -1
  59. data/lib/serverspec_extra_types/types/consul_node_list.rb +1 -1
  60. data/lib/serverspec_extra_types/types/consul_service.rb +188 -1
  61. data/lib/serverspec_extra_types/types/consul_service_list.rb +0 -0
  62. data/lib/serverspec_extra_types/types/curl.rb +5 -1
  63. data/lib/serverspec_extra_types/types/docker_config.rb +55 -0
  64. data/lib/serverspec_extra_types/types/docker_container.rb +0 -0
  65. data/lib/serverspec_extra_types/types/docker_network.rb +74 -1
  66. data/lib/serverspec_extra_types/types/docker_node.rb +12 -0
  67. data/lib/serverspec_extra_types/types/docker_secret.rb +56 -0
  68. data/lib/serverspec_extra_types/types/docker_service.rb +0 -0
  69. data/lib/serverspec_extra_types/types/rabbitmq_base.rb +7 -1
  70. data/lib/serverspec_extra_types/types/rabbitmq_node_list.rb +5 -1
  71. data/lib/serverspec_extra_types/types/rabbitmq_user_permission.rb +0 -0
  72. data/lib/serverspec_extra_types/types/rabbitmq_vhost_list.rb +4 -0
  73. data/lib/serverspec_extra_types/types/rabbitmq_vhost_policy.rb +0 -0
  74. data/lib/serverspec_extra_types/types/sudo_user.rb +90 -0
  75. data/lib/serverspec_extra_types/version.rb +1 -1
  76. data/properties.yml +45 -7
  77. data/serverspec-extra-types.gemspec +4 -1
  78. metadata +55 -5
@@ -44,8 +44,12 @@ module Serverspec::Type
44
44
 
45
45
  private
46
46
 
47
+ def extra_args
48
+ "-w \"#{output_format}\""
49
+ end
50
+
47
51
  def get_inspection
48
- command = "curl -s -w \"#{output_format}\" #{url} #{@insecure ? '-k' : ''} #{@redirects ? '-L' : ''}"
52
+ command = curl_command
49
53
  unless @get_inspection
50
54
  (body, rest) = @runner.run_command(command).stdout.split('!!SS_URL_YAML!!')
51
55
  result = YAML.safe_load(rest).each_with_object({}) { |(k, v), memo| memo[k.to_sym] = v; }
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+ require 'base64'
3
+ module Serverspec::Type
4
+ class DockerConfig < DockerBase
5
+ def exist?
6
+ get_inspection.success?
7
+ end
8
+
9
+ def has_data?(data)
10
+ self.data == data
11
+ end
12
+
13
+ def data
14
+ @data ||= Base64.decode64(data64)
15
+ end
16
+
17
+ def has_data64?(data)
18
+ self.data64 == data
19
+ end
20
+
21
+ def data64
22
+ inspection['Spec']['Data']
23
+ end
24
+
25
+ def labels
26
+ inspection['Spec']['Labels']
27
+ end
28
+
29
+ def has_label?(label, value = nil)
30
+ if value
31
+ label(label)[1] == value
32
+ else
33
+ label(label)
34
+ end
35
+ end
36
+
37
+ def label(label)
38
+ labels.find { |key, _val| key == label }
39
+ end
40
+
41
+ def has_name?(name)
42
+ self.name == name
43
+ end
44
+
45
+ def name
46
+ inspection['Spec']['Name']
47
+ end
48
+
49
+ private
50
+
51
+ def get_inspection
52
+ @get_inspection ||= @runner.run_command("docker config inspect #{@name}")
53
+ end
54
+ end
55
+ end
File without changes
@@ -3,8 +3,9 @@
3
3
  require 'serverspec'
4
4
 
5
5
  module Serverspec::Type
6
- # This class monkey patches serverspec's docker container type with some more method to be used in matchers
6
+
7
7
  class DockerNetwork < DockerBase
8
+
8
9
  def name
9
10
  inspection['Name']
10
11
  end
@@ -13,6 +14,78 @@ module Serverspec::Type
13
14
  inspection['Id']
14
15
  end
15
16
 
17
+ def has_scope?(scope)
18
+ self.scope == scope
19
+ end
20
+
21
+ def scope
22
+ inspection['Scope']
23
+ end
24
+
25
+ def local_scoped?
26
+ scope == 'local'
27
+ end
28
+
29
+ def swarm_scoped?
30
+ scope == 'swarm'
31
+ end
32
+
33
+ def attachable?
34
+ inspection['Scope']
35
+ end
36
+
37
+ def overlay?
38
+ self.has_driver? 'overlay'
39
+ end
40
+
41
+ def bridge?
42
+ self.has_driver? 'bridge'
43
+ end
44
+
45
+ def driver
46
+ inspection['Driver']
47
+ end
48
+
49
+ def has_driver?(driver)
50
+ self.driver == driver
51
+ end
52
+
53
+ def has_label?(label, value = nil)
54
+ if value
55
+ label(label)[1] == value
56
+ else
57
+ label(label)
58
+ end
59
+ end
60
+
61
+ def label(label)
62
+ labels.find { |key, _val| key == label }
63
+ end
64
+
65
+ def labels
66
+ inspection['Labels']
67
+ end
68
+
69
+ def IPv6_enabled?
70
+ inspection['EnableIPv6']
71
+ end
72
+
73
+ def internal?
74
+ inspection['Internal']
75
+ end
76
+
77
+ def external?
78
+ !inspection['Internal']
79
+ end
80
+
81
+ def ingress?
82
+ inspection['Ingress']
83
+ end
84
+
85
+ def exist?
86
+ get_inspection.success?
87
+ end
88
+
16
89
  private
17
90
 
18
91
  def get_inspection
@@ -6,6 +6,15 @@ module Serverspec::Type
6
6
  availability == 'active'
7
7
  end
8
8
 
9
+ def draining?
10
+ availability == 'drain'
11
+ end
12
+
13
+ def paused?
14
+ availability == 'pause'
15
+ end
16
+
17
+
9
18
  def availability
10
19
  inspection['Spec']['Availability']
11
20
  end
@@ -34,6 +43,9 @@ module Serverspec::Type
34
43
  inspection['Description']['Engine']['EngineVersion']
35
44
  end
36
45
 
46
+ def exist?
47
+ get_inspection.success?
48
+ end
37
49
  private
38
50
 
39
51
  def get_inspection
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+ require 'base64'
3
+ module Serverspec::Type
4
+ class DockerSecret < DockerBase
5
+ def exist?
6
+ get_inspection.success?
7
+ end
8
+
9
+ def has_data?(data)
10
+ self.data == data
11
+ end
12
+
13
+ def data
14
+ @data ||= Base64.decode64(data64)
15
+ end
16
+
17
+ def has_data64?(data)
18
+ self.data64 == data
19
+ end
20
+
21
+
22
+ def data64
23
+ inspection['Spec']['Data']
24
+ end
25
+
26
+ def labels
27
+ inspection['Spec']['Labels']
28
+ end
29
+
30
+ def has_label?(label, value = nil)
31
+ if value
32
+ label(label)[1] == value
33
+ else
34
+ label(label)
35
+ end
36
+ end
37
+
38
+ def label(label)
39
+ labels.find { |key, _val| key == label }
40
+ end
41
+
42
+ def has_name?(name)
43
+ self.name == name
44
+ end
45
+
46
+ def name
47
+ inspection['Spec']['Name']
48
+ end
49
+
50
+ private
51
+
52
+ def get_inspection
53
+ @get_inspection ||= @runner.run_command("docker secret inspect #{@name}")
54
+ end
55
+ end
56
+ end
File without changes
@@ -29,10 +29,16 @@ module Serverspec::Type
29
29
  end
30
30
  end
31
31
 
32
+
33
+
32
34
  private
33
35
 
36
+ def extra_args
37
+ "-u #{@user}:#{@password}"
38
+ end
39
+
34
40
  def get_inspection
35
- command = "curl -s -u #{@user}:#{@password} #{url}"
41
+ command = curl_command
36
42
  @get_inspection ||= @runner.run_command(command)
37
43
  end
38
44
  end
@@ -5,7 +5,11 @@ require 'serverspec_extra_types/types/rabbitmq_base'
5
5
  module Serverspec::Type
6
6
  class RabbitmqNodeList < RabbitmqBase
7
7
  def url
8
- "#{@url_base}/api/vhosts"
8
+ "#{@url_base}/api/nodes"
9
+ end
10
+
11
+ def to_s
12
+ "RabbitMQ node list"
9
13
  end
10
14
 
11
15
  def inspection
@@ -8,6 +8,10 @@ module Serverspec::Type
8
8
  inspection.find { |str| str['name'] == vhost }
9
9
  end
10
10
 
11
+ def to_s
12
+ "RabbitMQ VHosts List"
13
+ end
14
+
11
15
  def url
12
16
  "#{@url_base}/api/vhosts"
13
17
  end
@@ -0,0 +1,90 @@
1
+ require 'serverspec'
2
+ require 'serverspec/type/base'
3
+ require 'multi_json'
4
+ require 'serverspec_extra_types/helpers/properties'
5
+
6
+ module Serverspec::Type
7
+ class SudoUser < Base
8
+
9
+ def initialize(name)
10
+ super
11
+ @user = name
12
+ end
13
+
14
+ def exist?
15
+ if get_inspection.success? && /User #{@user} may run the following commands/.match(@get_inspection.stdout)
16
+ true
17
+ else
18
+ false
19
+ end
20
+ end
21
+
22
+
23
+
24
+ def allowed_to_run_command?(command, user = nil, checkpw = false)
25
+ perm = permission(command)
26
+ if user
27
+ if checkpw
28
+ perm[:user] == user && perm[:nopasswd]
29
+ else
30
+ perm[:user] == user
31
+ end
32
+ else
33
+ checkpw ? perm && perm[:nopasswd] : perm
34
+ end
35
+ end
36
+
37
+
38
+
39
+ def permission(command)
40
+ permissions.find {|x| x[:command] == command}
41
+ end
42
+
43
+ def permissions
44
+ inspection[:permissions]
45
+ end
46
+
47
+ def has_sudo_disabled?
48
+ /User #{@user} is not allowed to run sudo/.match(@get_inspection.stdout)
49
+ end
50
+
51
+ def inspection
52
+ @inspection ||= get_sudo_perms(get_inspection.stdout)
53
+ end
54
+
55
+
56
+ private
57
+ def get_inspection
58
+ @get_inspection ||= @runner.run_command("sudo -l -U #{@user}")
59
+ end
60
+
61
+ def chunk_permission(perm)
62
+ chunks = {}
63
+ parts = perm.sub(' : ', ':').split(/\s+/).reject{ |x| x == '' || x == "\n"}
64
+ user = parts[0].sub('(', '').sub(')', '')
65
+ if user.include?(':')
66
+ chunks[:user] = user.split(':')[0]
67
+ chunks[:group] = user.split(':')[1]
68
+ else
69
+ chunks[:user] = user
70
+ end
71
+ if /NOPASSWD:/.match perm
72
+ chunks[:nopasswd] = true
73
+ chunks[:command] = parts[2..-1].join(" ")
74
+ else
75
+ chunks[:nopasswd] = false
76
+ chunks[:command] = parts[1..-1].join(' ')
77
+ end
78
+ chunks
79
+ end
80
+
81
+ def get_sudo_perms(output)
82
+ matches = /Matching Defaults entries for #{@user} on .*\n(.*)\n/.match output
83
+ defaults = matches[1].split(', ').map(&:strip)
84
+ matches = (/User #{@user} may run the following commands on .*\n((\W.*\n)*)/).match output
85
+
86
+ permissions = matches[1].split("\n").map{ |x| chunk_permission(x.strip) }
87
+ { defaults: defaults, permissions: permissions }
88
+ end
89
+ end
90
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ServerspecExtraTypes
4
- VERSION = '0.3.3'
4
+ VERSION = '0.4.0'
5
5
  end
data/properties.yml CHANGED
@@ -2,17 +2,31 @@
2
2
 
3
3
  options:
4
4
  # Stop the test on the first failure (default: true)
5
- fail_on_err: true
5
+ fail_on_err: false
6
6
  # Specify output format defaults is docs_screen multiple formatters can be specified
7
- formaters:
7
+ formatters:
8
8
  - tick
9
9
 
10
10
  targets:
11
11
  # Run tests against a vagrant file
12
- docker:
13
- backend: vagrant
14
- vagrant_dir: spec/vagrant
15
- spec_type: docker
12
+ container:
13
+ backend: exec
14
+ spec_type: docker_container
15
+
16
+ service:
17
+ backend: exec
18
+ spec_type: docker_service
19
+
20
+
21
+ node:
22
+ backend: exec
23
+ spec_type: docker_node
24
+
25
+ network:
26
+ backend: exec
27
+ spec_type: docker_network
28
+
29
+
16
30
 
17
31
  rabbitmq:
18
32
  backend: exec
@@ -20,4 +34,28 @@ targets:
20
34
 
21
35
  consul:
22
36
  backend: exec
23
- spec_type: consul
37
+ spec_type: consul
38
+
39
+
40
+ curl:
41
+ backend: exec
42
+ spec_type: curl
43
+
44
+ secret:
45
+ backend: exec
46
+ spec_type: docker_secret
47
+
48
+ config:
49
+ backend: exec
50
+ spec_type: docker_config
51
+
52
+ sudo:
53
+ backend: docker
54
+ docker_build_dir: spec/resources
55
+ spec_type: sudo
56
+
57
+
58
+ sudo_user:
59
+ backend: docker
60
+ docker_build_dir: spec/resources
61
+ spec_type: sudo_user