vayacondios-server 0.2.11 → 0.3.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.
- data/.gitignore +3 -1
- data/.travis.yml +2 -0
- data/Gemfile +15 -9
- data/LICENSE.md +2 -6
- data/Procfile +1 -1
- data/README.md +656 -111
- data/Rakefile +89 -6
- data/bin/vcd +10 -0
- data/bin/vcd-server +8 -0
- data/config/database.yml +6 -0
- data/config/spec.example.yml +18 -0
- data/config/vayacondios.example.yml +15 -0
- data/config/vcd-server.rb +37 -0
- data/examples/configuration.rb +56 -0
- data/examples/event_stream.rb +19 -0
- data/examples/simple.rb +61 -0
- data/features/event.feature +319 -0
- data/features/events.feature +208 -0
- data/features/stash.feature +840 -0
- data/features/stashes.feature +492 -0
- data/features/step_definitions/stash_steps.rb +113 -0
- data/features/stream.feature +30 -0
- data/features/support/em.rb +14 -0
- data/features/support/env.rb +13 -0
- data/lib/vayacondios/configuration.rb +63 -0
- data/lib/vayacondios/server/api.rb +126 -0
- data/lib/vayacondios/server/api_options.rb +56 -0
- data/lib/vayacondios/server/configuration.rb +23 -0
- data/lib/vayacondios/server/driver.rb +71 -0
- data/lib/vayacondios/server/drivers/mongo.rb +126 -0
- data/lib/vayacondios/server/handlers/document_handler.rb +81 -0
- data/lib/vayacondios/server/handlers/event_handler.rb +31 -26
- data/lib/vayacondios/server/handlers/events_handler.rb +31 -0
- data/lib/vayacondios/server/handlers/stash_handler.rb +69 -0
- data/lib/vayacondios/server/handlers/stashes_handler.rb +49 -0
- data/lib/vayacondios/server/handlers/stream_handler.rb +39 -0
- data/lib/vayacondios/server/models/document.rb +87 -0
- data/lib/vayacondios/server/models/event.rb +198 -0
- data/lib/vayacondios/server/models/stash.rb +100 -0
- data/lib/vayacondios/server.rb +35 -0
- data/lib/vayacondios-server.rb +19 -13
- data/lib/vayacondios.rb +22 -0
- data/pom.xml +124 -4
- data/spec/configuration_spec.rb +41 -0
- data/spec/server/api_options_spec.rb +32 -0
- data/spec/server/api_spec.rb +279 -0
- data/spec/server/configuration_spec.rb +27 -0
- data/spec/server/drivers/mongo_spec.rb +107 -0
- data/spec/server/handlers/event_handler_spec.rb +62 -0
- data/spec/server/handlers/events_handler_spec.rb +51 -0
- data/spec/server/handlers/stash_handler_spec.rb +68 -0
- data/spec/server/handlers/stashes_handler_spec.rb +50 -0
- data/spec/server/handlers/stream_handler_spec.rb +5 -0
- data/spec/server/models/document_spec.rb +9 -0
- data/spec/server/models/event_spec.rb +185 -0
- data/spec/server/models/stash_spec.rb +95 -0
- data/spec/spec_helper.rb +23 -3
- data/spec/support/database_helper.rb +42 -0
- data/spec/support/log_helper.rb +19 -0
- data/spec/support/shared_context_for_events.rb +22 -0
- data/spec/support/shared_context_for_stashes.rb +24 -0
- data/spec/support/shared_examples_for_handlers.rb +32 -0
- data/src/main/java/com/infochimps/vayacondios/BaseClient.java +342 -0
- data/src/main/java/com/infochimps/vayacondios/HTTPClient.java +426 -0
- data/src/main/java/com/infochimps/vayacondios/VayacondiosClient.java +487 -65
- data/src/main/java/com/infochimps/vayacondios/test/IntegrationTest.java +3 -0
- data/src/test/java/com/infochimps/vayacondios/BaseClientTest.java +50 -0
- data/src/test/java/com/infochimps/vayacondios/HTTPClientIT.java +267 -0
- data/vayacondios-server.gemspec +9 -9
- metadata +127 -122
- checksums.yaml +0 -15
- data/.rspec +0 -2
- data/.yardopts +0 -10
- data/Guardfile +0 -41
- data/app/http_shim.rb +0 -71
- data/bin/vcd.sh +0 -27
- data/config/http_shim.rb +0 -43
- data/config/vayacondios.example.yaml +0 -7
- data/config/vayacondios.yaml +0 -7
- data/examples/java/ItemSetTest.java +0 -76
- data/lib/tasks/publish.rake +0 -23
- data/lib/tasks/spec.rake +0 -11
- data/lib/tasks/yard.rake +0 -2
- data/lib/vayacondios/client/config.rb +0 -7
- data/lib/vayacondios/client/configliere.rb +0 -38
- data/lib/vayacondios/client/cube_client.rb +0 -39
- data/lib/vayacondios/client/http_client.rb +0 -49
- data/lib/vayacondios/client/itemset.rb +0 -130
- data/lib/vayacondios/client/legacy_switch.rb +0 -43
- data/lib/vayacondios/client/notifier.rb +0 -123
- data/lib/vayacondios/client/zabbix_client.rb +0 -148
- data/lib/vayacondios/legacy_switch.rb +0 -43
- data/lib/vayacondios/server/errors/bad_request.rb +0 -6
- data/lib/vayacondios/server/errors/not_found.rb +0 -6
- data/lib/vayacondios/server/handlers/config_handler.rb +0 -32
- data/lib/vayacondios/server/handlers/itemset_handler.rb +0 -60
- data/lib/vayacondios/server/legacy_switch.rb +0 -43
- data/lib/vayacondios/server/model/config_document.rb +0 -89
- data/lib/vayacondios/server/model/document.rb +0 -25
- data/lib/vayacondios/server/model/event_document.rb +0 -94
- data/lib/vayacondios/server/model/itemset_document.rb +0 -126
- data/lib/vayacondios/server/rack/extract_methods.rb +0 -35
- data/lib/vayacondios/server/rack/jsonize.rb +0 -43
- data/lib/vayacondios/server/rack/params.rb +0 -50
- data/lib/vayacondios/server/rack/path.rb +0 -23
- data/lib/vayacondios/server/rack/path_validation.rb +0 -22
- data/lib/vayacondios/version.rb +0 -3
- data/lib/vayacondios-client.rb +0 -22
- data/scripts/hadoop_monitor/configurable.rb +0 -66
- data/scripts/hadoop_monitor/hadoop_attempt_scraper.rb +0 -45
- data/scripts/hadoop_monitor/hadoop_client.rb +0 -273
- data/scripts/hadoop_monitor/hadoop_monitor.rb +0 -101
- data/scripts/hadoop_monitor/hadoopable.rb +0 -65
- data/scripts/hadoop_monitor/machine_monitor.rb +0 -115
- data/scripts/s3_cataloger/buckets +0 -33
- data/scripts/s3_cataloger/foreach_bucket +0 -88
- data/scripts/s3_cataloger/parse_ls.py +0 -391
- data/spec/client/itemset_legacy_spec.rb +0 -55
- data/spec/client/itemset_spec.rb +0 -60
- data/spec/client/notifier_spec.rb +0 -120
- data/spec/server/config_spec.rb +0 -113
- data/spec/server/event_spec.rb +0 -103
- data/spec/server/itemset_legacy_spec.rb +0 -320
- data/spec/server/itemset_spec.rb +0 -317
- data/spec/server/rack/extract_methods_spec.rb +0 -60
- data/spec/server/rack/path_spec.rb +0 -36
- data/spec/server/rack/path_validation_spec.rb +0 -22
- data/spec/server/server_spec.rb +0 -20
- data/spec/support/mongo_cleaner.rb +0 -32
- data/src/main/java/ItemSetTest.java +0 -76
- data/src/main/java/com/infochimps/util/CurrentClass.java +0 -26
- data/src/main/java/com/infochimps/util/DebugUtil.java +0 -38
- data/src/main/java/com/infochimps/util/HttpHelper.java +0 -181
- data/src/main/java/com/infochimps/vayacondios/ItemSets.java +0 -373
- data/src/main/java/com/infochimps/vayacondios/LinkToVCD.java +0 -18
- data/src/main/java/com/infochimps/vayacondios/MemoryVCDShim.java +0 -84
- data/src/main/java/com/infochimps/vayacondios/Organization.java +0 -62
- data/src/main/java/com/infochimps/vayacondios/PathBuilder.java +0 -13
- data/src/main/java/com/infochimps/vayacondios/StandardVCDLink.java +0 -218
- data/src/main/java/com/infochimps/vayacondios/VCDIntegrationTest.java +0 -108
- data/src/test/java/com/infochimps/vayacondios/TestVayacondiosInMemory.java +0 -78
- data/vayacondios-client.gemspec +0 -25
@@ -1,76 +0,0 @@
|
|
1
|
-
import com.infochimps.vayacondios.Organization;
|
2
|
-
import com.infochimps.vayacondios.VayacondiosClient;
|
3
|
-
import com.infochimps.vayacondios.ItemSets;
|
4
|
-
import static com.infochimps.vayacondios.ItemSets.Item;
|
5
|
-
import static com.infochimps.vayacondios.ItemSets.ItemSet;
|
6
|
-
|
7
|
-
import java.io.*;
|
8
|
-
import java.util.*;
|
9
|
-
|
10
|
-
public class ItemSetTest {
|
11
|
-
private static final int VCD_PORT = 8000;
|
12
|
-
|
13
|
-
public static void main(String argv[]) throws IOException {
|
14
|
-
// Instantiate a new Vayacondios client.
|
15
|
-
VayacondiosClient client = new VayacondiosClient("localhost", VCD_PORT);
|
16
|
-
|
17
|
-
// Organizations can allow for testing and multiple environments
|
18
|
-
// (staging, development).
|
19
|
-
Organization org = client.organization("test");
|
20
|
-
|
21
|
-
// At the moment, only the itemsets protocol is supported via a
|
22
|
-
// Java API.
|
23
|
-
ItemSets isets = org.itemsets();
|
24
|
-
|
25
|
-
List<Item> foobar = Arrays.asList(new Item("foo"), new Item("bar"));
|
26
|
-
|
27
|
-
// All of the following are equivalent ways to clobber the itemset
|
28
|
-
// at topic my_topic and id my_id, replacing it with the items
|
29
|
-
// "foo" and "bar." The first and second exist to avoid
|
30
|
-
// instantiating new objects repeatedly when a code path must
|
31
|
-
// access many different topics and ids.
|
32
|
-
isets .create("my_topic", "my_id", foobar);
|
33
|
-
isets.topic("my_topic") .create( "my_id", foobar);
|
34
|
-
isets.topic("my_topic").itemSet("my_id").create( foobar);
|
35
|
-
|
36
|
-
List<Item> fetched;
|
37
|
-
|
38
|
-
// Similarly, these are all equivalent ways to fetch items.
|
39
|
-
fetched = isets .fetch("my_topic", "my_id");
|
40
|
-
fetched = isets.topic("my_topic") .fetch( "my_id");
|
41
|
-
fetched = isets.topic("my_topic").itemSet("my_id").fetch( );
|
42
|
-
|
43
|
-
ItemSet iset = isets.topic("my_topic").itemSet("my_id");
|
44
|
-
|
45
|
-
// foo and bar will be printed, along with their types: STRING
|
46
|
-
System.out.println("fetched items: " + fetched);
|
47
|
-
|
48
|
-
List<Item> bazqux = Arrays.asList(new Item("baz"), new Item("qux"));
|
49
|
-
|
50
|
-
// Updating an itemset with a list of items ensures the presence
|
51
|
-
// in the itemset of all of the items in the specified list.
|
52
|
-
isets .update("my_topic", "my_id", bazqux);
|
53
|
-
isets.topic("my_topic") .update( "my_id", bazqux);
|
54
|
-
isets.topic("my_topic").itemSet("my_id").update( bazqux);
|
55
|
-
|
56
|
-
// foo, bar, baz, and qux will all be printed.
|
57
|
-
System.out.println("after update: " + iset.fetch());
|
58
|
-
|
59
|
-
List<Item> barbaz = Arrays.asList(new Item("bar"), new Item("baz"));
|
60
|
-
|
61
|
-
// Updating an itemset with a list of items ensures the presence
|
62
|
-
// in the itemset of all of the items in the specified list.
|
63
|
-
isets .remove("my_topic", "my_id", barbaz);
|
64
|
-
isets.topic("my_topic") .remove( "my_id", barbaz);
|
65
|
-
isets.topic("my_topic").itemSet("my_id").remove( barbaz);
|
66
|
-
|
67
|
-
// foo and qux will now be printed
|
68
|
-
System.out.println("after removing: " + iset.fetch());
|
69
|
-
|
70
|
-
// Create an empty itemset to effectively delete it.
|
71
|
-
iset.create(Collections.EMPTY_LIST);
|
72
|
-
|
73
|
-
// foo and qux will now be printed
|
74
|
-
System.out.println("after deletion: " + iset.fetch());
|
75
|
-
}
|
76
|
-
}
|
data/lib/tasks/publish.rake
DELETED
@@ -1,23 +0,0 @@
|
|
1
|
-
$:.push File.expand_path('..', __FILE__)
|
2
|
-
require 'vayacondios/version'
|
3
|
-
|
4
|
-
Dir['*.gemspec'].each do |gemspec|
|
5
|
-
gem_name = gemspec.gsub(/\.gemspec/, '')
|
6
|
-
|
7
|
-
desc "Build #{gem_name} gem into the pkg directory"
|
8
|
-
task "build_#{gem_name}" do
|
9
|
-
FileUtils.rm_rf('pkg')
|
10
|
-
system "gem build #{gemspec}"
|
11
|
-
FileUtils.mkdir_p('pkg')
|
12
|
-
FileUtils.mv(Dir['*.gem'], 'pkg')
|
13
|
-
end
|
14
|
-
|
15
|
-
desc "Tags version, pushes to remote, and pushes #{gem_name} gem"
|
16
|
-
task "release_#{gem_name}" => "build_#{gem_name}" do
|
17
|
-
sh 'git', 'tag', '-m', "releasing #{gem_name}", "#{gem_name}-v#{Vayacondios::VERSION}"
|
18
|
-
branch = `git branch | awk -F '/* ' '{print $2}'`.strip
|
19
|
-
sh "git push origin #{branch}"
|
20
|
-
sh "git push origin #{gem_name}-v#{Vayacondios::VERSION}"
|
21
|
-
sh "ls pkg/#{gem_name}*.gem | xargs -n 1 gem push"
|
22
|
-
end
|
23
|
-
end
|
data/lib/tasks/spec.rake
DELETED
data/lib/tasks/yard.rake
DELETED
@@ -1,38 +0,0 @@
|
|
1
|
-
class Vayacondios
|
2
|
-
module Configliere
|
3
|
-
|
4
|
-
def load_from_vayacondios(organization, id, options = {})
|
5
|
-
options.symbolize_keys!.deep_merge!(organization: organization)
|
6
|
-
|
7
|
-
client = ::Vayacondios::HttpClient.receive(options.deep_compact!)
|
8
|
-
id = [id, options[:env]].compact.join('.')
|
9
|
-
|
10
|
-
begin
|
11
|
-
new_data = client.fetch(:config, id)
|
12
|
-
rescue ::Vayacondios::HttpClient::Error
|
13
|
-
warn "Unable to load vayacondios config '#{id}' for #{organization} at: #{client.host}:#{client.port}"
|
14
|
-
new_data = {}
|
15
|
-
end
|
16
|
-
deep_merge! new_data
|
17
|
-
self
|
18
|
-
end
|
19
|
-
|
20
|
-
def save_to_vayacondios(organization, id, options = {})
|
21
|
-
options.symbolize_keys!.deep_merge!(organization: organization)
|
22
|
-
|
23
|
-
client = ::Vayacondios::HttpClient.receive(options.deep_compact!)
|
24
|
-
id = [id, options[:env]].compact.join('.')
|
25
|
-
|
26
|
-
begin
|
27
|
-
client.insert(self.to_hash, :config, id)
|
28
|
-
rescue ::Vayacondios::HttpClient::Error
|
29
|
-
warn "Unable to save vayacondios config '#{id}' for #{organization} at: #{client.host}:#{client.port}"
|
30
|
-
end
|
31
|
-
self
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
::Configliere::Param.class_eval do
|
37
|
-
include ::Vayacondios::Configliere
|
38
|
-
end
|
@@ -1,39 +0,0 @@
|
|
1
|
-
class Vayacondios
|
2
|
-
class CubeClient
|
3
|
-
include Gorillib::Model
|
4
|
-
|
5
|
-
field :host, String, :default => 'localhost'
|
6
|
-
field :port, Integer, :default => 6000
|
7
|
-
|
8
|
-
class Error < StandardError; end
|
9
|
-
|
10
|
-
def uri
|
11
|
-
return @uri if @uri
|
12
|
-
|
13
|
-
uri_str = "http://#{host}:#{port}/1.0"
|
14
|
-
@uri ||= URI(uri_str)
|
15
|
-
end
|
16
|
-
|
17
|
-
def event(topic, document = {})
|
18
|
-
request(:post, File.join(uri.path, 'event'), MultiJson.dump(document))
|
19
|
-
end
|
20
|
-
|
21
|
-
private
|
22
|
-
|
23
|
-
def request(method, path, document=nil)
|
24
|
-
http = Net::HTTP.new(uri.host, uri.port)
|
25
|
-
|
26
|
-
params = [method.to_sym, path]
|
27
|
-
params += [document, {'Content-Type' => 'application/json'}] unless document.nil?
|
28
|
-
|
29
|
-
response = http.send *params
|
30
|
-
|
31
|
-
if Net::HTTPSuccess === response
|
32
|
-
MultiJson.load(response.body) rescue response.body
|
33
|
-
else
|
34
|
-
raise Error.new("Error (#{response.code}) while #{method.to_s == 'get' ? 'fetching' : 'inserting'} document: " + response.body)
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
@@ -1,49 +0,0 @@
|
|
1
|
-
class Vayacondios
|
2
|
-
class HttpClient
|
3
|
-
include Gorillib::Model
|
4
|
-
|
5
|
-
field :host, String, :default => 'localhost'
|
6
|
-
field :port, String, :default => '8000'
|
7
|
-
field :organization, String, :default => 'infochimps'
|
8
|
-
|
9
|
-
class Error < StandardError; end
|
10
|
-
|
11
|
-
def uri
|
12
|
-
return @uri if @uri
|
13
|
-
|
14
|
-
uri_str = "http://#{host}:#{port}/v1"
|
15
|
-
uri_str += "/#{organization}" if organization
|
16
|
-
@uri ||= URI(uri_str)
|
17
|
-
end
|
18
|
-
|
19
|
-
def fetch(type, id)
|
20
|
-
request(:get, type, id)
|
21
|
-
end
|
22
|
-
|
23
|
-
def insert(document = {}, type = nil, id = nil)
|
24
|
-
id ||= document.delete(:_id) || document.delete('_id')
|
25
|
-
type ||= document.delete(:_type) || document.delete('_type')
|
26
|
-
|
27
|
-
request(:post, type, id, MultiJson.dump(document))
|
28
|
-
end
|
29
|
-
|
30
|
-
private
|
31
|
-
|
32
|
-
def request(method, type, id = nil, document = nil)
|
33
|
-
path = File.join(uri.path, type.to_s, *id.to_s.split(/\W/))
|
34
|
-
http = Net::HTTP.new(uri.host, uri.port)
|
35
|
-
|
36
|
-
params = [method.to_sym, path]
|
37
|
-
params += [document, {'Content-Type' => 'application/json'}] unless document.nil?
|
38
|
-
|
39
|
-
response = http.send *params
|
40
|
-
|
41
|
-
if Net::HTTPSuccess === response
|
42
|
-
MultiJson.load(response.body) rescue response.body
|
43
|
-
else
|
44
|
-
raise Error.new("Error (#{response.code}) while #{method.to_s == 'get' ? 'fetching' : 'inserting'} document: " + response.body)
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
@@ -1,130 +0,0 @@
|
|
1
|
-
require 'gorillib/logger/log'
|
2
|
-
require 'net/http'
|
3
|
-
require 'multi_json'
|
4
|
-
require_relative 'config'
|
5
|
-
require_relative 'legacy_switch'
|
6
|
-
|
7
|
-
class Vayacondios
|
8
|
-
class Client
|
9
|
-
class ItemSet
|
10
|
-
def initialize host, port, organization=nil, topic=nil, id=nil
|
11
|
-
@host = host
|
12
|
-
@port = port
|
13
|
-
@organization = organization
|
14
|
-
@topic = topic
|
15
|
-
@id = id
|
16
|
-
end
|
17
|
-
|
18
|
-
def fetch organization=nil, topic=nil, id=nil
|
19
|
-
resp = execute_request(_req(:fetch, nil, organization, topic, id)) and
|
20
|
-
Vayacondios.legacy_switch.extract_response(resp)
|
21
|
-
end
|
22
|
-
|
23
|
-
def update ary, organization=nil, topic=nil, id=nil
|
24
|
-
execute_request(_req(:update, ary, organization, topic, id))
|
25
|
-
end
|
26
|
-
|
27
|
-
def create ary, organization=nil, topic=nil, id=nil
|
28
|
-
execute_request(_req(:create, ary, organization, topic, id))
|
29
|
-
end
|
30
|
-
|
31
|
-
def remove ary, organization=nil, topic=nil, id=nil
|
32
|
-
execute_request(_req(:remove, ary, organization, topic, id))
|
33
|
-
end
|
34
|
-
|
35
|
-
private
|
36
|
-
|
37
|
-
def execute_request req
|
38
|
-
begin
|
39
|
-
resp = Net::HTTP.start(@host, @port) do |http|
|
40
|
-
http.request(req)
|
41
|
-
end.body
|
42
|
-
result = MultiJson.decode(resp) unless resp.nil? or resp.empty?
|
43
|
-
(result.respond_to?(:has_key?) and result.has_key? "error") ? nil : result
|
44
|
-
rescue StandardError => ex
|
45
|
-
Log.warn("problem contacting vayacondios: #{ex.message}")
|
46
|
-
Log.debug(ex.backtrace.join("\n"))
|
47
|
-
nil
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
def path organization, topic, id
|
52
|
-
if ((the_organization = (organization || @organization)).nil? ||
|
53
|
-
(the_topic = (topic || @topic )).nil? ||
|
54
|
-
(the_id = (id || @id )).nil?)
|
55
|
-
raise ArgumentError.new("must provide organization, topic, and id!")
|
56
|
-
end
|
57
|
-
|
58
|
-
['/v1', the_organization, 'itemset', the_topic, the_id].join("/")
|
59
|
-
end
|
60
|
-
|
61
|
-
# This is the only private method that is tested.
|
62
|
-
def _req type, ary=nil, organization=nil, topic=nil, id=nil
|
63
|
-
|
64
|
-
the_path = path(organization, topic, id)
|
65
|
-
headers = {"content-type" => "application/json"}
|
66
|
-
headers.merge!("x-method" => "PATCH") if type == :update
|
67
|
-
|
68
|
-
case type
|
69
|
-
when :fetch then Net::HTTP::Get
|
70
|
-
when :create then Net::HTTP::Put
|
71
|
-
when :update then Net::HTTP::Put
|
72
|
-
when :remove then Net::HTTP::Delete
|
73
|
-
else raise ArgumentError.new("invalid type: #{type}")
|
74
|
-
end.new(the_path, headers).tap do |req|
|
75
|
-
unless type == :fetch
|
76
|
-
req.body =
|
77
|
-
MultiJson.encode(Vayacondios.legacy_switch.wrap_contents(ary))
|
78
|
-
end
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
# Subclasses should implement the remove_items(arr) and
|
84
|
-
# add_items(arr) methods, both of which will be called with arrays
|
85
|
-
# when the items in an itemset change. The run method polls the
|
86
|
-
# provided itemset at a specified interval and calls these methods
|
87
|
-
# appropriately.
|
88
|
-
class ItemSetListener
|
89
|
-
POLL_WAIT_SEC=2
|
90
|
-
|
91
|
-
def initialize itemset, poll_wait_sec = POLL_WAIT_SEC
|
92
|
-
@itemset = itemset
|
93
|
-
@items = []
|
94
|
-
@poll_wait_sec = poll_wait_sec
|
95
|
-
end
|
96
|
-
|
97
|
-
def run
|
98
|
-
setup
|
99
|
-
loop do
|
100
|
-
new_items = @itemset.fetch || []
|
101
|
-
|
102
|
-
Log.debug "currently configured: #{@items.inspect}"
|
103
|
-
Log.debug "new items: #{new_items.inspect}"
|
104
|
-
|
105
|
-
add_items(new_items - @items)
|
106
|
-
remove_items(@items - new_items)
|
107
|
-
|
108
|
-
@items = new_items
|
109
|
-
|
110
|
-
sleep @poll_wait_sec
|
111
|
-
end
|
112
|
-
teardown
|
113
|
-
end
|
114
|
-
|
115
|
-
protected
|
116
|
-
|
117
|
-
def add_items
|
118
|
-
raise NoMethodError.new("class #{self.class.name} must override add_items")
|
119
|
-
end
|
120
|
-
|
121
|
-
def remove_items
|
122
|
-
raise NoMethodError.new("class #{self.class.name} must override remove_items")
|
123
|
-
end
|
124
|
-
|
125
|
-
def setup() end
|
126
|
-
def teardown() end
|
127
|
-
|
128
|
-
end
|
129
|
-
end
|
130
|
-
end
|
@@ -1,43 +0,0 @@
|
|
1
|
-
require 'gorillib/logger/log'
|
2
|
-
|
3
|
-
class Vayacondios
|
4
|
-
# Are we operating on JSON Hashes (Vayacondios) or on JSON arrays
|
5
|
-
# (Vayacondios Legacy)? These classes determine which to use.
|
6
|
-
|
7
|
-
class StandardContentsHandler
|
8
|
-
def wrap_contents(contents) {contents: contents} end
|
9
|
-
def extract_contents(document) document['contents'] end
|
10
|
-
def extract_response(document) document['contents'] end
|
11
|
-
def proper_request(document) true end
|
12
|
-
end
|
13
|
-
|
14
|
-
class LegacyContentsHandler
|
15
|
-
def wrap_contents(contents) contents end
|
16
|
-
def extract_contents(document) document end
|
17
|
-
def extract_response(document) document end
|
18
|
-
def proper_request(document) true end
|
19
|
-
end
|
20
|
-
|
21
|
-
@@legacy_switch = nil
|
22
|
-
|
23
|
-
def self.legacy_switch
|
24
|
-
if @@legacy_switch.nil?
|
25
|
-
legacy_mode_on = Settings[:vayacondios][:legacy]
|
26
|
-
@@legacy_switch = get_legacy_switch(legacy_mode_on)
|
27
|
-
Log.info("using #{legacy_mode_on ? 'legacy' : 'standard'} mode")
|
28
|
-
end
|
29
|
-
@@legacy_switch
|
30
|
-
end
|
31
|
-
|
32
|
-
def self.force_legacy_mode on
|
33
|
-
Log.info("forcing #{on ? 'legacy' : 'standard'} mode")
|
34
|
-
@@legacy_switch = get_legacy_switch on
|
35
|
-
end
|
36
|
-
|
37
|
-
private
|
38
|
-
|
39
|
-
def self.get_legacy_switch on
|
40
|
-
(on ? LegacyContentsHandler : StandardContentsHandler).new
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
@@ -1,123 +0,0 @@
|
|
1
|
-
class Vayacondios
|
2
|
-
|
3
|
-
class_attribute :notifier
|
4
|
-
|
5
|
-
class Notifier < Vayacondios
|
6
|
-
attr_accessor :client
|
7
|
-
|
8
|
-
def prepare(obj)
|
9
|
-
case
|
10
|
-
when obj.respond_to?(:to_inspectable) then obj.to_inspectable
|
11
|
-
when obj.respond_to?(:to_wire) then obj.to_wire
|
12
|
-
when obj.respond_to?(:to_hash) then obj.to_hash
|
13
|
-
else
|
14
|
-
raise ArgumentError.new("Cannot notify '#{obj.inspect}' -- require a hash-like object.")
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
def notify(topic, cargo = {})
|
19
|
-
NoMethodError.unimplemented_method(self)
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
class NullNotifier < Notifier
|
24
|
-
def initialize(*args) ; end
|
25
|
-
|
26
|
-
def notify topic, cargo={}
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
class LogNotifier < Notifier
|
31
|
-
|
32
|
-
def initialize(options = {})
|
33
|
-
@client = options[:log] || Log
|
34
|
-
end
|
35
|
-
|
36
|
-
def notify(topic, cargo = {})
|
37
|
-
prepped = prepare(cargo)
|
38
|
-
level = prepped.delete(:level) || :info
|
39
|
-
message = "Notification: #{topic.inspect}."
|
40
|
-
message += " Reason: #{prepped.delete(:reason)}." if prepped[:reason]
|
41
|
-
message += " Cargo: #{prepped.inspect}"
|
42
|
-
client.send(level, message)
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
class HttpNotifier < Notifier
|
47
|
-
|
48
|
-
def initialize(options = {})
|
49
|
-
@client = Vayacondios::HttpClient.receive(options)
|
50
|
-
end
|
51
|
-
|
52
|
-
def notify(topic, cargo = {})
|
53
|
-
prepped = prepare(cargo)
|
54
|
-
client.insert(prepped, :event, topic)
|
55
|
-
nil
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
class CubeNotifier < Notifier
|
60
|
-
def initialize(options={})
|
61
|
-
@client = Vayacondios::CubeClient.receive(options)
|
62
|
-
end
|
63
|
-
def notify topic, cargo={}
|
64
|
-
prepped = prepare(cargo)
|
65
|
-
client.event(topic, prepped)
|
66
|
-
nil
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
class ZabbixNotifier < Notifier
|
71
|
-
def initialize options={}
|
72
|
-
@client = Vayacondios::ZabbixClient.receive(options)
|
73
|
-
end
|
74
|
-
def notify(topic, cargo={})
|
75
|
-
prepped = prepare(cargo)
|
76
|
-
client.insert(topic, prepped)
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
class NotifierFactory
|
81
|
-
def self.receive(attrs = {})
|
82
|
-
type = attrs[:type]
|
83
|
-
case type
|
84
|
-
when 'http' then HttpNotifier.new(attrs)
|
85
|
-
when 'cube' then CubeNotifier.new(attrs)
|
86
|
-
when 'zabbix' then ZabbixNotifier.new(attrs)
|
87
|
-
when 'log' then LogNotifier.new(attrs)
|
88
|
-
when 'none','null' then NullNotifier.new(attrs)
|
89
|
-
else
|
90
|
-
raise ArgumentError, "<#{type}> is not a valid build option"
|
91
|
-
end
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
def self.default_notifier(log = nil) NotifierFactory.receive(type: 'log', log: log) ; end
|
96
|
-
|
97
|
-
module Notifications
|
98
|
-
|
99
|
-
def notify(topic, cargo = {})
|
100
|
-
notifier.notify(topic, cargo)
|
101
|
-
end
|
102
|
-
|
103
|
-
def self.included klass
|
104
|
-
if klass.ancestors.include? Gorillib::Model
|
105
|
-
klass.class_eval do
|
106
|
-
field :notifier, Vayacondios::NotifierFactory, default: Vayacondios.default_notifier, :doc => "Notifier used to notify out of band data"
|
107
|
-
|
108
|
-
def receive_notifier params
|
109
|
-
params.merge!(log: try(:log)) if params[:type] == 'log'
|
110
|
-
@notifier = Vayacondios::NotifierFactory.receive(params)
|
111
|
-
end
|
112
|
-
end
|
113
|
-
else
|
114
|
-
klass.class_attribute :notifier
|
115
|
-
klass.notifier = Vayacondios.default_notifier try(:log)
|
116
|
-
end
|
117
|
-
end
|
118
|
-
|
119
|
-
end
|
120
|
-
|
121
|
-
extend Notifications
|
122
|
-
self.notifier = default_notifier
|
123
|
-
end
|
@@ -1,148 +0,0 @@
|
|
1
|
-
require 'socket'
|
2
|
-
|
3
|
-
class Vayacondios
|
4
|
-
|
5
|
-
# Used for sending events to a Zabbix server.
|
6
|
-
#
|
7
|
-
# An 'event' from Vayacondios' perspective is an arbitrary Hash.
|
8
|
-
#
|
9
|
-
# An 'event' from Zabbix's perspective is a tuple of values:
|
10
|
-
#
|
11
|
-
# * time
|
12
|
-
# * host
|
13
|
-
# * key
|
14
|
-
# * value
|
15
|
-
#
|
16
|
-
# This client will accept a Vayacondios event and internally
|
17
|
-
# translate it into a set of Zabbix events.
|
18
|
-
#
|
19
|
-
# @example A CPU monitoring notification
|
20
|
-
#
|
21
|
-
# notify "foo-server.example.com", cpu: {
|
22
|
-
# util: {
|
23
|
-
# user: 0.20,
|
24
|
-
# idle: 0.70,
|
25
|
-
# sys: 0.10
|
26
|
-
# },
|
27
|
-
# load: 1.3
|
28
|
-
# }
|
29
|
-
#
|
30
|
-
# would get turned into the following events when written to Zabbix:
|
31
|
-
#
|
32
|
-
# @example The CPU monitoring notification translated to Zabbix events
|
33
|
-
#
|
34
|
-
# [
|
35
|
-
# { host: "foo-server.example.com", key: "cpu.util.user", value: 0.20 }
|
36
|
-
# { host: "foo-server.example.com", key: "cpu.util.idle", value: 0.70 },
|
37
|
-
# { host: "foo-server.example.com", key: "cpu.util.sys", value: 0.10 },
|
38
|
-
# { host: "foo-server.example.com", key: "cpu.load", value: 1.3 }
|
39
|
-
# ]
|
40
|
-
#
|
41
|
-
# Zabbix will interpret the time as the time it receives each event.
|
42
|
-
#
|
43
|
-
# The following links provide details on the protocol used by Zabbix
|
44
|
-
# to receive events:
|
45
|
-
#
|
46
|
-
# * https://www.zabbix.com/forum/showthread.php?t=20047&highlight=sender
|
47
|
-
# * https://gist.github.com/1170577
|
48
|
-
# * http://spin.atomicobject.com/2012/10/30/collecting-metrics-from-ruby-processes-using-zabbix-trappers/?utm_source=rubyflow&utm_medium=ao&utm_campaign=collecting-metrics-zabix
|
49
|
-
class ZabbixClient
|
50
|
-
include Gorillib::Builder
|
51
|
-
|
52
|
-
attr_accessor :socket
|
53
|
-
|
54
|
-
field :host, String, :default => 'localhost', :doc => "Host for the Zabbix server"
|
55
|
-
field :port, Integer, :default => 10051, :doc => "Port for the Zabbix server"
|
56
|
-
|
57
|
-
# Insert events to a Zabbix server.
|
58
|
-
#
|
59
|
-
# The `topic` will be used as the name of the Zabbix host to
|
60
|
-
# associate event data to.
|
61
|
-
#
|
62
|
-
# As per the documentation for the [Zabbix sender
|
63
|
-
# protocol](https://www.zabbix.com/wiki/doc/tech/proto/zabbixsenderprotocol),
|
64
|
-
# a new TCP connection will be created for each event.
|
65
|
-
#
|
66
|
-
# @param [String] topic
|
67
|
-
# @param [Hash] cargo
|
68
|
-
# Array<Hash>] text
|
69
|
-
def insert topic, cargo={}
|
70
|
-
self.socket = TCPSocket.new(host, port)
|
71
|
-
send_request(topic, cargo)
|
72
|
-
handle_response
|
73
|
-
self.socket.close
|
74
|
-
end
|
75
|
-
|
76
|
-
private
|
77
|
-
|
78
|
-
# :nodoc
|
79
|
-
def send_request topic, cargo
|
80
|
-
socket.write(payload(topic, cargo))
|
81
|
-
end
|
82
|
-
|
83
|
-
# :nodoc
|
84
|
-
def handle_response
|
85
|
-
header = socket.recv(5)
|
86
|
-
if header == "ZBXD\1"
|
87
|
-
data_header = socket.recv(8)
|
88
|
-
length = data_header[0,4].unpack("i")[0]
|
89
|
-
response = MultiJson.load(socket.recv(length))
|
90
|
-
puts response["info"]
|
91
|
-
else
|
92
|
-
puts "Invalid response: #{header}"
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
# :nodoc
|
97
|
-
def payload topic, cargo={}
|
98
|
-
body = body_for(topic, cargo)
|
99
|
-
header_for(body) + body
|
100
|
-
end
|
101
|
-
|
102
|
-
# :nodoc
|
103
|
-
def body_for topic, cargo={}
|
104
|
-
MultiJson.dump({request: "sender data", data: zabbix_events_from(topic, cargo) })
|
105
|
-
end
|
106
|
-
|
107
|
-
# :nodoc
|
108
|
-
def header_for body
|
109
|
-
length = body.bytesize
|
110
|
-
"ZBXD\1".encode("ascii") + [length].pack("i") + "\x00\x00\x00\x00"
|
111
|
-
end
|
112
|
-
|
113
|
-
# :nodoc
|
114
|
-
def zabbix_events_from topic, cargo, scope=''
|
115
|
-
events = []
|
116
|
-
case cargo
|
117
|
-
when Hash
|
118
|
-
cargo.each_pair do |key, value|
|
119
|
-
events += zabbix_events_from(topic, value, new_scope(scope, key))
|
120
|
-
end
|
121
|
-
when Array
|
122
|
-
cargo.each_with_index do |item, index|
|
123
|
-
events += zabbix_events_from(topic, item, new_scope(scope, index))
|
124
|
-
end
|
125
|
-
else
|
126
|
-
events << event_body(topic, scope, cargo)
|
127
|
-
end
|
128
|
-
events
|
129
|
-
end
|
130
|
-
|
131
|
-
# :nodoc
|
132
|
-
def new_scope(current_scope, new_scope)
|
133
|
-
[current_scope, new_scope].map(&:to_s).reject(&:empty?).join('.')
|
134
|
-
end
|
135
|
-
|
136
|
-
# :nodoc
|
137
|
-
def event_body topic, scope, cargo
|
138
|
-
value = case cargo
|
139
|
-
when Hash then cargo[:value]
|
140
|
-
when Array then cargo.first
|
141
|
-
else cargo
|
142
|
-
end
|
143
|
-
{ host: topic, key: scope, value: value }
|
144
|
-
end
|
145
|
-
|
146
|
-
end
|
147
|
-
end
|
148
|
-
|