baton 0.3.6

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.
Files changed (49) hide show
  1. data/.gitignore +19 -0
  2. data/.rspec +1 -0
  3. data/.travis.yml +6 -0
  4. data/COPYING +8 -0
  5. data/Gemfile +10 -0
  6. data/Guardfile +6 -0
  7. data/README.md +77 -0
  8. data/Rakefile +10 -0
  9. data/baton.gemspec +30 -0
  10. data/bin/batonize +60 -0
  11. data/lib/baton.rb +13 -0
  12. data/lib/baton/api.rb +27 -0
  13. data/lib/baton/channel.rb +47 -0
  14. data/lib/baton/configuration.rb +63 -0
  15. data/lib/baton/consumer.rb +89 -0
  16. data/lib/baton/consumer_manager.rb +67 -0
  17. data/lib/baton/logging.rb +18 -0
  18. data/lib/baton/observer.rb +74 -0
  19. data/lib/baton/server.rb +68 -0
  20. data/lib/baton/service.rb +55 -0
  21. data/lib/baton/templates/gem/Gemfile.tt +5 -0
  22. data/lib/baton/templates/gem/LICENSE.tt +22 -0
  23. data/lib/baton/templates/gem/README.md.tt +29 -0
  24. data/lib/baton/templates/gem/Rakefile.tt +6 -0
  25. data/lib/baton/templates/gem/bin/gem-monitor.tt +10 -0
  26. data/lib/baton/templates/gem/bin/gem.tt +12 -0
  27. data/lib/baton/templates/gem/config/gem.cfg.tt +4 -0
  28. data/lib/baton/templates/gem/gem.gemspec.tt +22 -0
  29. data/lib/baton/templates/gem/gitignore.tt +17 -0
  30. data/lib/baton/templates/gem/lib/baton/gem.rb.tt +15 -0
  31. data/lib/baton/templates/gem/lib/baton/gem/gem-api.rb.tt +17 -0
  32. data/lib/baton/templates/gem/lib/baton/gem/gem-consumer.rb.tt +26 -0
  33. data/lib/baton/templates/gem/lib/baton/gem/gem-monitor.rb.tt +32 -0
  34. data/lib/baton/templates/gem/lib/baton/gem/version.rb.tt +7 -0
  35. data/lib/baton/version.rb +3 -0
  36. data/spec/baton/baton_spec.rb +13 -0
  37. data/spec/baton/configuration_spec.rb +54 -0
  38. data/spec/baton/consumer_manager_spec.rb +72 -0
  39. data/spec/baton/consumer_spec.rb +63 -0
  40. data/spec/baton/server_spec.rb +64 -0
  41. data/spec/fixtures/config.cfg +4 -0
  42. data/spec/fixtures/facts.json +1776 -0
  43. data/spec/fixtures/file +1 -0
  44. data/spec/fixtures/file.sum +1 -0
  45. data/spec/fixtures/invalid_facts.json +1774 -0
  46. data/spec/fixtures/invalid_file +1 -0
  47. data/spec/fixtures/invalid_file.sum +1 -0
  48. data/spec/spec_helper.rb +12 -0
  49. metadata +236 -0
@@ -0,0 +1,67 @@
1
+ require "baton/logging"
2
+
3
+ module Baton
4
+ class ConsumerManager
5
+ include Baton::Logging
6
+ attr_accessor :consumer, :channel, :exchange_in, :exchange_out
7
+
8
+ # Public: Initialize a ConsumerManager and adds itself as an observer to the consumer.
9
+ #
10
+ # consumer - An instance of Baton::Consumer
11
+ # channel - An AMQP channel
12
+ # exchange_in - An input exchange
13
+ # exchange_out - An output exchange
14
+ def initialize(consumer, channel, exchange_in, exchange_out)
15
+ @consumer, @channel, @exchange_in, @exchange_out = consumer, channel, exchange_in, exchange_out
16
+ @consumer.add_observer(self)
17
+ @consumer.consumer_manager = self
18
+ end
19
+
20
+ # Public: Creates a queue and binds it to the input exchange based on the consumer's
21
+ # routing key. Also adds handle_message as a callback method to queue.subscribe().
22
+ #
23
+ # Returns nothing.
24
+ def start
25
+ queue = channel.queue("", :exclusive => true, :auto_delete => true)
26
+ queue.bind(exchange_in, :routing_key => consumer.routing_key)
27
+ queue.subscribe(&method(:handle_message))
28
+ logger.info "Bind queue with routing key '#{consumer.routing_key}' to exchange '#{exchange_in.name}', waiting for messages..."
29
+ end
30
+
31
+ # Public: Triggered whenever a message is received and forwards the message
32
+ # to the consumer's handle_message.
33
+ #
34
+ # metadata - A metadata structure such as OpenStruct
35
+ # payload - A JSON message
36
+ #
37
+ # Examples
38
+ #
39
+ # handle_message(metadata, "{\"message\":\"a message\",\"type\":\"a type\"}")
40
+ #
41
+ # Returns nothing.
42
+ def handle_message(metadata, payload)
43
+ logger.debug "Received #{payload}, content_type = #{metadata.content_type}"
44
+ consumer.handle_message(payload)
45
+ end
46
+
47
+ # Public: Method that is triggered when a consumer notifies with a message. It
48
+ # logs the messages and writes them to the output exchange as json.
49
+ #
50
+ # message - A general message (Hash, String, etc)
51
+ #
52
+ # Examples
53
+ #
54
+ # update("A message")
55
+ #
56
+ # Returns nothing.
57
+ def update(message)
58
+ case message.fetch(:type){""}
59
+ when "error"
60
+ logger.error message
61
+ else
62
+ logger.info message
63
+ end
64
+ exchange_out.publish(message.to_json)
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,18 @@
1
+ require "logger"
2
+
3
+ module Baton
4
+ module Logging
5
+ def logger
6
+ Baton::Logging.logger
7
+ end
8
+
9
+ def self.logger
10
+ STDOUT.sync = true
11
+ @logger ||= Logger.new(STDOUT)
12
+ end
13
+
14
+ def self.logger=(out)
15
+ @logger = Logger.new(out)
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,74 @@
1
+ require "observer"
2
+
3
+ module Baton
4
+ module Observer
5
+ include Observable
6
+
7
+ # Public: Method that notifies errors to observers.
8
+ #
9
+ # klass - Error class
10
+ # message - Error message
11
+ #
12
+ # Examples
13
+ #
14
+ # notify_error(Exception, "Error message")
15
+ #
16
+ # Returns nothing.
17
+ def notify_error(klass, message)
18
+ notify_log({type: "error", error_class: klass, error_message: message})
19
+ end
20
+
21
+ # Public: Method that notifies informations to observers.
22
+ #
23
+ # message - Info message
24
+ #
25
+ # Examples
26
+ #
27
+ # notify_info("info message")
28
+ #
29
+ # Returns nothing.
30
+ def notify_info(message)
31
+ notify_log({:type => "info", :message => message})
32
+ end
33
+
34
+ # Public: Method that notifies success to observers.
35
+ #
36
+ # message - Success message
37
+ #
38
+ # Examples
39
+ #
40
+ # notify_success("success message")
41
+ #
42
+ # Returns nothing.
43
+ def notify_success(message)
44
+ notify_log({:type => "success", :message => message})
45
+ end
46
+
47
+ # Public: Method that merges attributes to be sent as messages and notifies observers.
48
+ #
49
+ # attrs - A number of attributes represented by an Hash
50
+ #
51
+ # Examples
52
+ #
53
+ # notify_log({field_1: "text", :field_2: 123})
54
+ #
55
+ # Returns nothing.
56
+ def notify_log(attrs)
57
+ notify(attributes.merge(attrs))
58
+ end
59
+
60
+ # Public: Method that notifies messages to observers.
61
+ #
62
+ # message - General message
63
+ #
64
+ # Examples
65
+ #
66
+ # notify("message")
67
+ #
68
+ # Returns nothing.
69
+ def notify(message)
70
+ changed
71
+ notify_observers(message)
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,68 @@
1
+ require "json"
2
+
3
+ module Baton
4
+ class Server
5
+
6
+ attr_accessor :environment, :fqdn, :app_names
7
+
8
+ # Public: Initialize a Server. ALso, configures the server by reading Baton's configuration
9
+ # file.
10
+ def initialize
11
+ configure
12
+ end
13
+
14
+ # Public: Method that configures the server. It sets the fqdn, environment and a list
15
+ # of app names specified by the ohai config file.
16
+ #
17
+ # Returns nothing.
18
+ def configure
19
+ @environment = facts.fetch("chef_environment"){"development"}.downcase
20
+ @fqdn = facts.fetch("fqdn"){""}
21
+ @app_names = facts.fetch("trebuchet"){[]}
22
+ end
23
+
24
+ # Public: Method that reads facts from the file specified by facts_file.
25
+ #
26
+ # Examples
27
+ #
28
+ # facts
29
+ # # => {"fqdn" => "server.dsci.it", "chef_environment" => "production", "trebuchet" => []}
30
+ #
31
+ # Returns a hash with server information.
32
+ def facts
33
+ @facts ||= JSON.parse(facts_file.read)
34
+ end
35
+
36
+ # Public: Provides the content of the ohai file.
37
+ #
38
+ # Returns content of ohai facts file.
39
+ def facts_file
40
+ File.open(facts_path)
41
+ end
42
+
43
+ # Public: Provides the path to the ohai file
44
+ #
45
+ # Examples
46
+ #
47
+ # facts_path
48
+ # # => "/path/to/file/facts.json"
49
+ #
50
+ # Returns the path of the ohai file
51
+ def facts_path
52
+ Baton.configuration.ohai_file
53
+ end
54
+
55
+ # Public: Method that provides an hash of attributes for a server.
56
+ #
57
+ # Examples
58
+ #
59
+ # attributes
60
+ # # => {environment: "production", fqdn: "server.dsci.it", app_names: ["app1","app2"]}
61
+ #
62
+ # Returns Output depends on the implementation.
63
+ def attributes
64
+ {environment: environment, fqdn: fqdn, app_names: app_names}
65
+ end
66
+
67
+ end
68
+ end
@@ -0,0 +1,55 @@
1
+ require "baton"
2
+ require "amqp"
3
+ require "eventmachine"
4
+ require "em-http-request"
5
+ require "json"
6
+ require "baton/channel"
7
+ require "baton/server"
8
+ require "baton/consumer_manager"
9
+
10
+ module Baton
11
+ class Service
12
+ include Baton::Logging
13
+
14
+ attr_accessor :server, :channel
15
+
16
+ # Public: Initialize a Service. Sets up a new server for this service.
17
+ def initialize
18
+ @server = Baton::Server.new
19
+ end
20
+
21
+ # Public: Method that starts the service.
22
+ #
23
+ # Returns nothing.
24
+ def run
25
+ logger.info "Starting Baton v#{Baton::VERSION}"
26
+ EM.run do
27
+ @channel = Baton::Channel.new
28
+ setup_consumers
29
+ end
30
+ end
31
+
32
+ # Public: Method that allows implementations to setup new consumers
33
+ # depending on their needs. An example would be add a deploy consumer
34
+ # which will listen to deploy messages. For each consumer, add_consumer
35
+ # should be called to attach the consumers to the AMQP channel.
36
+ #
37
+ # Returns Output depends on the implementation.
38
+ def setup_consumers
39
+ end
40
+
41
+ # Public: Adds a given consumer to the AMQP channel.
42
+ #
43
+ # consumer - An instance of Baton::Consumer.
44
+ #
45
+ # Examples
46
+ #
47
+ # add_consumer(Baton::DeployConsumer.new("consumer_name", Baton::Server.new))
48
+ #
49
+ # Returns nothing..
50
+ def add_consumer(consumer)
51
+ channel.add_consumer(consumer)
52
+ end
53
+
54
+ end
55
+ end
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+ source 'http://gems.dsci.it'
3
+
4
+ # Specify your gem's dependencies in <%=config[:name]%>.gemspec
5
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) <%=Time.now.year%> <%=config[:author]%>
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,29 @@
1
+ # <%=config[:constant_name]%>
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem '<%=config[:name]%>'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install <%=config[:name]%>
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+
4
+ task :console do
5
+ sh "irb -rubygems -I lib/baton -r <%= config[:name] %>.rb"
6
+ end
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "baton/<%= config[:name] %>/<%= config[:name] %>-monitor"
4
+
5
+ Baton.configure do |c|
6
+ c.config_path = "<%= File.join(Dir.pwd, config[:name], 'config', config[:name]) %>.cfg"
7
+ c.exchange_out = "<%= config[:name] %>_out"
8
+ end
9
+
10
+ Baton::<%= config[:constant_array].last %>Monitor.run
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'baton/<%= config[:name] %>'
4
+
5
+ Baton.configure do |c|
6
+ c.config_path = "<%= File.join(Dir.pwd, config[:name], 'config', config[:name]) %>.cfg"
7
+ c.ohai_file = "/var/lib/ohai/facts.json"
8
+ c.exchange = "<%= config[:name] %>_in"
9
+ c.exchange_out = "<%= config[:name] %>_out"
10
+ end
11
+
12
+ Baton::<%= config[:constant_array].last %>Service.new.run
@@ -0,0 +1,4 @@
1
+ RABBIT_HOST: localhost
2
+ RABBIT_VHOST:
3
+ RABBIT_USER: guest
4
+ RABBIT_PASS: guest
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/baton/<%=config[:name]%>/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = [<%=config[:author].inspect%>]
6
+ gem.email = [<%=config[:email].inspect%>]
7
+ gem.description = %q{TODO: Write a gem description}
8
+ gem.summary = %q{TODO: Write a gem summary}
9
+ gem.homepage = ""
10
+
11
+ gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
12
+ gem.files = `git ls-files`.split("\n")
13
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
14
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
15
+ gem.name = <%=config[:name].inspect%>
16
+ gem.require_paths = ["lib"]
17
+ gem.version = <%=config[:constant_name]%>::VERSION
18
+
19
+ gem.add_runtime_dependency "baton"
20
+
21
+ gem.add_development_dependency "rake"
22
+ end
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
@@ -0,0 +1,15 @@
1
+ require "baton"
2
+ require "baton/service"
3
+ require "baton/<%=config[:name]%>/version"
4
+ require "baton/<%=config[:name]%>/<%=config[:name]%>-consumer"
5
+
6
+ module Baton
7
+ class <%= config[:constant_array].last %>Service < Baton::Service
8
+
9
+ def setup_consumers
10
+ srv = <%=config[:constant_name]%>Consumer.new(server.fqdn, server)
11
+ add_consumer(srv)
12
+ end
13
+ end
14
+ end
15
+