arborist 0.0.1.pre20160106113421
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.document +4 -0
- data/.simplecov +9 -0
- data/ChangeLog +417 -0
- data/Events.md +20 -0
- data/History.md +4 -0
- data/LICENSE +29 -0
- data/Manifest.txt +72 -0
- data/Monitors.md +141 -0
- data/Nodes.md +0 -0
- data/Observers.md +72 -0
- data/Protocol.md +214 -0
- data/README.md +75 -0
- data/Rakefile +81 -0
- data/TODO.md +24 -0
- data/bin/amanagerd +10 -0
- data/bin/amonitord +12 -0
- data/bin/aobserverd +12 -0
- data/lib/arborist.rb +182 -0
- data/lib/arborist/client.rb +191 -0
- data/lib/arborist/event.rb +61 -0
- data/lib/arborist/event/node_acked.rb +18 -0
- data/lib/arborist/event/node_delta.rb +20 -0
- data/lib/arborist/event/node_matching.rb +34 -0
- data/lib/arborist/event/node_update.rb +19 -0
- data/lib/arborist/event/sys_reloaded.rb +15 -0
- data/lib/arborist/exceptions.rb +21 -0
- data/lib/arborist/manager.rb +508 -0
- data/lib/arborist/manager/event_publisher.rb +97 -0
- data/lib/arborist/manager/tree_api.rb +207 -0
- data/lib/arborist/mixins.rb +363 -0
- data/lib/arborist/monitor.rb +377 -0
- data/lib/arborist/monitor/socket.rb +163 -0
- data/lib/arborist/monitor_runner.rb +217 -0
- data/lib/arborist/node.rb +700 -0
- data/lib/arborist/node/host.rb +87 -0
- data/lib/arborist/node/root.rb +60 -0
- data/lib/arborist/node/service.rb +112 -0
- data/lib/arborist/observer.rb +176 -0
- data/lib/arborist/observer/action.rb +125 -0
- data/lib/arborist/observer/summarize.rb +105 -0
- data/lib/arborist/observer_runner.rb +181 -0
- data/lib/arborist/subscription.rb +82 -0
- data/spec/arborist/client_spec.rb +282 -0
- data/spec/arborist/event/node_update_spec.rb +71 -0
- data/spec/arborist/event_spec.rb +64 -0
- data/spec/arborist/manager/event_publisher_spec.rb +66 -0
- data/spec/arborist/manager/tree_api_spec.rb +458 -0
- data/spec/arborist/manager_spec.rb +442 -0
- data/spec/arborist/mixins_spec.rb +195 -0
- data/spec/arborist/monitor/socket_spec.rb +195 -0
- data/spec/arborist/monitor_runner_spec.rb +152 -0
- data/spec/arborist/monitor_spec.rb +251 -0
- data/spec/arborist/node/host_spec.rb +104 -0
- data/spec/arborist/node/root_spec.rb +29 -0
- data/spec/arborist/node/service_spec.rb +98 -0
- data/spec/arborist/node_spec.rb +552 -0
- data/spec/arborist/observer/action_spec.rb +205 -0
- data/spec/arborist/observer/summarize_spec.rb +294 -0
- data/spec/arborist/observer_spec.rb +146 -0
- data/spec/arborist/subscription_spec.rb +71 -0
- data/spec/arborist_spec.rb +146 -0
- data/spec/data/monitors/pings.rb +80 -0
- data/spec/data/monitors/port_checks.rb +27 -0
- data/spec/data/monitors/system_resources.rb +30 -0
- data/spec/data/monitors/web_services.rb +17 -0
- data/spec/data/nodes/duir.rb +20 -0
- data/spec/data/nodes/localhost.rb +15 -0
- data/spec/data/nodes/sidonie.rb +29 -0
- data/spec/data/nodes/yevaud.rb +26 -0
- data/spec/data/observers/auditor.rb +23 -0
- data/spec/data/observers/webservices.rb +18 -0
- data/spec/spec_helper.rb +117 -0
- metadata +368 -0
data/README.md
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
# Arborist
|
2
|
+
|
3
|
+
home :: http://deveiate.org/projects/Arborist
|
4
|
+
code :: http://bitbucket.org/ged/Arborist
|
5
|
+
github :: https://github.com/ged/arborist
|
6
|
+
docs :: http://deveiate.org/code/arborist
|
7
|
+
|
8
|
+
|
9
|
+
## Description
|
10
|
+
|
11
|
+
Arborist is a monitoring framework that follows the UNIX philosophy
|
12
|
+
of small parts and loose coupling for stability, reliability, and
|
13
|
+
customizability.
|
14
|
+
|
15
|
+
|
16
|
+
## Prerequisites
|
17
|
+
|
18
|
+
* Ruby 2.2 or better
|
19
|
+
|
20
|
+
|
21
|
+
## Installation
|
22
|
+
|
23
|
+
$ gem install arborist
|
24
|
+
|
25
|
+
|
26
|
+
## Further Reading
|
27
|
+
|
28
|
+
You'll likely want to start with [the Tutorial](Tutorial.html).
|
29
|
+
|
30
|
+
|
31
|
+
## Contributing
|
32
|
+
|
33
|
+
You can check out the current development source with Mercurial via its
|
34
|
+
[project page](http://bitbucket.org/ged/Arborist). Or if you prefer Git, via
|
35
|
+
[its Github mirror](https://github.com/ged/arborist).
|
36
|
+
|
37
|
+
After checking out the source, run:
|
38
|
+
|
39
|
+
$ rake newb
|
40
|
+
|
41
|
+
This task will install any missing dependencies, run the tests/specs,
|
42
|
+
and generate the API documentation.
|
43
|
+
|
44
|
+
|
45
|
+
## License
|
46
|
+
|
47
|
+
Copyright (c) 2015, Michael Granger and Mahlon E. Smith
|
48
|
+
All rights reserved.
|
49
|
+
|
50
|
+
Redistribution and use in source and binary forms, with or without
|
51
|
+
modification, are permitted provided that the following conditions are met:
|
52
|
+
|
53
|
+
* Redistributions of source code must retain the above copyright notice,
|
54
|
+
this list of conditions and the following disclaimer.
|
55
|
+
|
56
|
+
* Redistributions in binary form must reproduce the above copyright notice,
|
57
|
+
this list of conditions and the following disclaimer in the documentation
|
58
|
+
and/or other materials provided with the distribution.
|
59
|
+
|
60
|
+
* Neither the name of the author/s, nor the names of the project's
|
61
|
+
contributors may be used to endorse or promote products derived from this
|
62
|
+
software without specific prior written permission.
|
63
|
+
|
64
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
65
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
66
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
67
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
68
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
69
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
70
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
71
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
72
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
73
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
74
|
+
|
75
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
|
3
|
+
begin
|
4
|
+
require 'hoe'
|
5
|
+
rescue LoadError
|
6
|
+
abort "This Rakefile requires hoe (gem install hoe)"
|
7
|
+
end
|
8
|
+
|
9
|
+
GEMSPEC = 'arborist.gemspec'
|
10
|
+
|
11
|
+
|
12
|
+
Hoe.plugin :mercurial
|
13
|
+
Hoe.plugin :signing
|
14
|
+
Hoe.plugin :deveiate
|
15
|
+
|
16
|
+
Hoe.plugins.delete :rubyforge
|
17
|
+
Hoe.plugins.delete :gemcutter
|
18
|
+
|
19
|
+
hoespec = Hoe.spec 'arborist' do |spec|
|
20
|
+
spec.readme_file = 'README.md'
|
21
|
+
spec.history_file = 'History.md'
|
22
|
+
spec.extra_rdoc_files = FileList[ '*.rdoc', '*.md' ]
|
23
|
+
self.license 'BSD-3-Clause'
|
24
|
+
spec.urls = {
|
25
|
+
home: 'http://deveiate.org/projects/arborist',
|
26
|
+
code: 'http://bitbucket.org/ged/arborist',
|
27
|
+
docs: 'http://deveiate.org/code/arborist',
|
28
|
+
github: 'http://github.com/ged/arborist',
|
29
|
+
}
|
30
|
+
|
31
|
+
spec.developer 'Michael Granger', 'ged@FaerieMUD.org'
|
32
|
+
spec.developer 'Mahlon E. Smith', 'mahlon@martini.nu'
|
33
|
+
|
34
|
+
spec.dependency 'schedulability', '~> 0.1'
|
35
|
+
spec.dependency 'loggability', '~> 0.11'
|
36
|
+
spec.dependency 'configurability', '~> 2.2'
|
37
|
+
spec.dependency 'pluggability', '~> 0.4'
|
38
|
+
spec.dependency 'state_machines', '~> 0.2'
|
39
|
+
spec.dependency 'msgpack', '~> 0.6'
|
40
|
+
spec.dependency 'rbczmq', '~> 1.7'
|
41
|
+
|
42
|
+
spec.dependency 'rspec', '~> 3.2', :developer
|
43
|
+
spec.dependency 'simplecov', '~> 0.9', :developer
|
44
|
+
spec.dependency 'timecop', '~> 0.7', :developer
|
45
|
+
|
46
|
+
spec.require_ruby_version( '>=2.2.0' )
|
47
|
+
spec.hg_sign_tags = true if spec.respond_to?( :hg_sign_tags= )
|
48
|
+
|
49
|
+
self.rdoc_locations << "deveiate:/usr/local/www/public/code/#{remote_rdoc_dir}"
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
ENV['VERSION'] ||= hoespec.spec.version.to_s
|
54
|
+
|
55
|
+
# Run the tests before checking in
|
56
|
+
task 'hg:precheckin' => [ :check_history, :check_manifest, :gemspec, :spec ]
|
57
|
+
|
58
|
+
# Rebuild the ChangeLog immediately before release
|
59
|
+
task :prerelease => 'ChangeLog'
|
60
|
+
CLOBBER.include( 'ChangeLog' )
|
61
|
+
|
62
|
+
desc "Build a coverage report"
|
63
|
+
task :coverage do
|
64
|
+
ENV["COVERAGE"] = 'yes'
|
65
|
+
Rake::Task[:spec].invoke
|
66
|
+
end
|
67
|
+
|
68
|
+
|
69
|
+
task :gemspec => GEMSPEC
|
70
|
+
file GEMSPEC => __FILE__ do |task|
|
71
|
+
spec = $hoespec.spec
|
72
|
+
spec.files.delete( '.gemtest' )
|
73
|
+
spec.signing_key = nil
|
74
|
+
spec.version = "#{spec.version}.pre#{Time.now.strftime("%Y%m%d%H%M%S")}"
|
75
|
+
File.open( task.name, 'w' ) do |fh|
|
76
|
+
fh.write( spec.to_ruby )
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
task :default => :gemspec
|
81
|
+
|
data/TODO.md
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# To-Do
|
2
|
+
|
3
|
+
## Manager
|
4
|
+
|
5
|
+
* Serialize nodes on shutdown
|
6
|
+
* Include a node's subscriptions in its serialized data
|
7
|
+
* Implement loading/reloading nodes.
|
8
|
+
|
9
|
+
## Tree API
|
10
|
+
|
11
|
+
* Add "grafting": node add/removal
|
12
|
+
|
13
|
+
## Observers
|
14
|
+
|
15
|
+
* Scheduling time periods for action/summarizing
|
16
|
+
* Summarizing and Actions should be 1st order objects
|
17
|
+
* Unsubscribe from Arborist and ZMQ subscriptions on shutdown
|
18
|
+
* Figure out how to match on delta events: the criteria
|
19
|
+
for matching nodes has to be separated from that which matches
|
20
|
+
the delta pairs.
|
21
|
+
|
22
|
+
## Node
|
23
|
+
|
24
|
+
* Add a 'disabled' state, can be set on 'up' nodes by acking them.
|
data/bin/amanagerd
ADDED
data/bin/amonitord
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'arborist'
|
4
|
+
require 'arborist/monitor_runner'
|
5
|
+
|
6
|
+
monitors_path = ARGV.shift or raise "No monitor file specified."
|
7
|
+
|
8
|
+
Arborist.load_config( ARGV.shift )
|
9
|
+
Arborist.load_all
|
10
|
+
|
11
|
+
runner = Arborist.monitor_runner_for( monitors_path )
|
12
|
+
runner.run
|
data/bin/aobserverd
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'arborist'
|
4
|
+
require 'arborist/observer_runner'
|
5
|
+
|
6
|
+
observers_path = ARGV.shift or raise "No observer file specified."
|
7
|
+
|
8
|
+
Arborist.load_config( ARGV.shift )
|
9
|
+
Arborist.load_all
|
10
|
+
|
11
|
+
runner = Arborist.observer_runner_for( observers_path )
|
12
|
+
runner.run
|
data/lib/arborist.rb
ADDED
@@ -0,0 +1,182 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
#encoding: utf-8
|
3
|
+
|
4
|
+
require 'rbczmq'
|
5
|
+
|
6
|
+
require 'pathname'
|
7
|
+
require 'configurability'
|
8
|
+
require 'loggability'
|
9
|
+
|
10
|
+
|
11
|
+
# Arborist namespace
|
12
|
+
module Arborist
|
13
|
+
extend Loggability,
|
14
|
+
Configurability
|
15
|
+
|
16
|
+
# Package version
|
17
|
+
VERSION = '0.0.1'
|
18
|
+
|
19
|
+
# Version control revision
|
20
|
+
REVISION = %q$Revision: fddcbace9b6d $
|
21
|
+
|
22
|
+
|
23
|
+
# The name of the environment variable which can be used to set the config path
|
24
|
+
CONFIG_ENV = 'ARBORIST_CONFIG'
|
25
|
+
|
26
|
+
# The name of the config file for local overrides.
|
27
|
+
LOCAL_CONFIG_FILE = Pathname( '~/.arborist.yml' ).expand_path
|
28
|
+
|
29
|
+
# The name of the config file that's loaded if none is specified.
|
30
|
+
DEFAULT_CONFIG_FILE = Pathname( 'arborist.yml' ).expand_path
|
31
|
+
|
32
|
+
# Configurability API -- default configuration values
|
33
|
+
CONFIG_DEFAULTS = {
|
34
|
+
tree_api_url: 'ipc:///tmp/arborist_tree.sock',
|
35
|
+
event_api_url: 'ipc:///tmp/arborist_events.sock'
|
36
|
+
}
|
37
|
+
|
38
|
+
|
39
|
+
##
|
40
|
+
# Set up a logger for the Arborist namespace
|
41
|
+
log_as :arborist
|
42
|
+
|
43
|
+
# Configurability API -- use the 'arborist'
|
44
|
+
config_key :arborist
|
45
|
+
|
46
|
+
|
47
|
+
require 'arborist/mixins'
|
48
|
+
extend Arborist::MethodUtilities
|
49
|
+
|
50
|
+
|
51
|
+
##
|
52
|
+
# The ZMQ REP socket for the API for accessing the node tree.
|
53
|
+
singleton_attr_accessor :tree_api_url
|
54
|
+
@tree_api_url = CONFIG_DEFAULTS[ :tree_api_url ]
|
55
|
+
|
56
|
+
##
|
57
|
+
# The ZMQ PUB socket for published events
|
58
|
+
singleton_attr_accessor :event_api_url
|
59
|
+
@event_api_url = CONFIG_DEFAULTS[ :event_api_url ]
|
60
|
+
|
61
|
+
|
62
|
+
#
|
63
|
+
# :section: Configuration API
|
64
|
+
#
|
65
|
+
|
66
|
+
### Configurability API.
|
67
|
+
def self::configure( config=nil )
|
68
|
+
config = self.defaults.merge( config || {} )
|
69
|
+
|
70
|
+
self.tree_api_url = config[ :tree_api_url ]
|
71
|
+
self.event_api_url = config[ :event_api_url ]
|
72
|
+
end
|
73
|
+
|
74
|
+
|
75
|
+
### Get the loaded config (a Configurability::Config object)
|
76
|
+
def self::config
|
77
|
+
Configurability.loaded_config
|
78
|
+
end
|
79
|
+
|
80
|
+
|
81
|
+
### Returns +true+ if the configuration has been loaded at least once.
|
82
|
+
def self::config_loaded?
|
83
|
+
return self.config ? true : false
|
84
|
+
end
|
85
|
+
|
86
|
+
|
87
|
+
### Load the specified +config_file+, install the config in all objects with
|
88
|
+
### Configurability, and call any callbacks registered via #after_configure.
|
89
|
+
def self::load_config( config_file=nil, defaults=nil )
|
90
|
+
config_file ||= ENV[ CONFIG_ENV ]
|
91
|
+
config_file ||= LOCAL_CONFIG_FILE if LOCAL_CONFIG_FILE.exist?
|
92
|
+
config_file ||= DEFAULT_CONFIG_FILE
|
93
|
+
|
94
|
+
defaults ||= Configurability.gather_defaults
|
95
|
+
|
96
|
+
self.log.info "Loading config from %p with defaults for sections: %p." %
|
97
|
+
[ config_file, defaults.keys ]
|
98
|
+
config = Configurability::Config.load( config_file, defaults )
|
99
|
+
|
100
|
+
config.install
|
101
|
+
end
|
102
|
+
|
103
|
+
|
104
|
+
### Add a constructor function to the Arborist namespace called +name+
|
105
|
+
### with the specified +method_body+.
|
106
|
+
def self::add_dsl_constructor( name, &method_body )
|
107
|
+
self.log.debug "Adding constructor for %p: %p" % [ name, method_body ]
|
108
|
+
singleton_class.instance_exec( name, method_body ) do |name, body|
|
109
|
+
define_method( name, &body )
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
|
114
|
+
### Return a new Arborist::Manager for the nodes described in files under
|
115
|
+
### the specified +directory+.
|
116
|
+
def self::manager_for( directory )
|
117
|
+
self.load_all
|
118
|
+
nodes = Arborist::Node.each_in( directory )
|
119
|
+
manager = Arborist::Manager.new
|
120
|
+
manager.load_tree( nodes )
|
121
|
+
|
122
|
+
return manager
|
123
|
+
end
|
124
|
+
|
125
|
+
|
126
|
+
### Return a new Arborist::MonitorRunner for the monitors described in files under
|
127
|
+
### the specified +directory+.
|
128
|
+
def self::monitor_runner_for( directory )
|
129
|
+
self.load_all
|
130
|
+
monitors = Arborist::Monitor.each_in( directory )
|
131
|
+
runner = Arborist::MonitorRunner.new
|
132
|
+
runner.load_monitors( monitors )
|
133
|
+
|
134
|
+
return runner
|
135
|
+
end
|
136
|
+
|
137
|
+
|
138
|
+
### Return a new Arborist::ObserverRunner for the observers described in files under
|
139
|
+
### the specified +directory+.
|
140
|
+
def self::observer_runner_for( directory )
|
141
|
+
self.load_all
|
142
|
+
observers = Arborist::Observer.each_in( directory )
|
143
|
+
runner = Arborist::ObserverRunner.new
|
144
|
+
runner.load_observers( observers )
|
145
|
+
|
146
|
+
return runner
|
147
|
+
end
|
148
|
+
|
149
|
+
|
150
|
+
### Load all node and event types
|
151
|
+
def self::load_all
|
152
|
+
Arborist::Node.load_all
|
153
|
+
end
|
154
|
+
|
155
|
+
|
156
|
+
### Destroy any existing ZMQ state.
|
157
|
+
def self::reset_zmq_context
|
158
|
+
@zmq_context.destroy if @zmq_context.respond_to?( :destroy )
|
159
|
+
@zmq_context = nil
|
160
|
+
end
|
161
|
+
|
162
|
+
|
163
|
+
### Fetch the ZMQ context for Arborist.
|
164
|
+
def self::zmq_context
|
165
|
+
return @zmq_context ||= ZMQ::Context.new
|
166
|
+
end
|
167
|
+
|
168
|
+
|
169
|
+
require 'arborist/exceptions'
|
170
|
+
require 'arborist/mixins'
|
171
|
+
|
172
|
+
autoload :Client, 'arborist/client'
|
173
|
+
autoload :Event, 'arborist/event'
|
174
|
+
autoload :Manager, 'arborist/manager'
|
175
|
+
autoload :Monitor, 'arborist/monitor'
|
176
|
+
autoload :MonitorRunner, 'arborist/monitor_runner'
|
177
|
+
autoload :Node, 'arborist/node'
|
178
|
+
autoload :Observer, 'arborist/observer'
|
179
|
+
autoload :Subscription, 'arborist/subscription'
|
180
|
+
|
181
|
+
end # module Arborist
|
182
|
+
|
@@ -0,0 +1,191 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
#encoding: utf-8
|
3
|
+
|
4
|
+
require 'arborist' unless defined?( Arborist )
|
5
|
+
require 'msgpack'
|
6
|
+
|
7
|
+
|
8
|
+
# Unified Arborist Manager client for both the Tree and Event APIs
|
9
|
+
class Arborist::Client
|
10
|
+
extend Loggability
|
11
|
+
|
12
|
+
# The version of the client.
|
13
|
+
API_VERSION = 1
|
14
|
+
|
15
|
+
# Loggability API -- log to the Arborist log host
|
16
|
+
log_to :arborist
|
17
|
+
|
18
|
+
|
19
|
+
### Create a new Client with the given API socket URIs.
|
20
|
+
def initialize( tree_api_url: nil, event_api_url: nil )
|
21
|
+
@tree_api_url = tree_api_url || Arborist.tree_api_url
|
22
|
+
@event_api_url = event_api_url || Arborist.event_api_url
|
23
|
+
|
24
|
+
@request_queue = nil
|
25
|
+
@event_subscriptions = nil
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
######
|
30
|
+
public
|
31
|
+
######
|
32
|
+
|
33
|
+
# The ZMQ URI required to speak to the Arborist tree API.
|
34
|
+
attr_accessor :tree_api_url
|
35
|
+
|
36
|
+
# The ZMQ URI required to speak to the Arborist event API.
|
37
|
+
attr_accessor :event_api_url
|
38
|
+
|
39
|
+
|
40
|
+
### Return the manager's current status as a hash.
|
41
|
+
def status
|
42
|
+
request = self.make_status_request
|
43
|
+
return self.send_tree_api_request( request )
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
### Return the manager's current status as a hash.
|
48
|
+
def make_status_request
|
49
|
+
return self.pack_message( :status )
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
### Return the manager's current node tree.
|
54
|
+
def list( *args )
|
55
|
+
request = self.make_list_request( *args )
|
56
|
+
return self.send_tree_api_request( request )
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
### Return the manager's current node tree.
|
61
|
+
def make_list_request( from: nil )
|
62
|
+
header = {}
|
63
|
+
self.log.debug "From is: %p" % [ from ]
|
64
|
+
header[:from] = from if from
|
65
|
+
|
66
|
+
return self.pack_message( :list, header )
|
67
|
+
end
|
68
|
+
|
69
|
+
|
70
|
+
### Return the manager's current node tree.
|
71
|
+
def fetch( criteria={}, *args )
|
72
|
+
request = self.make_fetch_request( criteria, *args )
|
73
|
+
return self.send_tree_api_request( request )
|
74
|
+
end
|
75
|
+
|
76
|
+
|
77
|
+
### Return the manager's current node tree.
|
78
|
+
def make_fetch_request( criteria, include_down: false, properties: :all )
|
79
|
+
header = {}
|
80
|
+
header[ :include_down ] = true if include_down
|
81
|
+
header[ :return ] = properties if properties != :all
|
82
|
+
|
83
|
+
return self.pack_message( :fetch, header, criteria )
|
84
|
+
end
|
85
|
+
|
86
|
+
|
87
|
+
### Update the identified nodes in the manager with the specified data.
|
88
|
+
def update( *args )
|
89
|
+
request = self.make_update_request( *args )
|
90
|
+
return self.send_tree_api_request( request )
|
91
|
+
end
|
92
|
+
|
93
|
+
|
94
|
+
### Update the identified nodes in the manager with the specified data.
|
95
|
+
def make_update_request( data )
|
96
|
+
return self.pack_message( :update, nil, data )
|
97
|
+
end
|
98
|
+
|
99
|
+
|
100
|
+
### Add a subscription
|
101
|
+
def subscribe( *args )
|
102
|
+
request = self.make_subscribe_request( *args )
|
103
|
+
response = self.send_tree_api_request( request )
|
104
|
+
return response.first
|
105
|
+
end
|
106
|
+
|
107
|
+
|
108
|
+
### Make a subscription request for the specified +criteria+, +identifier+, and +event_type+.
|
109
|
+
def make_subscribe_request( criteria: {}, identifier: nil, event_type: nil )
|
110
|
+
self.log.debug "Making subscription request for identifier: %p, event_type: %p, criteria: %p" %
|
111
|
+
[ identifier, event_type, criteria ]
|
112
|
+
header = {}
|
113
|
+
header[ :identifier ] = identifier if identifier
|
114
|
+
header[ :event_type ] = event_type
|
115
|
+
|
116
|
+
return self.pack_message( :subscribe, header, criteria )
|
117
|
+
end
|
118
|
+
|
119
|
+
|
120
|
+
### Send the packed +request+ via the Tree API socket, raise an error on
|
121
|
+
### unsuccessful response, and return the response body.
|
122
|
+
def send_tree_api_request( request )
|
123
|
+
self.log.debug "Sending request: %p" % [ request ]
|
124
|
+
self.tree_api.send( request )
|
125
|
+
|
126
|
+
res = self.tree_api.recv
|
127
|
+
self.log.debug "Received response: %p" % [ res ]
|
128
|
+
|
129
|
+
header, body = self.unpack_message( res )
|
130
|
+
unless header[ 'success' ]
|
131
|
+
raise "Arborist manager said: %s" % [ header['reason'] ]
|
132
|
+
end
|
133
|
+
|
134
|
+
return body
|
135
|
+
end
|
136
|
+
|
137
|
+
|
138
|
+
|
139
|
+
### Format ruby +data+ for communicating with the Arborist manager.
|
140
|
+
def pack_message( verb, *data )
|
141
|
+
header = data.shift || {}
|
142
|
+
body = data.shift
|
143
|
+
|
144
|
+
header.merge!( action: verb, version: API_VERSION )
|
145
|
+
|
146
|
+
self.log.debug "Packing message; header: %p, body: %p" % [ header, body ]
|
147
|
+
|
148
|
+
return MessagePack.pack([ header, body ])
|
149
|
+
end
|
150
|
+
|
151
|
+
|
152
|
+
### De-serialize an Arborist manager response.
|
153
|
+
def unpack_message( msg )
|
154
|
+
return MessagePack.unpack( msg )
|
155
|
+
end
|
156
|
+
|
157
|
+
|
158
|
+
### Return a ZMQ REQ socket connected to the manager's tree API, instantiating
|
159
|
+
### it if necessary.
|
160
|
+
def tree_api
|
161
|
+
return @tree_api ||= self.make_tree_api_socket
|
162
|
+
end
|
163
|
+
|
164
|
+
|
165
|
+
### Create a new ZMQ REQ socket connected to the manager's tree API.
|
166
|
+
def make_tree_api_socket
|
167
|
+
self.log.info "Connecting to the tree socket %p" % [ self.tree_api_url ]
|
168
|
+
sock = Arborist.zmq_context.socket( :REQ )
|
169
|
+
sock.connect( self.tree_api_url )
|
170
|
+
|
171
|
+
return sock
|
172
|
+
end
|
173
|
+
|
174
|
+
|
175
|
+
### Return a ZMQ SUB socket connected to the manager's event API, instantiating
|
176
|
+
### it if necessary.
|
177
|
+
def event_api
|
178
|
+
return @event_api ||= self.make_event_api_socket
|
179
|
+
end
|
180
|
+
|
181
|
+
|
182
|
+
### Create a new ZMQ SUB socket connected to the manager's event API.
|
183
|
+
def make_event_api_socket
|
184
|
+
self.log.info "Connecting to the event socket %p" % [ self.event_api_url ]
|
185
|
+
sock = Arborist.zmq_context.socket( :SUB )
|
186
|
+
sock.connect( self.event_api_url )
|
187
|
+
|
188
|
+
return sock
|
189
|
+
end
|
190
|
+
|
191
|
+
end # class Arborist::Client
|