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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/ChangeLog +670 -1
- data/History.md +67 -0
- data/Manifest.txt +9 -6
- data/README.md +1 -3
- data/Rakefile +39 -4
- data/TODO.md +22 -31
- data/lib/arborist.rb +9 -2
- data/lib/arborist/cli.rb +67 -85
- data/lib/arborist/client.rb +125 -59
- data/lib/arborist/command/ack.rb +86 -0
- data/lib/arborist/command/reset.rb +48 -0
- data/lib/arborist/command/start.rb +11 -1
- data/lib/arborist/command/summary.rb +173 -0
- data/lib/arborist/command/tree.rb +215 -0
- data/lib/arborist/command/watch.rb +22 -22
- data/lib/arborist/dependency.rb +24 -4
- data/lib/arborist/event.rb +18 -2
- data/lib/arborist/event/node.rb +6 -2
- data/lib/arborist/event/node_warn.rb +16 -0
- data/lib/arborist/manager.rb +179 -48
- data/lib/arborist/mixins.rb +11 -0
- data/lib/arborist/monitor.rb +29 -17
- data/lib/arborist/monitor/connection_batching.rb +293 -0
- data/lib/arborist/monitor/socket.rb +101 -167
- data/lib/arborist/monitor_runner.rb +101 -24
- data/lib/arborist/node.rb +297 -68
- data/lib/arborist/node/ack.rb +1 -1
- data/lib/arborist/node/host.rb +26 -5
- data/lib/arborist/node/resource.rb +14 -5
- data/lib/arborist/node/root.rb +12 -3
- data/lib/arborist/node/service.rb +29 -26
- data/lib/arborist/node_subscription.rb +65 -0
- data/lib/arborist/observer.rb +8 -0
- data/lib/arborist/observer/action.rb +6 -0
- data/lib/arborist/subscription.rb +22 -16
- data/lib/arborist/tree_api.rb +7 -2
- data/spec/arborist/client_spec.rb +157 -51
- data/spec/arborist/dependency_spec.rb +21 -0
- data/spec/arborist/event/node_spec.rb +5 -0
- data/spec/arborist/event_spec.rb +3 -3
- data/spec/arborist/manager_spec.rb +626 -347
- data/spec/arborist/mixins_spec.rb +19 -0
- data/spec/arborist/monitor/socket_spec.rb +1 -2
- data/spec/arborist/monitor_runner_spec.rb +81 -29
- data/spec/arborist/monitor_spec.rb +89 -14
- data/spec/arborist/node/host_spec.rb +68 -0
- data/spec/arborist/node/resource_spec.rb +2 -0
- data/spec/arborist/node/root_spec.rb +13 -0
- data/spec/arborist/node/service_spec.rb +9 -0
- data/spec/arborist/node_spec.rb +673 -111
- data/spec/arborist/node_subscription_spec.rb +54 -0
- data/spec/arborist/observer/action_spec.rb +6 -0
- data/spec/arborist/observer_runner_spec.rb +8 -1
- data/spec/arborist/tree_api_spec.rb +111 -8
- data/spec/data/monitors/pings.rb +0 -11
- data/spec/data/monitors/port_checks.rb +0 -9
- data/spec/data/nodes/sidonie.rb +1 -0
- data/spec/data/nodes/vhosts.rb +23 -0
- data/spec/data/nodes/yevaud.rb +4 -2
- data/spec/spec_helper.rb +71 -1
- metadata +91 -28
- metadata.gz.sig +0 -0
- data/Events.md +0 -35
- data/Monitors.md +0 -155
- data/Nodes.md +0 -70
- data/Observers.md +0 -72
- data/Protocol.md +0 -276
- data/Tutorial.md +0 -8
metadata.gz.sig
ADDED
Binary file
|
data/Events.md
DELETED
@@ -1,35 +0,0 @@
|
|
1
|
-
# Events
|
2
|
-
|
3
|
-
## Event Types
|
4
|
-
|
5
|
-
«type».«subtype»
|
6
|
-
|
7
|
-
node.acked
|
8
|
-
node.delta
|
9
|
-
node.disabled
|
10
|
-
node.down
|
11
|
-
node.quieted
|
12
|
-
node.unknown
|
13
|
-
node.up
|
14
|
-
node.update
|
15
|
-
sys.node_added
|
16
|
-
sys.node_removed
|
17
|
-
sys.reloaded
|
18
|
-
sys.hearbeat
|
19
|
-
|
20
|
-
|
21
|
-
## Event Movement
|
22
|
-
|
23
|
-
Propagation
|
24
|
-
|
25
|
-
events being sent up the tree to the root node
|
26
|
-
|
27
|
-
Broadcast
|
28
|
-
|
29
|
-
events being sent down to node children
|
30
|
-
|
31
|
-
Publishing
|
32
|
-
|
33
|
-
events being sent to subscriptions, including dependent nodes
|
34
|
-
triggered via propagation and broadcasting
|
35
|
-
|
data/Monitors.md
DELETED
@@ -1,155 +0,0 @@
|
|
1
|
-
# Monitors
|
2
|
-
|
3
|
-
Monitors are loaded in a fashion similar to the way nodes describing the network topology are
|
4
|
-
loaded: you provide a Enumerator that yields Arborist::Monitor objects to the #load_monitors method
|
5
|
-
of an Arborist::MonitorRunner object. The `Arborist::Monitor.each_in` method, given a path to a directory containing `.rb` files that declare one or more monitors, will return such an Enumerator, but you could also use this to load monitor descriptions from any source you prefer, e.g., LDAP, a RDBMS, etc.
|
6
|
-
|
7
|
-
|
8
|
-
## Declaration DSL
|
9
|
-
|
10
|
-
To facilitate describing monitors to run, Arborist::Monitor also provides a DSL-like syntax for constructing them.
|
11
|
-
|
12
|
-
For example, this would declare two monitors, one which pings every 'host' node except those tagged as laptops in the network every 20 seconds, and the other which pings 'host' nodes tagged as laptops every 5 minutes.
|
13
|
-
|
14
|
-
# monitors/pings.rb
|
15
|
-
require 'arborist/monitor'
|
16
|
-
|
17
|
-
Arborist::Monitor 'ping check' do
|
18
|
-
key :pingcheck
|
19
|
-
every 20.seconds
|
20
|
-
match type: 'host'
|
21
|
-
exclude tag: :laptop
|
22
|
-
use :address
|
23
|
-
exec 'fping'
|
24
|
-
end
|
25
|
-
|
26
|
-
Arborist::Monitor 'transient host pings' do
|
27
|
-
key :pingcheck
|
28
|
-
every 5.minutes
|
29
|
-
match type: 'host', tag: 'laptop'
|
30
|
-
use :address
|
31
|
-
exec 'fping'
|
32
|
-
end
|
33
|
-
|
34
|
-
Each monitor is given a human-readable description for use in user interfaces, and one or more attributes that describe which nodes should be monitored, how they should be monitored, and how often the monitor should be run.
|
35
|
-
|
36
|
-
### Monitor Attributes
|
37
|
-
|
38
|
-
#### key
|
39
|
-
|
40
|
-
Declare a namespace for the monitor. The error status for a node is keyed by this value, so that monitors with different keys don't clear each other's errors.
|
41
|
-
|
42
|
-
This attribute is mandatory.
|
43
|
-
|
44
|
-
#### description
|
45
|
-
|
46
|
-
Set a human-readable description for the monitor, for use in interfaces or logs.
|
47
|
-
|
48
|
-
This attribute is mandatory.
|
49
|
-
|
50
|
-
#### every( seconds )
|
51
|
-
|
52
|
-
Declare the interval between runs of the monitor. The monitor will be skewed by a small amount from this value (unless you specify `splay 0`) to prevent many monitors from starting up simultaneously.
|
53
|
-
|
54
|
-
#### splay( seconds )
|
55
|
-
|
56
|
-
Manually set the amount of splay (random offset from the interval) the monitor should use. It defaults to `Math.logn( interval )`.
|
57
|
-
|
58
|
-
#### exec( command )
|
59
|
-
#### exec {|node_attributes| ... }
|
60
|
-
#### exec( module )
|
61
|
-
|
62
|
-
Specify what should be run to do the actual monitoring. The first form simply `spawn`s the specified command with its STDIN opened to a stream of serialized node data.
|
63
|
-
|
64
|
-
By default, the format of the serialized nodes is one node per line, and each line looks like this:
|
65
|
-
|
66
|
-
«identifier» «attribute1»=«attribute1 value» «attribute2»=«attribute2 value»
|
67
|
-
|
68
|
-
Each line should use shell-escaping semantics, so that if an attribute value contains whitespace, it should be quoted, control characters need to be escaped, etc.
|
69
|
-
|
70
|
-
For example, the ping checker might receive input like:
|
71
|
-
|
72
|
-
duir address=192.168.16.3
|
73
|
-
sidonie address="192.168.16.3"
|
74
|
-
yevaud address="192.168.16.10"
|
75
|
-
|
76
|
-
If the command you are running doesn't support this format, you can override this in one of two ways.
|
77
|
-
|
78
|
-
If your command expects the node data as command-line arguments, you can provide a custom `exec_arguments` block. It will receive an Array of Arborist::Node objects and it should generate an Array of arguments to append to the command before `spawn`ing it.
|
79
|
-
|
80
|
-
exec_arguments do |nodes|
|
81
|
-
# Build an address -> node mapping for pairing the updates back up by address
|
82
|
-
@node_map = nodes.each_with_object( {} ) do |node, hash|
|
83
|
-
address = node.address
|
84
|
-
hash[ address ] = node
|
85
|
-
end
|
86
|
-
|
87
|
-
@node_map.keys
|
88
|
-
end
|
89
|
-
|
90
|
-
If your command expects the node data via `STDIN`, but in a different format, you may declare an `exec_input` block. It will be called with the same node array, and additionally an IO open to the STDIN of the running command. This can be combined with the `exec_arguments` block, if you're dealing with something really weird.
|
91
|
-
|
92
|
-
exec_input do |nodes, writer|
|
93
|
-
# Build an address -> node mapping for pairing the updates back up by address
|
94
|
-
@node_map = nodes.each_with_object( {} ) do |node, hash|
|
95
|
-
address = node.address
|
96
|
-
hash[ address ] = node
|
97
|
-
end
|
98
|
-
|
99
|
-
writer.puts( node_map.values )
|
100
|
-
end
|
101
|
-
|
102
|
-
The monitor must write results for any of the listed identifiers that require update in the same format to its STDOUT. For the ping check above, the results might look like:
|
103
|
-
|
104
|
-
duir rtt=20ms
|
105
|
-
sidonie rtt=103ms
|
106
|
-
yevaud rtt= error=Host\ unreachable.
|
107
|
-
|
108
|
-
If the program writes its output in some other format, you can provide a `handle_results` block. It will be called with the program's `STDOUT` if the block takes one argument, and if it takes an additional argument its `STDERR` as well. It should return a Hash of update Hashes, keyed by the node identifier it should be sent to.
|
109
|
-
|
110
|
-
handle_results do |pid, out, err|
|
111
|
-
updates = {}
|
112
|
-
|
113
|
-
out.each_line do |line|
|
114
|
-
address, status = line.split( /\s+:\s+/, 2 )
|
115
|
-
|
116
|
-
# Use the @node_map we created up in the exec_arguments to map the output
|
117
|
-
# back into identifiers. Error-checking omitted for brevity.
|
118
|
-
identifier = @node_map[ address ].identifier
|
119
|
-
|
120
|
-
# 127.0.0.1 is alive (0.12 ms)
|
121
|
-
# 8.8.8.8 is alive (61.6 ms)
|
122
|
-
# 192.168.16.16 is unreachable
|
123
|
-
if status =~ /is alive \((\d+\.\d+ ms)\)/i
|
124
|
-
updates[ identifier ] = { ping: { rtt: Float($1) } }
|
125
|
-
else
|
126
|
-
updates[ identifier ] = { error: status }
|
127
|
-
end
|
128
|
-
end
|
129
|
-
|
130
|
-
updates
|
131
|
-
end
|
132
|
-
|
133
|
-
Unlisted attributes are unchanged. A listed attribute with an empty value is explicitly cleared. An identifier that isn't listed in the results means no update is necessary for that node.
|
134
|
-
|
135
|
-
If you find yourself wanting to repeat one or more of the exec callbacks, you can also wrap them in a module and call `exec_callbacks` with it.
|
136
|
-
|
137
|
-
The second and third forms can be used to implement a monitor in Ruby. In the second, the block is called with the Hash of node data, keyed by identifier, and it must return a Hash of updates keyed by identifier. The third form expects any object that responds to `#run`, which will be invoked the same way as the block.
|
138
|
-
|
139
|
-
|
140
|
-
#### use( *properties )
|
141
|
-
|
142
|
-
Specify the list of properties to provide to the monitor for each node. If this is unspecified, the input to the monitor will be just the list of identifiers.
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
# Does everything in Ruby; gets the Array of Nodes as arguments to the block, expected to
|
147
|
-
# return a Hash of updates keyed by node identifier
|
148
|
-
exec do |nodes|
|
149
|
-
|
150
|
-
end
|
151
|
-
|
152
|
-
|
153
|
-
# Runs an external
|
154
|
-
exec 'fping', '-e', '-t', '150'
|
155
|
-
|
data/Nodes.md
DELETED
@@ -1,70 +0,0 @@
|
|
1
|
-
# Nodes
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
Arborist::Host 'sidonie' do
|
6
|
-
parent 'duir'
|
7
|
-
description "NAS and media server"
|
8
|
-
address '192.168.16.3'
|
9
|
-
|
10
|
-
tags :infrastructure,
|
11
|
-
:storage,
|
12
|
-
:media,
|
13
|
-
:rip_status_check
|
14
|
-
|
15
|
-
service 'ssh'
|
16
|
-
service 'demon-http', port: 6666, protocol: 'http'
|
17
|
-
service 'postgresql'
|
18
|
-
|
19
|
-
service 'smtp'
|
20
|
-
|
21
|
-
service 'http',
|
22
|
-
depends_on: 'postgresql'
|
23
|
-
service 'sabnzbd', port: 8080, protocol: 'http'
|
24
|
-
service 'sickbeard', port: 8081, protocol: 'http'
|
25
|
-
service 'pms', port: 32400, protocol: 'http'
|
26
|
-
service 'couchpotato', port: 5050, protocol: 'http'
|
27
|
-
end
|
28
|
-
|
29
|
-
|
30
|
-
Arborist::Host 'jhereg' do
|
31
|
-
parent 'duir'
|
32
|
-
description "Directory server"
|
33
|
-
address '192.168.16.7'
|
34
|
-
|
35
|
-
service 'ldaps'
|
36
|
-
end
|
37
|
-
|
38
|
-
|
39
|
-
Arborist::Host 'webserver' do
|
40
|
-
description "Public webserver"
|
41
|
-
address '54.16.62.181'
|
42
|
-
|
43
|
-
service 'http',
|
44
|
-
depends_on: 'foo'
|
45
|
-
depends_on: all_of( 'postgresql', 'daemon-http', on: 'sidonie' ),
|
46
|
-
all_of( 'ldaps', on: 'jhereg' )
|
47
|
-
end
|
48
|
-
|
49
|
-
|
50
|
-
An application server depends on one each of the 'http' services and 'ldaps' services
|
51
|
-
to be up.
|
52
|
-
|
53
|
-
Arborist::Host 'appserver1' do
|
54
|
-
description "Public application webserver"
|
55
|
-
address '54.16.62.185'
|
56
|
-
service 'http',
|
57
|
-
depends_on: all_of(
|
58
|
-
any_of( 'http', on: %w[service1 service2 service3] ),
|
59
|
-
any_of( 'ldaps', on: %w[directory1 directory2] ),
|
60
|
-
all_of( 'else', on: 'something' )
|
61
|
-
)
|
62
|
-
end
|
63
|
-
|
64
|
-
|
65
|
-
[ :all_of,
|
66
|
-
[ :any_of, 'service1-http', 'service2-http', 'service3-http' ],
|
67
|
-
[ :any_of, 'directory1-ldaps', 'directory2-ldaps' ],
|
68
|
-
'something-else'
|
69
|
-
]
|
70
|
-
|
data/Observers.md
DELETED
@@ -1,72 +0,0 @@
|
|
1
|
-
# Observers
|
2
|
-
|
3
|
-
subscription
|
4
|
-
* Event to subscribe to
|
5
|
-
* Node to attach subscription to. No node means 'root', which sees all subnode events.
|
6
|
-
* One or more action blocks
|
7
|
-
|
8
|
-
Actions have:
|
9
|
-
* a block to execute
|
10
|
-
* Zero or more time-periods, which are unioned together. No time periods means anytime.
|
11
|
-
|
12
|
-
Pragmas:
|
13
|
-
* Summarize:
|
14
|
-
(send a single alert summarizing every event received over x period of time, or n events)
|
15
|
-
* Squelch:
|
16
|
-
|
17
|
-
|
18
|
-
:MAHLON:
|
19
|
-
The manager should probably serialize subscriptions for its nodes. Otherwise the manager
|
20
|
-
can restart and any running observers will never again receive events because the
|
21
|
-
subscriptions will have disappeared.
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
## Examples
|
26
|
-
|
27
|
-
# -*- ruby -*-
|
28
|
-
#encoding: utf-8
|
29
|
-
|
30
|
-
require 'arborist'
|
31
|
-
|
32
|
-
WORK_HOURS = 'hour {8am-6pm}'
|
33
|
-
OFF_HOURS = 'hour {6pm-8am}'
|
34
|
-
|
35
|
-
Arborist::Observer "Webservers" do
|
36
|
-
subscribe to: 'node.delta',
|
37
|
-
where: {
|
38
|
-
type: 'service',
|
39
|
-
port: 80,
|
40
|
-
delta: { status: ['up', 'down'] }
|
41
|
-
}
|
42
|
-
|
43
|
-
action( during: WORK_HOURS ) do |uuid, event|
|
44
|
-
$stderr.puts "Webserver %s is DOWN (%p)" % [ event['data']['identifier'], event['data'] ]
|
45
|
-
end
|
46
|
-
summarize( every: 5.minutes, count: 5, during: OFF_HOURS ) do |*tuples|
|
47
|
-
email to: 'ops@example.com', subject: ""
|
48
|
-
end
|
49
|
-
|
50
|
-
end
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
## Schedulability stuff
|
55
|
-
|
56
|
-
schedule = Schedule.new
|
57
|
-
schedule |= Period.time( '8AM' .. '8PM' )
|
58
|
-
schedule |= Period.day( 'Mon' .. 'Fri' )
|
59
|
-
|
60
|
-
|
61
|
-
# Thymelörde! - An Amazeballs Gem for Doing Stuff With Time™
|
62
|
-
|
63
|
-
|
64
|
-
schedule = Thymelörde!.yes?( 'Tue-Thur {6am-9pm}' )
|
65
|
-
schedule.ehh? #=> false
|
66
|
-
schedule.yes? #=> false
|
67
|
-
|
68
|
-
|
69
|
-
Legba -- the gatekeeper?
|
70
|
-
|
71
|
-
|
72
|
-
|
data/Protocol.md
DELETED
@@ -1,276 +0,0 @@
|
|
1
|
-
# Monitors
|
2
|
-
|
3
|
-
## Basic Protocol
|
4
|
-
|
5
|
-
ZMQ REQ socket, msgpack message consisting of an Array of two elements:
|
6
|
-
|
7
|
-
[
|
8
|
-
header,
|
9
|
-
body
|
10
|
-
]
|
11
|
-
|
12
|
-
Header is a Map of the form:
|
13
|
-
|
14
|
-
{
|
15
|
-
action: «verb», # required
|
16
|
-
version: 1, # required
|
17
|
-
[verb-specific attributes]
|
18
|
-
}
|
19
|
-
|
20
|
-
Body is either Nil, a Map of key-value pairs, or an Array of Maps appropriate to the `action`.
|
21
|
-
|
22
|
-
|
23
|
-
## Commands
|
24
|
-
|
25
|
-
|
26
|
-
### «commandname»
|
27
|
-
|
28
|
-
«description»
|
29
|
-
|
30
|
-
#### Header
|
31
|
-
|
32
|
-
#### Body
|
33
|
-
|
34
|
-
#### Return
|
35
|
-
|
36
|
-
#### Examples
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
### status
|
42
|
-
|
43
|
-
Fetch the status of the Manager.
|
44
|
-
|
45
|
-
{
|
46
|
-
action: status,
|
47
|
-
version: 1,
|
48
|
-
}
|
49
|
-
|
50
|
-
Response:
|
51
|
-
|
52
|
-
{
|
53
|
-
success: true,
|
54
|
-
version: 1
|
55
|
-
},
|
56
|
-
{
|
57
|
-
server_version: 0.0.1,
|
58
|
-
state: 'running',
|
59
|
-
uptime: 17155,
|
60
|
-
nodecount: 342
|
61
|
-
}
|
62
|
-
|
63
|
-
|
64
|
-
### list
|
65
|
-
|
66
|
-
Retrieve an Array of Maps that describes all or part of the node tree.
|
67
|
-
|
68
|
-
#### Required
|
69
|
-
from the node with the specified `identifier`, or the root node if no `identifier` is specified.
|
70
|
-
|
71
|
-
|
72
|
-
Request:
|
73
|
-
|
74
|
-
[
|
75
|
-
{
|
76
|
-
action: list,
|
77
|
-
version: 1
|
78
|
-
[from: «identifier»]
|
79
|
-
[depth: «arg»]
|
80
|
-
}
|
81
|
-
]
|
82
|
-
|
83
|
-
Successful response:
|
84
|
-
|
85
|
-
[
|
86
|
-
{
|
87
|
-
success: true,
|
88
|
-
version: 1
|
89
|
-
},
|
90
|
-
[
|
91
|
-
{
|
92
|
-
identifier: 'foo',
|
93
|
-
status: 'up',
|
94
|
-
parent: '_',
|
95
|
-
properties: {},
|
96
|
-
},
|
97
|
-
{
|
98
|
-
identifier: 'bar',
|
99
|
-
status: 'down',
|
100
|
-
parent: 'foo',
|
101
|
-
properties: {},
|
102
|
-
}
|
103
|
-
]
|
104
|
-
]
|
105
|
-
|
106
|
-
failure example:
|
107
|
-
|
108
|
-
[
|
109
|
-
{
|
110
|
-
success: false,
|
111
|
-
reason: "human readable exception message or whatever",
|
112
|
-
category: either 'server' or 'client', meaning who is responsible for the error
|
113
|
-
version: 1
|
114
|
-
}
|
115
|
-
]
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
### fetch
|
120
|
-
|
121
|
-
Fetch the `address`, `description`, and `status` of all nodes.
|
122
|
-
|
123
|
-
[
|
124
|
-
{
|
125
|
-
action: fetch,
|
126
|
-
version: 1,
|
127
|
-
include_down: true,
|
128
|
-
return: [address, description, status]
|
129
|
-
},
|
130
|
-
|
131
|
-
Response
|
132
|
-
|
133
|
-
{
|
134
|
-
'theon' => {
|
135
|
-
address: '10.2.10.4',
|
136
|
-
description: 'no theon, reek',
|
137
|
-
status: down,
|
138
|
-
},
|
139
|
-
'thoros' => {
|
140
|
-
address: '10.2.10.4',
|
141
|
-
description: "The Red God's champion",
|
142
|
-
status: up,
|
143
|
-
}
|
144
|
-
]
|
145
|
-
]
|
146
|
-
|
147
|
-
|
148
|
-
#### return
|
149
|
-
|
150
|
-
- not specified : returns everything.
|
151
|
-
- `Nil` : returns just identifiers
|
152
|
-
- array of fields : returns the values of those fields
|
153
|
-
|
154
|
-
Search for nodes that match the filter given in the request body, returning a serialized map of node identifiers to requested state.
|
155
|
-
|
156
|
-
|
157
|
-
### update
|
158
|
-
|
159
|
-
[
|
160
|
-
{
|
161
|
-
action: update,
|
162
|
-
version: 1
|
163
|
-
},
|
164
|
-
{
|
165
|
-
duir: {
|
166
|
-
pingtime: 0.02
|
167
|
-
},
|
168
|
-
sidonie: {
|
169
|
-
pingtime: 0.28
|
170
|
-
}
|
171
|
-
}
|
172
|
-
]
|
173
|
-
|
174
|
-
With a failure:
|
175
|
-
|
176
|
-
[
|
177
|
-
{
|
178
|
-
action: update,
|
179
|
-
version: 1
|
180
|
-
},
|
181
|
-
{
|
182
|
-
duir: {
|
183
|
-
pingtime: null,
|
184
|
-
error: "Host unreachable."
|
185
|
-
},
|
186
|
-
sidonie: {
|
187
|
-
pingtime: 0.28
|
188
|
-
}
|
189
|
-
}
|
190
|
-
]
|
191
|
-
|
192
|
-
|
193
|
-
### subscribe
|
194
|
-
|
195
|
-
Get node change delta events for every 'host' type node.
|
196
|
-
|
197
|
-
{
|
198
|
-
action: subscribe,
|
199
|
-
version: 1,
|
200
|
-
event_type: node.delta
|
201
|
-
},
|
202
|
-
{
|
203
|
-
type: 'host',
|
204
|
-
}
|
205
|
-
|
206
|
-
Get a snapshot of node state on every update for 'service' type nodes under
|
207
|
-
the 'bennett' node.
|
208
|
-
|
209
|
-
{
|
210
|
-
action: subscribe,
|
211
|
-
version: 1,
|
212
|
-
event_type: node.update,
|
213
|
-
identifier: 'bennett'
|
214
|
-
},
|
215
|
-
{
|
216
|
-
type: 'service',
|
217
|
-
}
|
218
|
-
|
219
|
-
Get events of state changes to services running on port 80.
|
220
|
-
|
221
|
-
{
|
222
|
-
action: subscribe,
|
223
|
-
version: 1,
|
224
|
-
event_type: node.delta
|
225
|
-
},
|
226
|
-
{
|
227
|
-
type: 'service',
|
228
|
-
port: 80
|
229
|
-
}
|
230
|
-
|
231
|
-
Get notified of every system event (startup, shutdown, reload, etc.)
|
232
|
-
|
233
|
-
{
|
234
|
-
action: subscribe,
|
235
|
-
version: 1,
|
236
|
-
event_type: sys.*
|
237
|
-
},
|
238
|
-
Nil
|
239
|
-
|
240
|
-
|
241
|
-
### graft
|
242
|
-
|
243
|
-
{
|
244
|
-
action: graft,
|
245
|
-
version: 1,
|
246
|
-
type: 'host',
|
247
|
-
identifier: 'joliet',
|
248
|
-
parent: 'bennett' # defaults to root
|
249
|
-
},
|
250
|
-
{
|
251
|
-
addresses: [],
|
252
|
-
tags: []
|
253
|
-
}
|
254
|
-
|
255
|
-
|
256
|
-
### prune
|
257
|
-
|
258
|
-
{
|
259
|
-
action: prune,
|
260
|
-
version: 1,
|
261
|
-
identifier: 'bennett'
|
262
|
-
},
|
263
|
-
Nil
|
264
|
-
|
265
|
-
|
266
|
-
### modify
|
267
|
-
|
268
|
-
{
|
269
|
-
action: modify,
|
270
|
-
version: 1,
|
271
|
-
identifier: 'bennett'
|
272
|
-
},
|
273
|
-
{
|
274
|
-
addresses: ['10.13.0.22', '10.1.0.23']
|
275
|
-
}
|
276
|
-
|