arborist 0.2.0.pre20170519125456 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/ChangeLog +670 -1
  5. data/History.md +67 -0
  6. data/Manifest.txt +9 -6
  7. data/README.md +1 -3
  8. data/Rakefile +39 -4
  9. data/TODO.md +22 -31
  10. data/lib/arborist.rb +9 -2
  11. data/lib/arborist/cli.rb +67 -85
  12. data/lib/arborist/client.rb +125 -59
  13. data/lib/arborist/command/ack.rb +86 -0
  14. data/lib/arborist/command/reset.rb +48 -0
  15. data/lib/arborist/command/start.rb +11 -1
  16. data/lib/arborist/command/summary.rb +173 -0
  17. data/lib/arborist/command/tree.rb +215 -0
  18. data/lib/arborist/command/watch.rb +22 -22
  19. data/lib/arborist/dependency.rb +24 -4
  20. data/lib/arborist/event.rb +18 -2
  21. data/lib/arborist/event/node.rb +6 -2
  22. data/lib/arborist/event/node_warn.rb +16 -0
  23. data/lib/arborist/manager.rb +179 -48
  24. data/lib/arborist/mixins.rb +11 -0
  25. data/lib/arborist/monitor.rb +29 -17
  26. data/lib/arborist/monitor/connection_batching.rb +293 -0
  27. data/lib/arborist/monitor/socket.rb +101 -167
  28. data/lib/arborist/monitor_runner.rb +101 -24
  29. data/lib/arborist/node.rb +297 -68
  30. data/lib/arborist/node/ack.rb +1 -1
  31. data/lib/arborist/node/host.rb +26 -5
  32. data/lib/arborist/node/resource.rb +14 -5
  33. data/lib/arborist/node/root.rb +12 -3
  34. data/lib/arborist/node/service.rb +29 -26
  35. data/lib/arborist/node_subscription.rb +65 -0
  36. data/lib/arborist/observer.rb +8 -0
  37. data/lib/arborist/observer/action.rb +6 -0
  38. data/lib/arborist/subscription.rb +22 -16
  39. data/lib/arborist/tree_api.rb +7 -2
  40. data/spec/arborist/client_spec.rb +157 -51
  41. data/spec/arborist/dependency_spec.rb +21 -0
  42. data/spec/arborist/event/node_spec.rb +5 -0
  43. data/spec/arborist/event_spec.rb +3 -3
  44. data/spec/arborist/manager_spec.rb +626 -347
  45. data/spec/arborist/mixins_spec.rb +19 -0
  46. data/spec/arborist/monitor/socket_spec.rb +1 -2
  47. data/spec/arborist/monitor_runner_spec.rb +81 -29
  48. data/spec/arborist/monitor_spec.rb +89 -14
  49. data/spec/arborist/node/host_spec.rb +68 -0
  50. data/spec/arborist/node/resource_spec.rb +2 -0
  51. data/spec/arborist/node/root_spec.rb +13 -0
  52. data/spec/arborist/node/service_spec.rb +9 -0
  53. data/spec/arborist/node_spec.rb +673 -111
  54. data/spec/arborist/node_subscription_spec.rb +54 -0
  55. data/spec/arborist/observer/action_spec.rb +6 -0
  56. data/spec/arborist/observer_runner_spec.rb +8 -1
  57. data/spec/arborist/tree_api_spec.rb +111 -8
  58. data/spec/data/monitors/pings.rb +0 -11
  59. data/spec/data/monitors/port_checks.rb +0 -9
  60. data/spec/data/nodes/sidonie.rb +1 -0
  61. data/spec/data/nodes/vhosts.rb +23 -0
  62. data/spec/data/nodes/yevaud.rb +4 -2
  63. data/spec/spec_helper.rb +71 -1
  64. metadata +91 -28
  65. metadata.gz.sig +0 -0
  66. data/Events.md +0 -35
  67. data/Monitors.md +0 -155
  68. data/Nodes.md +0 -70
  69. data/Observers.md +0 -72
  70. data/Protocol.md +0 -276
  71. data/Tutorial.md +0 -8
@@ -0,0 +1,54 @@
1
+ #!/usr/bin/env rspec -cfd
2
+
3
+ require_relative '../spec_helper'
4
+
5
+ require 'arborist/node_subscription'
6
+
7
+
8
+ describe Arborist::NodeSubscription do
9
+
10
+
11
+ it "can be created with just a node" do
12
+ node = Arborist::Node.create( 'host', 'testy' )
13
+ expect( described_class.new(node) ).to be_a( described_class )
14
+ end
15
+
16
+
17
+ it "raises an error if called with no node" do
18
+ expect {
19
+ described_class.new
20
+ }.to raise_error( ArgumentError )
21
+ end
22
+
23
+
24
+ it "raises an error if called with something that doesn't handle events" do
25
+ expect {
26
+ described_class.new( "hi i'm a little teapot" )
27
+ }.to raise_error( NameError, /handle_event/ )
28
+ end
29
+
30
+
31
+ it "uses its node's identifier for its ID" do
32
+ node = Arborist::Node.create( 'host', 'testy' )
33
+ sub = described_class.new( node )
34
+
35
+ expect( sub.id ).to eq( 'testy-subscription' )
36
+ end
37
+
38
+
39
+ it "matches all events" do
40
+ node = Arborist::Node.create( 'host', 'testy' )
41
+ sub = described_class.new( node )
42
+ events = [
43
+ Arborist::Event.create( 'node_update', node ),
44
+ Arborist::Event.create( 'node_delta', node, status: ['up', 'down'] ),
45
+ Arborist::Event.create( 'node_update', node ),
46
+ Arborist::Event.create( 'node_quieted', node ),
47
+ Arborist::Event.create( 'node_acked', node )
48
+ ]
49
+
50
+ expect( events ).to all( match sub )
51
+ end
52
+
53
+ end
54
+
@@ -47,6 +47,12 @@ describe Arborist::Observer::Action do
47
47
  end
48
48
 
49
49
 
50
+ it "continues through a misbehaving action" do
51
+ action = described_class.new { raise "boom" }
52
+ expect { action.handle_event(event) }.to_not raise_exception
53
+ end
54
+
55
+
50
56
  context "without any other criteria" do
51
57
 
52
58
  before( :each ) do
@@ -14,9 +14,11 @@ describe Arborist::ObserverRunner do
14
14
  before( :each ) do
15
15
  $emails = []
16
16
  $texts = []
17
+ Arborist::Node::Root.reset
17
18
  end
18
19
 
19
20
  after( :each ) do
21
+ Arborist::Node::Root.reset
20
22
  $emails.clear
21
23
  $texts.clear
22
24
  end
@@ -105,7 +107,12 @@ describe Arborist::ObserverRunner do
105
107
  thr = Thread.new { runner.run }
106
108
  wait( 3 ).for { runner }.to be_running
107
109
 
108
- expect( @manager.subscriptions.length ).to eq( runner.subscriptions.length )
110
+ # Count the manager's subs that have external (UUID) keys.
111
+ expected_sub_count = @manager.subscriptions.count do |key, sub|
112
+ Loggability[ Arborist ].debug "Counting %p: %p" % [ key, sub ]
113
+ key =~ /\A\p{XDigit}{8}-\p{XDigit}{4}-/
114
+ end
115
+ expect( runner.subscriptions.length ).to eq( expected_sub_count )
109
116
 
110
117
  runner.simulate_signal( :TERM )
111
118
  thr.join( 2 )
@@ -6,22 +6,125 @@ require 'arborist/tree_api'
6
6
 
7
7
  describe Arborist::TreeAPI, :testing_manager do
8
8
 
9
- it "can encode a valid Tree API header and body into a message"
10
- it "raises an exception if the header to encode isn't a Hash"
9
+ it "can encode a valid Tree API header and body into a message" do
10
+ result = described_class.encode( {version: 1}, foo: 'bar' )
11
+ expect( result ).to be_a( CZTop::Message )
11
12
 
12
- it "can build a valid Tree API request message"
13
+ payload = result.frames.first.to_s
14
+ expect( payload ).to be_a_messagepacked( Array )
13
15
 
16
+ decoded = MessagePack.unpack( payload )
17
+ expect( decoded.first ).to eq({ 'version' => 1 })
18
+ expect( decoded.last ).to eq({ 'foo' => 'bar' })
19
+ end
20
+
21
+
22
+ it "can encode a valid Tree API header and a nil body into a message" do
23
+ result = described_class.encode( {version: 1}, nil )
24
+ expect( result ).to be_a( CZTop::Message )
25
+
26
+ payload = result.frames.first.to_s
27
+ expect( payload ).to be_a_messagepacked( Array )
28
+
29
+ decoded = MessagePack.unpack( payload )
30
+ expect( decoded.first ).to eq({ 'version' => 1 })
31
+ expect( decoded.last ).to be_nil
32
+ end
33
+
34
+
35
+ it "raises an exception if the header to encode isn't a Hash" do
36
+ expect {
37
+ described_class.encode( 1 )
38
+ }.to raise_error( Arborist::MessageError, /header is not a Map/i )
39
+ end
40
+
41
+
42
+ it "raises an exception if the body is invalid" do
43
+ expect {
44
+ described_class.encode( {version: 1}, ['foo'] )
45
+ }.to raise_error( Arborist::MessageError, /invalid message.*body must be/i )
46
+ end
47
+
48
+
49
+ it "can build a valid Tree API request message" do
50
+ result = described_class.request( :status )
51
+ expect( result ).to be_a( CZTop::Message )
52
+
53
+ payload = result.frames.first.to_s
54
+ expect( payload ).to be_a_messagepacked( Array )
55
+
56
+ decoded = MessagePack.unpack( payload )
57
+ expect( decoded.first ).to eq({
58
+ 'version' => described_class::PROTOCOL_VERSION,
59
+ 'action' => 'status'
60
+ })
61
+ expect( decoded.last ).to be_nil
62
+ end
14
63
 
15
- it "can build a valid success response message"
16
- it "can build a valid error response message"
17
64
 
65
+ it "can build a valid success response message" do
66
+ result = described_class.successful_response( foo: 'bar' )
67
+ expect( result ).to be_a( CZTop::Message )
68
+
69
+ payload = result.frames.first.to_s
70
+ expect( payload ).to be_a_messagepacked( Array )
71
+
72
+ decoded = MessagePack.unpack( payload )
73
+ expect( decoded.first ).to include( 'success' => true )
74
+ expect( decoded.last ).to eq({ 'foo' => 'bar' })
75
+ end
76
+
77
+
78
+ it "can build a valid error response message" do
79
+ result = described_class.error_response( 'category', 'reason' )
80
+ expect( result ).to be_a( CZTop::Message )
81
+
82
+ payload = result.frames.first.to_s
83
+ expect( payload ).to be_a_messagepacked( Array )
84
+
85
+ decoded = MessagePack.unpack( payload )
86
+ expect( decoded.first['success'] ).to eq( false )
87
+ expect( decoded.first['category'] ).to eq( 'category' )
88
+ expect( decoded.first['reason'] ).to eq( 'reason' )
89
+ end
90
+
91
+
92
+ it "can decode a header and payload from a valid request message" do
93
+ payload = [
94
+ { 'version' => described_class::PROTOCOL_VERSION },
95
+ { 'foo' => 'bar' }
96
+ ]
97
+ msg = CZTop::Message.new( MessagePack.pack(payload) )
98
+
99
+ header, body = described_class.decode( msg )
100
+
101
+ expect( header ).to eq( payload.first )
102
+ expect( body ).to eq( payload.last )
103
+ end
18
104
 
19
- it "can decode a header and payload from a valid request message"
20
105
 
21
106
  describe "raises an exception when decoding a request message" do
22
107
 
23
- it "from a different protocol version"
24
- it "that doesn't contain a valid MessagePack payload'"
108
+ it "from a different protocol version" do
109
+ payload = [
110
+ { 'version' => described_class::PROTOCOL_VERSION.succ },
111
+ { 'foo' => 'bar' }
112
+ ]
113
+ msg = CZTop::Message.new( MessagePack.pack(payload) )
114
+
115
+ expect {
116
+ described_class.decode( msg )
117
+ }.to raise_error( Arborist::MessageError, /unknown protocol version/i )
118
+ end
119
+
120
+
121
+ it "that doesn't contain a valid MessagePack payload'" do
122
+ msg = CZTop::Message.new( 'some random junk' )
123
+
124
+ expect {
125
+ described_class.decode( msg )
126
+ }.to raise_error( Arborist::MessageError, /invalid message/i )
127
+ end
25
128
 
26
129
  end
27
130
 
@@ -59,17 +59,6 @@ Arborist::Monitor 'ping check' do
59
59
  exec_callbacks( FPingWrapper )
60
60
  end
61
61
 
62
- Arborist::Monitor 'ping check downed hosts' do
63
- every 40.seconds
64
- splay 15.seconds
65
- match type: 'host', status: 'down'
66
- include_down true
67
- use :addresses
68
-
69
- exec 'fping', '-e', '-t', '150'
70
- exec_callbacks( FPingWrapper )
71
- end
72
-
73
62
  Arborist::Monitor 'transient host pings' do
74
63
  every 5.minutes
75
64
  match type: 'host', tag: 'laptop'
@@ -13,12 +13,3 @@ Arborist::Monitor 'port checks on all tcp services' do
13
13
  exec( Arborist::Monitor::Socket::TCP )
14
14
  end
15
15
 
16
- Arborist::Monitor 'port checks on downed tcp services' do
17
- every 10.seconds
18
- match type: 'service', protocol: 'tcp', status: 'down'
19
- include_down true
20
- use :addresses, :port
21
- exec( Arborist::Monitor::Socket::TCP )
22
- end
23
-
24
-
@@ -17,6 +17,7 @@ Arborist::Host 'sidonie' do
17
17
  service 'ssh'
18
18
  service 'demon-http', port: 6666, protocol: 'http'
19
19
  service 'postgresql'
20
+ service 'iscsi', port: 860, protocol: 'udp'
20
21
 
21
22
  service 'smtp'
22
23
 
@@ -0,0 +1,23 @@
1
+ # -*- ruby -*-
2
+ #encoding: utf-8
3
+
4
+ require 'arborist'
5
+
6
+ Arborist::Host 'vhost01' do
7
+ parent 'duir'
8
+ description "Virtual Host server"
9
+ address '192.168.16.75'
10
+
11
+ tags :infrastructure
12
+
13
+ depends_on 'sidonie-iscsi'
14
+ end
15
+
16
+
17
+ Arborist::Host 'sandbox01' do
18
+ parent 'vhost01'
19
+ description "Scratch copy-on-write server for experiments"
20
+
21
+ service 'canary', port: 12131, protocol: 'udp'
22
+ end
23
+
@@ -13,11 +13,13 @@ Arborist::Host 'yevaud' do
13
13
  tags :laptop,
14
14
  :developer
15
15
 
16
+ service 'ntp'
16
17
  service 'ssh'
17
18
  service 'rabbitmq', app_protocol: 'amqp'
18
- service 'postgresql'
19
19
 
20
- service 'cozy_frontend', port: 3000, app_protocol: 'http'
20
+ service 'cozy_frontend', port: 3000, app_protocol: 'http' do
21
+ depends_on 'sidonie-postgresql', 'yevaud-rabbitmq'
22
+ end
21
23
  service 'cozy_admin_frontend', port: 4331, app_protocol: 'http'
22
24
  service 'cozy_services', port: 8888, app_protocol: 'http'
23
25
  service 'cozy_admin_services', port: 8889, app_protocol: 'http'
@@ -4,6 +4,7 @@
4
4
  require 'pathname'
5
5
  require 'simplecov' if ENV['COVERAGE']
6
6
  require 'rspec'
7
+ require 'rspec/wait'
7
8
  require 'loggability/spechelpers'
8
9
  require 'msgpack'
9
10
 
@@ -30,6 +31,52 @@ RSpec::Matchers.define( :match_criteria ) do |criteria|
30
31
  end
31
32
 
32
33
 
34
+ class BeMessagepacked
35
+
36
+ def initialize( expected_type )
37
+ @expected_type = expected_type
38
+ @actual_value = nil
39
+ @decoded = nil
40
+ @exception = nil
41
+ end
42
+
43
+
44
+ def matches?( actual_value )
45
+ @actual_value = actual_value
46
+ @decoded = MessagePack.unpack( actual_value )
47
+ return @decoded.is_a?( @expected_type )
48
+ rescue => err
49
+ @exception = err
50
+ return false
51
+ end
52
+
53
+
54
+ def failure_reason
55
+ if @exception && @exception.is_a?( MessagePack::MalformedFormatError )
56
+ return "it was not formatted correctly: %s" % [ @exception.message ]
57
+ elsif @exception
58
+ return "there was a %p when trying to decode it: %s" %
59
+ [ @exception.class, @exception.message ]
60
+ elsif @decoded && !@decoded.is_a?( @expected_type )
61
+ return "it was a msgpacked %p" % [ @decoded.class ]
62
+ else
63
+ return 'there was an unknown problem'
64
+ end
65
+ end
66
+
67
+
68
+ def failure_message
69
+ "expected %p to be a msgpacked %p but %s" % [ @actual_value, @expected_type, self.failure_reason ]
70
+ end
71
+
72
+
73
+ def failure_message_when_negated
74
+ "expected %p not to be a msgpacked %p, but it was" % [ @actual_value, @actual_value ]
75
+ end
76
+
77
+ end
78
+
79
+
33
80
  module Arborist::TestConstants
34
81
  SPEC_DIR = Pathname( __FILE__ ).dirname
35
82
  SPEC_DATA_DIR = SPEC_DIR + 'data'
@@ -79,7 +126,7 @@ module Arborist::TestHelpers
79
126
  #
80
127
 
81
128
  def node_subclass
82
- @node_subclass ||= Class.new( Arborist::Node )
129
+ return TestNode
83
130
  end
84
131
 
85
132
 
@@ -89,6 +136,29 @@ module Arborist::TestHelpers
89
136
  return node
90
137
  end
91
138
 
139
+
140
+ def node_hierarchy( root, *children )
141
+ root = node_subclass.new( root ) unless root.is_a?( Arborist::Node )
142
+
143
+ children.each do |child|
144
+ child.parent( root.identifier )
145
+ root.add_child( child )
146
+ end
147
+
148
+ return root
149
+ end
150
+
151
+
152
+ #
153
+ # Expectations
154
+ #
155
+
156
+ ### Set an expectation that the receiving value is an instance of the
157
+ ### +expected_class+ that's been encoded with msgpack.
158
+ def be_a_messagepacked( expected_class )
159
+ return BeMessagepacked.new( expected_class )
160
+ end
161
+
92
162
  end
93
163
 
94
164
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: arborist
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0.pre20170519125456
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Granger
@@ -9,8 +9,34 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain:
12
- - certs/ged.pem
13
- date: 2017-05-19 00:00:00.000000000 Z
12
+ - |
13
+ -----BEGIN CERTIFICATE-----
14
+ MIIEbDCCAtSgAwIBAgIBATANBgkqhkiG9w0BAQUFADA+MQwwCgYDVQQDDANnZWQx
15
+ GTAXBgoJkiaJk/IsZAEZFglGYWVyaWVNVUQxEzARBgoJkiaJk/IsZAEZFgNvcmcw
16
+ HhcNMTcwOTI3MDAzMDQ0WhcNMTgwOTI3MDAzMDQ0WjA+MQwwCgYDVQQDDANnZWQx
17
+ GTAXBgoJkiaJk/IsZAEZFglGYWVyaWVNVUQxEzARBgoJkiaJk/IsZAEZFgNvcmcw
18
+ ggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQC/JWGRHO+USzR97vXjkFgt
19
+ 83qeNf2KHkcvrRTSnR64i6um/ziin0I0oX23H7VYrDJC9A/uoUa5nGRJS5Zw/+wW
20
+ ENcvWVZS4iUzi4dsYJGY6yEOsXh2CcF46+QevV8iE+UmbkU75V7Dy1JCaUOyizEt
21
+ TH5UHsOtUU7k9TYARt/TgYZKuaoAMZZd5qyVqhF1vV+7/Qzmp89NGflXf2xYP26a
22
+ 4MAX2qqKX/FKXqmFO+AGsbwYTEds1mksBF3fGsFgsQWxftG8GfZQ9+Cyu2+l1eOw
23
+ cZ+lPcg834G9DrqW2zhqUoLr1MTly4pqxYGb7XoDhoR7dd1kFE2a067+DzWC/ADt
24
+ +QkcqWUm5oh1fN0eqr7NsZlVJDulFgdiiYPQiIN7UNsii4Wc9aZqBoGcYfBeQNPZ
25
+ soo/6za/bWajOKUmDhpqvaiRv9EDpVLzuj53uDoukMMwxCMfgb04+ckQ0t2G7wqc
26
+ /D+K9JW9DDs3Yjgv9k4h7YMhW5gftosd+NkNC/+Y2CkCAwEAAaN1MHMwCQYDVR0T
27
+ BAIwADALBgNVHQ8EBAMCBLAwHQYDVR0OBBYEFHKN/nkRusdqCJEuq3lgB3fJvyTg
28
+ MBwGA1UdEQQVMBOBEWdlZEBGYWVyaWVNVUQub3JnMBwGA1UdEgQVMBOBEWdlZEBG
29
+ YWVyaWVNVUQub3JnMA0GCSqGSIb3DQEBBQUAA4IBgQB/qyi5pCjK8ceoKalfVAjS
30
+ vG64FEnLnD1bm39T5UaFIRmo+abZtfpg2QhwKvPbPjOicau2+m+MDQ2Cc3tgyaC3
31
+ dZxcP6w8APFg4AId09uWAZKf0xajvBMS2aOz8Bbmag6fwqRRkTMqsNYnmqcF7aRT
32
+ DuEzbEMfaOUYjU9RuB48vr4q8yRft0ww+3jq5iwNkrX1buL2pwBbyvgms6D/BV41
33
+ MaTVMjsHqJUwU2xVfhGtxGAWAer5S1HGYHkbio6mGVtiie0uWjmnzi7ppIlMr48a
34
+ 7BNTsoZ+/JRk3iQWmmNsyFT7xfqBKye7cH11BX8V8P4MeGB5YWlMI+Myj5DZY3fQ
35
+ st2AGD4rb1l0ia7PfubcBThSIdz61eCb8gRi/RiZZwb3/7+eyEncLJzt2Ob9fGSF
36
+ X0qdrKi+2aZZ0NGuFj9AItBsVmAvkBGIpX4TEKQp5haEbPpmaqO5nIIhV26PXmyT
37
+ OMKv6pWsoS81vw5KAGBmfX8nht/Py90DQrbRvakATGI=
38
+ -----END CERTIFICATE-----
39
+ date: 2018-08-09 00:00:00.000000000 Z
14
40
  dependencies:
15
41
  - !ruby/object:Gem::Dependency
16
42
  name: schedulability
@@ -74,14 +100,14 @@ dependencies:
74
100
  requirements:
75
101
  - - "~>"
76
102
  - !ruby/object:Gem::Version
77
- version: '0.2'
103
+ version: '0.5'
78
104
  type: :runtime
79
105
  prerelease: false
80
106
  version_requirements: !ruby/object:Gem::Requirement
81
107
  requirements:
82
108
  - - "~>"
83
109
  - !ruby/object:Gem::Version
84
- version: '0.2'
110
+ version: '0.5'
85
111
  - !ruby/object:Gem::Dependency
86
112
  name: msgpack
87
113
  requirement: !ruby/object:Gem::Requirement
@@ -139,19 +165,47 @@ dependencies:
139
165
  - !ruby/object:Gem::Version
140
166
  version: '2.3'
141
167
  - !ruby/object:Gem::Dependency
142
- name: highline
168
+ name: tty
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - "~>"
172
+ - !ruby/object:Gem::Version
173
+ version: '0.7'
174
+ type: :runtime
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - "~>"
179
+ - !ruby/object:Gem::Version
180
+ version: '0.7'
181
+ - !ruby/object:Gem::Dependency
182
+ name: tty-tree
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - "~>"
186
+ - !ruby/object:Gem::Version
187
+ version: '0.1'
188
+ type: :runtime
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - "~>"
193
+ - !ruby/object:Gem::Version
194
+ version: '0.1'
195
+ - !ruby/object:Gem::Dependency
196
+ name: pry
143
197
  requirement: !ruby/object:Gem::Requirement
144
198
  requirements:
145
199
  - - "~>"
146
200
  - !ruby/object:Gem::Version
147
- version: '1.7'
201
+ version: '0.11'
148
202
  type: :runtime
149
203
  prerelease: false
150
204
  version_requirements: !ruby/object:Gem::Requirement
151
205
  requirements:
152
206
  - - "~>"
153
207
  - !ruby/object:Gem::Version
154
- version: '1.7'
208
+ version: '0.11'
155
209
  - !ruby/object:Gem::Dependency
156
210
  name: hoe-mercurial
157
211
  requirement: !ruby/object:Gem::Requirement
@@ -256,14 +310,28 @@ dependencies:
256
310
  requirements:
257
311
  - - "~>"
258
312
  - !ruby/object:Gem::Version
259
- version: '4.0'
313
+ version: '5.1'
314
+ type: :development
315
+ prerelease: false
316
+ version_requirements: !ruby/object:Gem::Requirement
317
+ requirements:
318
+ - - "~>"
319
+ - !ruby/object:Gem::Version
320
+ version: '5.1'
321
+ - !ruby/object:Gem::Dependency
322
+ name: state_machines-graphviz
323
+ requirement: !ruby/object:Gem::Requirement
324
+ requirements:
325
+ - - "~>"
326
+ - !ruby/object:Gem::Version
327
+ version: '0.0'
260
328
  type: :development
261
329
  prerelease: false
262
330
  version_requirements: !ruby/object:Gem::Requirement
263
331
  requirements:
264
332
  - - "~>"
265
333
  - !ruby/object:Gem::Version
266
- version: '4.0'
334
+ version: '0.0'
267
335
  - !ruby/object:Gem::Dependency
268
336
  name: hoe
269
337
  requirement: !ruby/object:Gem::Requirement
@@ -282,8 +350,6 @@ description: |-
282
350
  Arborist is a monitoring toolkit that follows the UNIX philosophy
283
351
  of small parts and loose coupling for stability, reliability, and
284
352
  customizability.
285
-
286
- [![Build Status](https://semaphoreci.com/api/v1/projects/13677b60-5f81-4e6e-a9c6-e21d30daa4ca/461532/badge.svg)](https://semaphoreci.com/ged/arborist)
287
353
  email:
288
354
  - ged@FaerieMUD.org
289
355
  - mahlon@martini.nu
@@ -291,38 +357,30 @@ executables:
291
357
  - arborist
292
358
  extensions: []
293
359
  extra_rdoc_files:
294
- - Events.md
295
360
  - History.md
296
361
  - Manifest.txt
297
- - Monitors.md
298
- - Nodes.md
299
- - Observers.md
300
- - Protocol.md
301
362
  - README.md
302
363
  - TODO.md
303
- - Tutorial.md
304
364
  files:
305
365
  - ".document"
306
366
  - ".simplecov"
307
367
  - ChangeLog
308
- - Events.md
309
368
  - History.md
310
369
  - Manifest.txt
311
- - Monitors.md
312
- - Nodes.md
313
- - Observers.md
314
- - Protocol.md
315
370
  - README.md
316
371
  - Rakefile
317
372
  - TODO.md
318
- - Tutorial.md
319
373
  - bin/arborist
320
374
  - lib/arborist.rb
321
375
  - lib/arborist/cli.rb
322
376
  - lib/arborist/client.rb
377
+ - lib/arborist/command/ack.rb
323
378
  - lib/arborist/command/client.rb
324
379
  - lib/arborist/command/config.rb
380
+ - lib/arborist/command/reset.rb
325
381
  - lib/arborist/command/start.rb
382
+ - lib/arborist/command/summary.rb
383
+ - lib/arborist/command/tree.rb
326
384
  - lib/arborist/command/watch.rb
327
385
  - lib/arborist/dependency.rb
328
386
  - lib/arborist/event.rb
@@ -335,6 +393,7 @@ files:
335
393
  - lib/arborist/event/node_unknown.rb
336
394
  - lib/arborist/event/node_up.rb
337
395
  - lib/arborist/event/node_update.rb
396
+ - lib/arborist/event/node_warn.rb
338
397
  - lib/arborist/event_api.rb
339
398
  - lib/arborist/exceptions.rb
340
399
  - lib/arborist/loader.rb
@@ -342,6 +401,7 @@ files:
342
401
  - lib/arborist/manager.rb
343
402
  - lib/arborist/mixins.rb
344
403
  - lib/arborist/monitor.rb
404
+ - lib/arborist/monitor/connection_batching.rb
345
405
  - lib/arborist/monitor/socket.rb
346
406
  - lib/arborist/monitor_runner.rb
347
407
  - lib/arborist/node.rb
@@ -350,6 +410,7 @@ files:
350
410
  - lib/arborist/node/resource.rb
351
411
  - lib/arborist/node/root.rb
352
412
  - lib/arborist/node/service.rb
413
+ - lib/arborist/node_subscription.rb
353
414
  - lib/arborist/observer.rb
354
415
  - lib/arborist/observer/action.rb
355
416
  - lib/arborist/observer/summarize.rb
@@ -375,6 +436,7 @@ files:
375
436
  - spec/arborist/node/root_spec.rb
376
437
  - spec/arborist/node/service_spec.rb
377
438
  - spec/arborist/node_spec.rb
439
+ - spec/arborist/node_subscription_spec.rb
378
440
  - spec/arborist/observer/action_spec.rb
379
441
  - spec/arborist/observer/summarize_spec.rb
380
442
  - spec/arborist/observer_runner_spec.rb
@@ -389,6 +451,7 @@ files:
389
451
  - spec/data/nodes/localhost.rb
390
452
  - spec/data/nodes/sidonie.rb
391
453
  - spec/data/nodes/sub/duir.rb
454
+ - spec/data/nodes/vhosts.rb
392
455
  - spec/data/nodes/yevaud.rb
393
456
  - spec/data/observers/auditor.rb
394
457
  - spec/data/observers/webservices.rb
@@ -410,14 +473,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
410
473
  version: 2.3.1
411
474
  required_rubygems_version: !ruby/object:Gem::Requirement
412
475
  requirements:
413
- - - ">"
476
+ - - ">="
414
477
  - !ruby/object:Gem::Version
415
- version: 1.3.1
478
+ version: '0'
416
479
  requirements: []
417
480
  rubyforge_project:
418
- rubygems_version: 2.6.12
481
+ rubygems_version: 2.7.6
419
482
  signing_key:
420
483
  specification_version: 4
421
484
  summary: Arborist is a monitoring toolkit that follows the UNIX philosophy of small
422
- parts and loose coupling for stability, reliability, and customizability
485
+ parts and loose coupling for stability, reliability, and customizability.
423
486
  test_files: []