flumify 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.bundle/config ADDED
@@ -0,0 +1,2 @@
1
+ ---
2
+ BUNDLE_DISABLE_SHARED_GEMS: "1"
data/.rvmrc ADDED
@@ -0,0 +1,2 @@
1
+ rvm use ruby-1.8.7-p302@flumify
2
+
data/Gemfile ADDED
@@ -0,0 +1,13 @@
1
+ source :gemcutter
2
+ source "http://gems.trafficbroker.co.uk"
3
+
4
+ # Specify your gem's dependencies in ace.gemspec
5
+ gemspec
6
+
7
+ group :test do
8
+ gem 'rspec', '2.5.0'
9
+ end
10
+
11
+ group :development do
12
+ gem "fwd", "0.2.0"
13
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,29 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ flumify (0.0.1)
5
+ net-ssh (~> 2.1.4)
6
+
7
+ GEM
8
+ remote: http://rubygems.org/
9
+ remote: http://gems.trafficbroker.co.uk/
10
+ specs:
11
+ diff-lcs (1.1.2)
12
+ fwd (0.2.0)
13
+ net-ssh (2.1.4)
14
+ rspec (2.5.0)
15
+ rspec-core (~> 2.5.0)
16
+ rspec-expectations (~> 2.5.0)
17
+ rspec-mocks (~> 2.5.0)
18
+ rspec-core (2.5.2)
19
+ rspec-expectations (2.5.0)
20
+ diff-lcs (~> 1.1.2)
21
+ rspec-mocks (2.5.0)
22
+
23
+ PLATFORMS
24
+ ruby
25
+
26
+ DEPENDENCIES
27
+ flumify!
28
+ fwd (= 0.2.0)
29
+ rspec (= 2.5.0)
data/README ADDED
File without changes
File without changes
@@ -0,0 +1,10 @@
1
+ require "rubygems"
2
+ require File.join(File.dirname(__FILE__), %w[.. lib flume_master])
3
+
4
+ logical_nodes = ["a","b","c","d", "e","f"]
5
+ logical_nodes = logical_nodes.map {|node| "#{node}.my.machine.ip"}
6
+
7
+ master = FlumeMaster.new(:host => "flume.master", :username => "user", :password => "password")
8
+
9
+
10
+ master.decommission(logical_nodes)
@@ -0,0 +1,19 @@
1
+ require "rubygems"
2
+ require File.join(File.dirname(__FILE__), %w[.. lib flume_master])
3
+ require File.join(File.dirname(__FILE__), %w[.. lib flumify])
4
+
5
+
6
+ config = Flumify.new("machine-to-configure") do
7
+ internal_collector :host => "internal-collector", :port => 35853
8
+ external_collector :host => "external-collector", :port => 35853
9
+
10
+ logical_node "access-logs", {:tail => "/mnt/logs/*.log", :bucket => "logs"}
11
+ logical_node "advert-clicks", {:tail => "/mnt/logs/clicks.log", :bucket => "clicks"}
12
+
13
+ end
14
+
15
+ master = FlumeMaster.new(:host => "flume.master", :username => "user", :password => "password")
16
+ master.apply(config)
17
+
18
+
19
+
data/flumify.gemspec ADDED
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "flumify/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "flumify"
7
+ s.version = Flumify::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Ryan Greenhall", "Tom Hall"]
10
+ s.email = ["ryan.greenhall@gmail.com"]
11
+ s.homepage = ""
12
+ s.summary = %q{Simple flume configuration}
13
+ s.description = %q{}
14
+
15
+ s.rubyforge_project = "flumify"
16
+
17
+ s.add_dependency("net-ssh", ["~> 2.1.4"])
18
+
19
+ s.files = `git ls-files`.split("\n")
20
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
21
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
22
+ s.require_paths = ["lib"]
23
+ end
@@ -0,0 +1,41 @@
1
+ require "rubygems"
2
+ require 'net/ssh'
3
+ require File.join(File.dirname(__FILE__), "ssh_connection")
4
+
5
+ class FlumeMaster
6
+ def initialize(opts)
7
+ @connection = SSHConnection.new({ :host => opts[:host],
8
+ :username => opts[:username],
9
+ :password => opts[:password]})
10
+ @connection.debug = true if opts[:debug] == true
11
+ end
12
+
13
+ def apply(config)
14
+ config.logical_nodes.each do |logical_node_command|
15
+ execute logical_node_command
16
+ end
17
+
18
+ config.node_configurations.each do |config|
19
+ config = config.gsub("\"", "\\\"")
20
+ execute "flume shell -c localhost -e \"exec multiconfig '#{config}'\""
21
+ end
22
+ end
23
+
24
+ def decommission(nodes)
25
+ nodes.each do |node|
26
+ execute "flume shell -c localhost -e 'exec decommission #{node}'"
27
+ execute "flume shell -c localhost -e 'exec purge #{node}'"
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ def execute(command)
34
+ 3.times do
35
+ response = @connection.send_command command
36
+ puts response
37
+ break if response.include? "Command succeeded"
38
+ sleep 3
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,3 @@
1
+ module Flumify
2
+ VERSION = "0.0.1"
3
+ end
data/lib/flumify.rb ADDED
@@ -0,0 +1,35 @@
1
+ require File.join(File.dirname(__FILE__), "ssh_connection")
2
+ require File.join(File.dirname(__FILE__), "flume_master")
3
+
4
+ class Flumify
5
+
6
+ attr_accessor :the_internal_collector, :the_external_collector, :logical_nodes, :node_configurations
7
+
8
+ def initialize(server, &blk)
9
+ @server = server
10
+ @logical_nodes = []
11
+ @node_configurations = []
12
+ instance_eval(&blk) if blk
13
+ end
14
+
15
+ def internal_collector(collector)
16
+ @the_internal_collector = collector
17
+ end
18
+
19
+ def external_collector(collector)
20
+ @the_external_collector = collector
21
+ end
22
+
23
+ def logical_node(name, opts)
24
+ @logical_nodes << "flume shell -c localhost -e 'exec spawn #{@server} #{name}.#{@server}'"
25
+
26
+ if opts[:tail].include? "*"
27
+ split = opts[:tail].split("*")
28
+ directory = split[0]
29
+ glob_pattern = ".*" + split[1]
30
+ @node_configurations << "#{name}.#{@server} : tailDir( \"#{directory}\", \"#{glob_pattern}\" ) | { value(\"bucket\", \"#{opts[:bucket]}\") => agentBEChain(\"#{@the_internal_collector[:host]}:#{@the_internal_collector[:port]}\",\"#{@the_external_collector[:host]}:#{@the_external_collector[:port]}\") };"
31
+ else
32
+ @node_configurations << "#{name}.#{@server} : tail( \"#{opts[:tail]}\", true ) | { value(\"bucket\", \"#{opts[:bucket]}\") => agentBEChain(\"#{@the_internal_collector[:host]}:#{@the_internal_collector[:port]}\",\"#{@the_external_collector[:host]}:#{@the_external_collector[:port]}\") };"
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,15 @@
1
+ class SSHConnection
2
+ attr_accessor :debug
3
+
4
+ def initialize(config)
5
+ @connection = Net::SSH.start(config[:host], config[:username], :password => config[:password])
6
+ end
7
+
8
+ def send_command(commandstr)
9
+ if !@debug
10
+ @connection.exec! commandstr
11
+ else
12
+ puts "command: #{commandstr}"
13
+ end
14
+ end
15
+ end
data/rakefile ADDED
@@ -0,0 +1,12 @@
1
+ require 'rspec/core/rake_task'
2
+ require 'bundler'
3
+
4
+ Bundler::GemHelper.install_tasks
5
+
6
+ desc 'Default: run specs.'
7
+ task :default => :spec
8
+
9
+ desc "Run specs"
10
+ RSpec::Core::RakeTask.new do |t|
11
+ t.pattern = "./spec/**/*_spec.rb"
12
+ end
@@ -0,0 +1,68 @@
1
+ require File.join(File.dirname(__FILE__), "../lib/flumify")
2
+
3
+ describe "Flumify" do
4
+
5
+ it "allows collectors to be specified" do
6
+ config = Flumify.new("ec2.us-west-1a") do
7
+ internal_collector "ec2-foo"
8
+ external_collector "ec2-bar"
9
+
10
+ logical_node "query", {:tail => "/my/file", :bucket => "ask-query"}
11
+ logical_node "adclick", {:tail => "/my/file", :bucket => "ask-query"}
12
+ logical_node "redirect", {:tail => "/my/file", :bucket => "ask-query"}
13
+ logical_node "query", {:tail => "/my/file", :bucket => "ask-query"}
14
+ end
15
+
16
+ config.the_internal_collector.should == "ec2-foo"
17
+ config.the_external_collector.should == "ec2-bar"
18
+ end
19
+
20
+ it "allows logical nodes to be specified" do
21
+ config = Flumify.new("ec2.us-west-1a") do
22
+ internal_collector "ec2-foo"
23
+ external_collector "ec2-bar"
24
+
25
+ logical_node "query", {:tail => "/my/file", :bucket => "ask-query"}
26
+ end
27
+
28
+ config.logical_nodes.should include "flume shell -c localhost -e 'exec spawn ec2.us-west-1a query.ec2.us-west-1a'"
29
+ end
30
+
31
+ it "creates node configuration" do
32
+ config = Flumify.new("ec2.us-west-1a") do
33
+ internal_collector :host => "ec2-foo", :port => 35853
34
+ external_collector :host => "ec2-bar", :port => 35853
35
+
36
+ logical_node "query", {:tail => "/path/to/query.log", :bucket => "ask-query"}
37
+ end
38
+
39
+ config.node_configurations.should include "query.ec2.us-west-1a : tail( \"/path/to/query.log\", true ) | { value(\"bucket\", \"ask-query\") => agentBEChain(\"ec2-foo:35853\",\"ec2-bar:35853\") };"
40
+ config.node_configurations.length.should == 1
41
+ end
42
+
43
+ it "can create multiple node configurations" do
44
+ config = Flumify.new("ec2.us-west-1a") do
45
+ internal_collector :host => "ec2-foo", :port => 35853
46
+ external_collector :host => "ec2-bar", :port => 35853
47
+
48
+ logical_node "query", {:tail => "/path/to/query.log", :bucket => "ask-query"}
49
+ logical_node "click", {:tail => "/path/to/click.log", :bucket => "ask-click"}
50
+ end
51
+
52
+ config.node_configurations.should include "query.ec2.us-west-1a : tail( \"/path/to/query.log\", true ) | { value(\"bucket\", \"ask-query\") => agentBEChain(\"ec2-foo:35853\",\"ec2-bar:35853\") };"
53
+ config.node_configurations.should include "click.ec2.us-west-1a : tail( \"/path/to/click.log\", true ) | { value(\"bucket\", \"ask-click\") => agentBEChain(\"ec2-foo:35853\",\"ec2-bar:35853\") };"
54
+ config.node_configurations.length.should == 2
55
+ end
56
+
57
+ it "allows multiple log files to be specified" do
58
+ config = Flumify.new("ec2.us-west-1a") do
59
+ internal_collector :host => "ec2-foo", :port => 35853
60
+ external_collector :host => "ec2-bar", :port => 35853
61
+
62
+ logical_node "query", {:tail => "/path/to/*.log", :bucket => "ask-query"}
63
+ end
64
+
65
+ config.node_configurations.should include "query.ec2.us-west-1a : tailDir( \"/path/to/\", \".*.log\" ) | { value(\"bucket\", \"ask-query\") => agentBEChain(\"ec2-foo:35853\",\"ec2-bar:35853\") };"
66
+ config.node_configurations.length.should == 1
67
+ end
68
+ end
metadata ADDED
@@ -0,0 +1,98 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: flumify
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Ryan Greenhall
14
+ - Tom Hall
15
+ autorequire:
16
+ bindir: bin
17
+ cert_chain: []
18
+
19
+ date: 2011-05-26 00:00:00 +01:00
20
+ default_executable:
21
+ dependencies:
22
+ - !ruby/object:Gem::Dependency
23
+ name: net-ssh
24
+ prerelease: false
25
+ requirement: &id001 !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ~>
29
+ - !ruby/object:Gem::Version
30
+ hash: 3
31
+ segments:
32
+ - 2
33
+ - 1
34
+ - 4
35
+ version: 2.1.4
36
+ type: :runtime
37
+ version_requirements: *id001
38
+ description: ""
39
+ email:
40
+ - ryan.greenhall@gmail.com
41
+ executables: []
42
+
43
+ extensions: []
44
+
45
+ extra_rdoc_files: []
46
+
47
+ files:
48
+ - .bundle/config
49
+ - .rvmrc
50
+ - Gemfile
51
+ - Gemfile.lock
52
+ - README
53
+ - config/config.yaml
54
+ - example/decommission.rb
55
+ - example/example.rb
56
+ - flumify.gemspec
57
+ - lib/flume_master.rb
58
+ - lib/flumify.rb
59
+ - lib/flumify/version.rb
60
+ - lib/ssh_connection.rb
61
+ - rakefile
62
+ - spec/flumify_spec.rb
63
+ has_rdoc: true
64
+ homepage: ""
65
+ licenses: []
66
+
67
+ post_install_message:
68
+ rdoc_options: []
69
+
70
+ require_paths:
71
+ - lib
72
+ required_ruby_version: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ hash: 3
78
+ segments:
79
+ - 0
80
+ version: "0"
81
+ required_rubygems_version: !ruby/object:Gem::Requirement
82
+ none: false
83
+ requirements:
84
+ - - ">="
85
+ - !ruby/object:Gem::Version
86
+ hash: 3
87
+ segments:
88
+ - 0
89
+ version: "0"
90
+ requirements: []
91
+
92
+ rubyforge_project: flumify
93
+ rubygems_version: 1.3.7
94
+ signing_key:
95
+ specification_version: 3
96
+ summary: Simple flume configuration
97
+ test_files:
98
+ - spec/flumify_spec.rb