serverspec-extra-types 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +13 -0
  3. data/.rspec +3 -0
  4. data/.rubocop.yml +6 -0
  5. data/.travis.yml +7 -0
  6. data/CODE_OF_CONDUCT.md +74 -0
  7. data/Gemfile +6 -0
  8. data/LICENSE.txt +21 -0
  9. data/README.md +191 -0
  10. data/Rakefile +7 -0
  11. data/bin/console +14 -0
  12. data/bin/setup +8 -0
  13. data/lib/serverspec_extra_types.rb +3 -0
  14. data/lib/serverspec_extra_types/helpers/properties.rb +11 -0
  15. data/lib/serverspec_extra_types/matchers.rb +34 -0
  16. data/lib/serverspec_extra_types/matchers/be_a_manager_node.rb +15 -0
  17. data/lib/serverspec_extra_types/matchers/be_a_worker_node.rb +14 -0
  18. data/lib/serverspec_extra_types/matchers/be_active.rb +11 -0
  19. data/lib/serverspec_extra_types/matchers/configure_queue.rb +8 -0
  20. data/lib/serverspec_extra_types/matchers/have_count.rb +11 -0
  21. data/lib/serverspec_extra_types/matchers/have_domain_name.rb +10 -0
  22. data/lib/serverspec_extra_types/matchers/have_engine_version.rb +11 -0
  23. data/lib/serverspec_extra_types/matchers/have_environment_variable.rb +21 -0
  24. data/lib/serverspec_extra_types/matchers/have_ha_mode.rb +5 -0
  25. data/lib/serverspec_extra_types/matchers/have_ha_nodes.rb +8 -0
  26. data/lib/serverspec_extra_types/matchers/have_ha_sync_mode.rb +5 -0
  27. data/lib/serverspec_extra_types/matchers/have_host.rb +8 -0
  28. data/lib/serverspec_extra_types/matchers/have_hostname.rb +6 -0
  29. data/lib/serverspec_extra_types/matchers/have_image.rb +8 -0
  30. data/lib/serverspec_extra_types/matchers/have_image_sha.rb +5 -0
  31. data/lib/serverspec_extra_types/matchers/have_label.rb +20 -0
  32. data/lib/serverspec_extra_types/matchers/have_mount.rb +11 -0
  33. data/lib/serverspec_extra_types/matchers/have_network.rb +8 -0
  34. data/lib/serverspec_extra_types/matchers/have_placement_constraint.rb +8 -0
  35. data/lib/serverspec_extra_types/matchers/have_replica_count.rb +8 -0
  36. data/lib/serverspec_extra_types/matchers/have_restart_limit.rb +8 -0
  37. data/lib/serverspec_extra_types/matchers/have_restart_policy.rb +8 -0
  38. data/lib/serverspec_extra_types/matchers/have_user.rb +10 -0
  39. data/lib/serverspec_extra_types/matchers/have_vhost.rb +5 -0
  40. data/lib/serverspec_extra_types/matchers/include_regex.rb +5 -0
  41. data/lib/serverspec_extra_types/matchers/map_port.rb +25 -0
  42. data/lib/serverspec_extra_types/matchers/mirror_all.rb +5 -0
  43. data/lib/serverspec_extra_types/matchers/publish_all_ports.rb +3 -0
  44. data/lib/serverspec_extra_types/matchers/read_from_queue.rb +8 -0
  45. data/lib/serverspec_extra_types/matchers/write_to_queue.rb +8 -0
  46. data/lib/serverspec_extra_types/types.rb +18 -0
  47. data/lib/serverspec_extra_types/types/api_base.rb +36 -0
  48. data/lib/serverspec_extra_types/types/consul_base.rb +40 -0
  49. data/lib/serverspec_extra_types/types/consul_node.rb +20 -0
  50. data/lib/serverspec_extra_types/types/consul_node_list.rb +32 -0
  51. data/lib/serverspec_extra_types/types/consul_service.rb +24 -0
  52. data/lib/serverspec_extra_types/types/consul_service_list.rb +32 -0
  53. data/lib/serverspec_extra_types/types/docker_container.rb +124 -0
  54. data/lib/serverspec_extra_types/types/docker_node.rb +41 -0
  55. data/lib/serverspec_extra_types/types/docker_service.rb +121 -0
  56. data/lib/serverspec_extra_types/types/rabbitmq_base.rb +38 -0
  57. data/lib/serverspec_extra_types/types/rabbitmq_node_list.rb +18 -0
  58. data/lib/serverspec_extra_types/types/rabbitmq_user_permission.rb +39 -0
  59. data/lib/serverspec_extra_types/types/rabbitmq_vhost_list.rb +22 -0
  60. data/lib/serverspec_extra_types/types/rabbitmq_vhost_policy.rb +57 -0
  61. data/lib/serverspec_extra_types/version.rb +3 -0
  62. data/properties.yml +23 -0
  63. data/serverspec-extra-types.gemspec +36 -0
  64. metadata +232 -0
@@ -0,0 +1,32 @@
1
+ require 'serverspec_extra_types/types/consul_base'
2
+
3
+
4
+ # TODO: List and singular
5
+ module Serverspec::Type
6
+ class ConsulNodeList < ConsulBase
7
+
8
+ def url
9
+ "#{@url_base}/v1/catalog/nodes"
10
+ end
11
+
12
+ def to_s
13
+ msg = "Consul Node List"
14
+ msg << %( with acl token: "#{@token}") if @token
15
+ msg
16
+ end
17
+
18
+ def has_node?(node)
19
+ nodes.include? node
20
+ end
21
+
22
+ def nodes
23
+ inspection.keys
24
+ end
25
+
26
+ def inspection
27
+ @inspection ||= ::MultiJson.load(get_inspection.stdout)
28
+ end
29
+
30
+
31
+ end
32
+ end
@@ -0,0 +1,24 @@
1
+ require 'serverspec_extra_types/types/consul_base'
2
+
3
+
4
+ # TODO: List and singular
5
+ module Serverspec::Type
6
+ class ConsulService < ConsulBase
7
+
8
+ def url
9
+ "#{@url_base}/v1/catalog/service/#{@name}"
10
+ end
11
+
12
+ def to_s
13
+ msg = "Consul Service #{@name}"
14
+ msg << %( with acl token: "#{@token}") if @token
15
+ msg
16
+ end
17
+
18
+ def inspection
19
+ @inspection ||= ::MultiJson.load(get_inspection.stdout)
20
+ end
21
+
22
+
23
+ end
24
+ end
@@ -0,0 +1,32 @@
1
+ require 'serverspec_extra_types/types/consul_base'
2
+
3
+
4
+ # TODO: List and singular
5
+ module Serverspec::Type
6
+ class ConsulServiceList < ConsulBase
7
+
8
+ def url
9
+ "#{@url_base}/v1/catalog/services"
10
+ end
11
+
12
+ def to_s
13
+ msg = "Consul Service List"
14
+ msg << %( with acl token: "#{@token}") if @token
15
+ msg
16
+ end
17
+
18
+ def has_service?(service)
19
+ services.include? service
20
+ end
21
+
22
+ def services
23
+ inspection.keys
24
+ end
25
+
26
+ def inspection
27
+ @inspection ||= ::MultiJson.load(get_inspection.stdout)
28
+ end
29
+
30
+
31
+ end
32
+ end
@@ -0,0 +1,124 @@
1
+ require 'serverspec'
2
+
3
+ module Serverspec::Type
4
+ # This class monkey patches serverspec's docker container type with some more method to be used in matchers
5
+ class DockerContainer
6
+ def include_regex?
7
+ inspection.find { |str| str =~ regex }
8
+ end
9
+
10
+ def has_image?(image)
11
+ self.image == image
12
+ end
13
+
14
+ def has_image_sha?(image)
15
+ self.image_sha == image
16
+ end
17
+
18
+ def image
19
+ inspection['Config']['Image'].split('@')[0]
20
+ end
21
+
22
+ def image_sha
23
+ inspection['Config']['Image'].split('@')[1]
24
+ end
25
+
26
+ def has_environment_variable?(regex, value = nil)
27
+ if value
28
+ environment_variable(regex) == value
29
+ else
30
+ environment_variable(regex)
31
+ end
32
+
33
+ end
34
+
35
+ def environment_variable(regex)
36
+ environment_variables.find { |str| str =~ /^#{regex}=/ }.split('=')[1]
37
+ end
38
+
39
+ def environment_variables
40
+ inspection['Config']['Env']
41
+ end
42
+
43
+ def has_user?(user)
44
+ self.user == user
45
+ end
46
+
47
+ def user
48
+ inspection['Config']['User']
49
+ end
50
+
51
+ def has_hostname?(hostname)
52
+ self.hostname == hostname
53
+ end
54
+
55
+ def hostname
56
+ inspection['Config']['Hostname']
57
+ end
58
+
59
+ def has_domainname?(domain)
60
+ self.domain_name == domain
61
+ end
62
+
63
+ def domain_name
64
+ inspection['Config']['Domainname']
65
+ end
66
+
67
+ def has_restart_limit?(limit)
68
+ restart_limit == limit
69
+ end
70
+
71
+ def restart_limit
72
+ inspection['HostConfig']['RestartPolicy']['MaximumRetryCount']
73
+ end
74
+
75
+ def has_restart_policy?(policy)
76
+ restart_policy == policy
77
+ end
78
+
79
+ def restart_policy
80
+ inspection['HostConfig']['RestartPolicy']['Name']
81
+ end
82
+ def has_host?(host)
83
+ hosts.include? host
84
+ end
85
+ def hosts
86
+ inspection['HostConfig']['ExtraHosts'].map {|itm| itm.split(':')[1] + ' ' + itm.split(':')[0]}
87
+ end
88
+
89
+ def privileged?
90
+ inspection['HostConfig']['Privileged']
91
+ end
92
+
93
+ # TODO: matcher for this
94
+ def publishes_all_ports?
95
+ inspection['HostConfig']['PublishAllPorts']
96
+ end
97
+
98
+
99
+ def map_port?(host, container, protocol = 'tcp')
100
+ inspection['NetworkSettings']['Ports']["#{container}/#{protocol}"][0]['HostPort'] == host
101
+ end
102
+
103
+ def port_map
104
+ inspection['HostConfig']['PortBindings']
105
+ end
106
+
107
+ def has_mount?(source, target, type)
108
+ mounts.find { |mount| mount['Source'] == source && mount['Destination'] == target && mount['Type'] == type }
109
+ end
110
+
111
+ def mounts
112
+ inspection['Mounts']
113
+ end
114
+
115
+ # TODO: matcher for volumes
116
+
117
+ private
118
+
119
+ def get_inspection
120
+ @containers ||= @name.include?('=') ? @runner.run_command("docker ps -qa -f #{@name}").stdout : @name
121
+ @get_inspection ||= @runner.run_command("docker inspect #{@containers}")
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,41 @@
1
+ module Serverspec::Type
2
+ class DockerNode < DockerBase
3
+
4
+ def active?
5
+ availability == 'active'
6
+ end
7
+
8
+ def availability
9
+ inspection['Spec']['Availability']
10
+ end
11
+
12
+ def role
13
+ inspection['Spec']['Role']
14
+ end
15
+
16
+ def manager?
17
+ role == 'manager'
18
+ end
19
+
20
+ def worker?
21
+ role == 'worker'
22
+ end
23
+
24
+ def labels
25
+ inspection['Spec']['Labels']
26
+ end
27
+
28
+ def has_engine_version?(version)
29
+ engine_version == version
30
+ end
31
+
32
+ def engine_version
33
+ inspection['Description']['Engine']['EngineVersion']
34
+ end
35
+ private
36
+
37
+ def get_inspection
38
+ @get_inspection ||= @runner.run_command("docker service inspect #{@name}")
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,121 @@
1
+ require 'serverspec'
2
+ require 'serverspec/type/base'
3
+ require 'serverspec/type/docker_base'
4
+
5
+ module Serverspec::Type
6
+ class DockerService < DockerBase
7
+ def exist?
8
+ get_inspection.success?
9
+ end
10
+
11
+ def has_restart_policy?(policy)
12
+ restart_policy == policy
13
+ end
14
+
15
+ def has_restart_limit?(limit)
16
+ restart_limit == limit
17
+ end
18
+
19
+ def restart_policy
20
+ inspection['Spec']['TaskTemplate']['RestartPolicy']['Condition']
21
+ end
22
+
23
+ def restart_limit
24
+ inspection['Spec']['TaskTemplate']['RestartPolicy']['MaxAttempts']
25
+ end
26
+
27
+ def has_image?(image)
28
+ self.image == image
29
+ end
30
+
31
+ def has_image_sha?(image)
32
+ self.image == image
33
+ end
34
+
35
+ def image
36
+ inspection['Spec']['TaskTemplate']['ContainerSpec']['Image'].split('@')[0]
37
+ end
38
+
39
+ def image_sha
40
+ inspection['Spec']['TaskTemplate']['ContainerSpec']['Image'].split('@')[1]
41
+ end
42
+
43
+ def has_user?(user)
44
+ self.user == user
45
+ end
46
+
47
+ def user
48
+ inspection['Spec']['TaskTemplate']['ContainerSpec']['User']
49
+ end
50
+
51
+ def has_mount?(source, target, type)
52
+ mounts.find do |mount|
53
+ mount['Source'] == source && mount['Target'] == target && mount['Type'] == type
54
+ end
55
+ end
56
+
57
+ def mounts
58
+ inspection['Spec']['TaskTemplate']['ContainerSpec']['Mounts']
59
+ end
60
+
61
+ def has_host?(host)
62
+ hosts.include? host
63
+ end
64
+
65
+ def hosts
66
+ inspection['Spec']['TaskTemplate']['ContainerSpec']['Hosts']
67
+ end
68
+
69
+ def has_placement_constraint?(constraint)
70
+ placement_constraints.include? constraint
71
+ end
72
+
73
+ def placement_constraints
74
+ inspection['Spec']['TaskTemplate']['Placement']['Constraints']
75
+ end
76
+
77
+ def replicated?
78
+ inspection['Spec']['Mode']['Replicated']
79
+ end
80
+
81
+ def replicas
82
+ ['Spec']['Mode']['Replicated']['Replicas']
83
+ end
84
+ def global?
85
+ inspection['Spec']['Mode']['Global']
86
+ end
87
+
88
+ def replicas
89
+ inspection['Spec']['Mode']['Replicated']['Replicas']
90
+ end
91
+
92
+ def networks
93
+ inspection['Spec']['TaskTemplate']['Networks']
94
+ end
95
+
96
+ def has_network?(name)
97
+ networks.find { |network| network['Aliases'].include? name }
98
+ end
99
+
100
+ def port_map
101
+ inspection['Spec']['EndpointSpec']['Ports']
102
+ end
103
+
104
+ def map_port?(published, target, protocol = 'tcp',mode = 'ingress')
105
+ port_map.find do |port|
106
+ port['PublishedPort'] == published.to_i &&
107
+ port['TargetPort'] == target.to_i && port['PublishMode'] == mode &&
108
+ port['Protocol'] == protocol
109
+ end
110
+ end
111
+
112
+
113
+ private
114
+
115
+ def get_inspection
116
+ @get_inspection ||= @runner.run_command("docker service inspect #{@name}")
117
+ end
118
+ end
119
+ end
120
+
121
+ include Serverspec::Type
@@ -0,0 +1,38 @@
1
+ require 'serverspec'
2
+ require 'serverspec/type/base'
3
+ require 'multi_json'
4
+ require 'serverspec_extra_types/helpers/properties'
5
+ require 'serverspec_extra_types/types/api_base'
6
+
7
+ module Serverspec::Type
8
+ class RabbitmqBase < ApiBase
9
+ def initialize(name = nil, options = {})
10
+ super(name, options)
11
+ @user = ENV['RABBITMQ_USER'] || 'guest'
12
+ @password = ENV['RABBITMQ_PASSWORD'] || 'guest'
13
+ @url_base = property[:variables][:rabbitmq_url] || 'http://localhost:15672'
14
+ end
15
+
16
+
17
+ def inspection
18
+ @inspection ||= ::MultiJson.load(get_inspection.stdout)[0]
19
+ end
20
+
21
+ def length
22
+ if inspection.is_a? String
23
+ inspection.length
24
+ elsif inspection.kind_of? Array
25
+ inspection.length
26
+ else
27
+ 1
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ def get_inspection
34
+ command = "curl -s -u #{@user}:#{@password} #{url}"
35
+ @get_inspection ||= @runner.run_command(command)
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,18 @@
1
+ require 'serverspec_extra_types/types/rabbitmq_base'
2
+
3
+ module Serverspec::Type
4
+ class RabbitmqNodeList < RabbitmqBase
5
+
6
+ def url
7
+ "#{@url_base}/api/vhosts"
8
+ end
9
+
10
+
11
+
12
+ def inspection
13
+ @inspection ||= ::MultiJson.load(get_inspection.stdout)
14
+ end
15
+
16
+
17
+ end
18
+ end
@@ -0,0 +1,39 @@
1
+ require 'serverspec_extra_types/types/rabbitmq_base'
2
+
3
+ module Serverspec::Type
4
+ class RabbitmqUserPermission < RabbitmqBase
5
+
6
+ def url
7
+ "#{@url_base}/api/users/#{name}/permissions"
8
+ end
9
+
10
+ def read_from_queue?(vhost, queue)
11
+ queue.match read_permissions(vhost)
12
+ end
13
+
14
+ def write_to_queue?(vhost, queue)
15
+ queue.match write_permissions(vhost)
16
+ end
17
+
18
+ def configure_queue?(vhost, queue)
19
+ queue.match configure_permissions(vhost)
20
+ end
21
+
22
+ def read_permissions(vhost)
23
+ inspection.find { |item| item['vhost'] == vhost}['read']
24
+ end
25
+
26
+ def write_permissions(vhost)
27
+ inspection.find { |item| item['vhost'] == vhost}['write']
28
+ end
29
+
30
+ def configure_permissions(vhost)
31
+ inspection.find { |item| item['vhost'] == vhost}['configure']
32
+ end
33
+
34
+ def inspection
35
+ @inspection ||= ::MultiJson.load(get_inspection.stdout)
36
+ end
37
+
38
+ end
39
+ end