ocular 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 981e6e95004d5057487b4fc0d616bdd9640b6c29
4
- data.tar.gz: db69ab3985347e0b4f06db7a568827fa8d33fe41
3
+ metadata.gz: 44118cd5f02b3dc8ef6388b180368295a0d9fa33
4
+ data.tar.gz: f9742f999a9dee9e10afcc0b1fde77c91dd7a0b3
5
5
  SHA512:
6
- metadata.gz: 8b9bcc9b27e6126d2c5600100163175cfb49d61c3eec68059fa7922b8998cff0f45a65f1caec2ab00b2b488268216a70d39bdcede89dc3aa44965a258b6ea91d
7
- data.tar.gz: 6f76ad19c003a5c2477cd950db9ed3e354425c0aca5e15b0f7fd6ab90226c028b91a2ce613ae73712f352a2f0c8e9d2f7ce1a669262ea3629fd5ed38fe167cd6
6
+ metadata.gz: e394d8d393db01c4fe7e3d00e57a29b8150eff97eb495c61897f4b00e3bebac985f82931060a08821d2d4230e23990f2d4a85c5a592e7625c2fb6e9366ba890f
7
+ data.tar.gz: a4d83f22add7eeefda8f3bfb36ad3e6016b981b8c20574982efe94a9d661e0f418eba0ce0eac000ed9ee62f2301d51c3b6ba5e09926c07ac0140f092a5685e88
data/bin/ocular ADDED
@@ -0,0 +1,102 @@
1
+ #!/usr/bin/ruby
2
+
3
+ require 'ocular'
4
+ require 'optparse'
5
+ require 'ostruct'
6
+ require 'pp'
7
+
8
+
9
+ class OptparseExample
10
+
11
+ #
12
+ # Return a structure describing the options.
13
+ #
14
+ def self.parse(args)
15
+ # The options specified on the command line will be collected in *options*.
16
+ # We set default values here.
17
+ options = OpenStruct.new
18
+ options.library = []
19
+ options.inplace = false
20
+ options.encoding = "utf8"
21
+ options.transfer_type = :auto
22
+ options.verbose = false
23
+ options.server = false
24
+ options.settings = "~/.ocular.yaml"
25
+ options.root = nil
26
+
27
+ opt_parser = OptionParser.new do |opts|
28
+ opts.banner = "Usage in shell mode: \"ocular [options] <script file>\" or server mode: \"ocular --server [options]\""
29
+
30
+ opts.separator ""
31
+ opts.separator "Specific options:"
32
+
33
+
34
+ opts.separator ""
35
+ opts.separator "Common options:"
36
+
37
+ # No argument, shows at tail. This will print an options summary.
38
+ # Try it and see!
39
+ opts.on_tail("-h", "--help", "Show this message") do
40
+ puts opts
41
+ exit
42
+ end
43
+
44
+ # Another typical switch to print the version.
45
+ opts.on_tail("--version", "Show version") do
46
+ puts Ocular::Version
47
+ exit
48
+ end
49
+
50
+ opts.on("--server", "Start in server mode") do
51
+ options.server = true
52
+ end
53
+
54
+ opts.on("--root PATH", "Script root path") do |path|
55
+ options.root = path
56
+ end
57
+
58
+ opts.on("--settings FILE", "Full path and file name to the settings yaml file. Default: #{options.settings}") do |path|
59
+ options.settings = path
60
+ end
61
+
62
+ end
63
+
64
+ opt_parser.parse!(args)
65
+ options
66
+ end # parse()
67
+
68
+ end # class OptparseExample
69
+
70
+ options = OptparseExample.parse(ARGV)
71
+
72
+ Ocular::Settings.load_from_file(File.expand_path(options.settings))
73
+
74
+ if options.server
75
+ if !options.root && !Ocular::Settings.get(:script_root)
76
+ puts "Please specify --root or set script_root in the settings.yaml"
77
+ exit
78
+ end
79
+
80
+ daemon = Ocular::Daemon.new(options.root || Ocular::Settings.get(:script_root))
81
+ daemon.load_script_files()
82
+ daemon.start_input_handlers()
83
+
84
+ puts "server started"
85
+ daemon.wait()
86
+
87
+ else
88
+ # Start shell mode
89
+
90
+ if ARGV.length == 0
91
+ puts "Missing script file to run. use -h to get more info"
92
+ exit
93
+ end
94
+
95
+ ef = Ocular::Event::EventFactory.new
96
+ proxy = ef.load_from_file(ARGV.shift)
97
+
98
+ context = Ocular::DSL::RunContext.new
99
+ eventbase = proxy.events[0]
100
+ eventbase.exec(context)
101
+
102
+ end
@@ -0,0 +1,59 @@
1
+ require 'ocular/utils.rb'
2
+ require 'pp'
3
+
4
+ class Ocular
5
+ class Daemon
6
+
7
+ attr_accessor :eventfactory
8
+
9
+ def initialize(root_path)
10
+
11
+ @root_path = root_path
12
+ @eventfactory = ::Ocular::Event::EventFactory.new
13
+ end
14
+
15
+ def get_script_files(root)
16
+ return Dir::glob("#{root}/**/*.rb")
17
+ end
18
+
19
+ def get_name_from_file(filename)
20
+
21
+ # -4 will strip the ".rb" away from the end
22
+ name = filename[@root_path.length..-4]
23
+
24
+ # If root_path is empty then we need to strip the '/' from the beginning
25
+ if name[0] == '/'
26
+ name = name[1..-1]
27
+ end
28
+
29
+ return name
30
+ end
31
+
32
+ def load_script_files()
33
+ files = self.get_script_files(@root_path)
34
+ for file in files
35
+ @eventfactory.load_from_file(file, get_name_from_file(file))
36
+ end
37
+ end
38
+
39
+ def start_input_handlers()
40
+ @eventfactory.start_input_handlers()
41
+ end
42
+
43
+ def stop_input_handlers()
44
+ @eventfactory.stop_input_handlers()
45
+ end
46
+
47
+ def wait()
48
+ while true
49
+ begin
50
+ sleep 60
51
+ rescue Interrupt
52
+ stop_input_handlers()
53
+ puts "\nGoing to exit"
54
+ return
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -13,8 +13,8 @@ class Ocular
13
13
 
14
14
  @@__aws_instance = ::Fog::Compute.new({
15
15
  :provider => 'AWS',
16
- :aws_access_key_id => ::Ocular::Settings::get('aws')['aws_access_key_id'],
17
- :aws_secret_access_key => ::Ocular::Settings::get('aws')['aws_secret_access_key']
16
+ :aws_access_key_id => ::Ocular::Settings::get(:aws)[:aws_access_key_id],
17
+ :aws_secret_access_key => ::Ocular::Settings::get(:aws)[:aws_secret_access_key]
18
18
  })
19
19
 
20
20
  return @@__aws_instance
@@ -22,8 +22,8 @@ class Ocular
22
22
 
23
23
  def autoscaling()
24
24
  return ::Fog::AWS::AutoScaling.new({
25
- :aws_access_key_id => ::Ocular::Settings::get('aws')['aws_access_key_id'],
26
- :aws_secret_access_key => ::Ocular::Settings::get('aws')['aws_secret_access_key']
25
+ :aws_access_key_id => ::Ocular::Settings::get(:aws)[:aws_access_key_id],
26
+ :aws_secret_access_key => ::Ocular::Settings::get(:aws)[:aws_secret_access_key]
27
27
  })
28
28
  end
29
29
 
@@ -6,7 +6,7 @@ class Ocular
6
6
  module SSH
7
7
 
8
8
  def ssh_to(hostname)
9
- settings = ::Ocular::Settings::get('ssh').inject({}){|memo,(k,v)| memo[k.to_sym] = v; memo}
9
+ settings = ::Ocular::Settings::get(:ssh)
10
10
  settings[:password_prompt] = false
11
11
  settings[:safe] = false
12
12
 
@@ -1,49 +1,73 @@
1
+ require 'ocular/inputs/handlers.rb'
1
2
  require 'ocular/event/eventbase.rb'
3
+ require 'ocular/inputs/http_input.rb'
2
4
 
3
5
  class Ocular
4
6
  module Event
5
7
  class DefinitionProxy
6
- attr_accessor :events
7
- attr_accessor :klass_name
8
-
9
- def initialize(klass_name)
10
- self.klass_name = klass_name
11
- @events = []
12
- @logger = Ocular::DSL::Logger.new
13
- end
14
-
15
- include Ocular::Mixin::FromFile
16
- include Ocular::DSL::Logging
17
- include Ocular::DSL::SSH
18
- include Ocular::DSL::Fog
19
-
20
- def onEvent(factory_class, &block)
21
- eventbase = Ocular::DSL::EventBase.new(&block)
22
- eventbase.proxy = self
23
- @events << eventbase
24
- end
8
+ attr_accessor :events
9
+ attr_reader :script_name
10
+ attr_accessor :handlers
11
+
12
+ def initialize(script_name, handlers)
13
+ @script_name = script_name
14
+ @events = []
15
+ @logger = Ocular::DSL::Logger.new
16
+ @handlers = handlers
17
+ end
18
+
19
+ include Ocular::Mixin::FromFile
20
+ include Ocular::DSL::Logging
21
+ include Ocular::DSL::SSH
22
+ include Ocular::DSL::Fog
23
+ include Ocular::Inputs::HTTP::DSL
24
+
25
+ def onEvent(factory_class, &block)
26
+ eventbase = Ocular::DSL::EventBase.new(&block)
27
+ eventbase.proxy = self
28
+ @events << eventbase
29
+ end
25
30
  end
26
31
 
27
32
  class EventFactory
28
33
 
34
+ attr_accessor :handlers
35
+ attr_accessor :files
36
+
29
37
  def initialize
30
38
  @files = {}
39
+ @handlers = ::Ocular::Inputs::Handlers.new
31
40
  end
32
41
 
33
- def load_from_file(file)
34
- proxy = DefinitionProxy.new(file)
42
+ def load_from_file(file, name = nil)
43
+ if !name
44
+ name = file
45
+ end
46
+
47
+ proxy = DefinitionProxy.new(name, @handlers)
35
48
  proxy.from_file(file)
36
- @files[file] = proxy
49
+ @files[name] = proxy
37
50
  return proxy
38
51
  end
39
52
 
40
53
  def load_from_block(name, &block)
41
- proxy = DefinitionProxy.new(name)
54
+ proxy = DefinitionProxy.new(name, @handlers)
42
55
  proxy.instance_eval(&block)
43
56
  @files[name] = proxy
44
57
  return proxy
45
58
  end
46
59
 
60
+ def get(name)
61
+ return @files[name]
62
+ end
63
+
64
+ def start_input_handlers()
65
+ @handlers.start()
66
+ end
67
+
68
+ def stop_input_handlers()
69
+ @handlers.stop()
70
+ end
47
71
  end
48
72
  end
49
- end
73
+ end
@@ -0,0 +1,35 @@
1
+ require 'ocular/mixin/from_file'
2
+ require 'ocular/dsl/fog'
3
+ require 'ocular/dsl/ssh'
4
+ require 'ocular/dsl/logging'
5
+
6
+ class Ocular
7
+ module Event
8
+
9
+ class Forker
10
+
11
+ def initialize(&block)
12
+ puts "Forker created with block #{block}"
13
+ @callback = block
14
+ end
15
+
16
+ def get_proc()
17
+ cb = @callback
18
+
19
+ def proxy(&block)
20
+ return block
21
+ end
22
+
23
+ p = proxy do |*args|
24
+ puts "Calling proc callback: #{cb}"
25
+ cb.call(*args)
26
+ end
27
+
28
+ puts "returning p: #{p}"
29
+
30
+ return p
31
+ end
32
+ end
33
+ end
34
+ end
35
+
@@ -0,0 +1,17 @@
1
+
2
+ class Ocular
3
+ module Inputs
4
+ class Base
5
+
6
+ def initialize(settings)
7
+ end
8
+
9
+ def start()
10
+ end
11
+
12
+ def stop()
13
+ end
14
+
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,33 @@
1
+ require 'pp'
2
+
3
+ class Ocular
4
+ module Inputs
5
+ class Handlers
6
+
7
+ def initialize
8
+ @handlers = Hash.new
9
+ end
10
+
11
+ def get(klass)
12
+ if @handlers[klass]
13
+ return @handlers[klass]
14
+ end
15
+
16
+ @handlers[klass] = klass.new(::Ocular::Settings.get(:inputs))
17
+ return @handlers[klass]
18
+ end
19
+
20
+ def start()
21
+ @handlers.each do |name, handler|
22
+ handler.start()
23
+ end
24
+ end
25
+
26
+ def stop()
27
+ @handlers.each do |name, handler|
28
+ handler.stop()
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,110 @@
1
+ require 'sinatra/base'
2
+ require 'puma'
3
+ require 'rack'
4
+ require 'rack/server'
5
+ require 'ocular/inputs/base.rb'
6
+
7
+ class Ocular
8
+ module Inputs
9
+
10
+ module HTTP
11
+
12
+ module DSL
13
+
14
+ def onGET(path, opts = {}, &block)
15
+ handler = handlers.get(::Ocular::Inputs::HTTP::Input)
16
+ handler.add_get(script_name, path, opts, &block)
17
+ end
18
+
19
+ def onPOST(path, opts = {}, &block)
20
+ handler = handlers.get(::Ocular::Inputs::HTTP::Input)
21
+ handler.add_post(script_name, path, opts, &block)
22
+ end
23
+
24
+ end
25
+
26
+ class Input < ::Ocular::Inputs::Base
27
+ DEFAULT_SETTINGS = {
28
+ :host => '0.0.0.0',
29
+ :port => 8080,
30
+ :verbose => false,
31
+ :silent => false
32
+ }
33
+
34
+ class SinatraApp < Sinatra::Base
35
+ configure do
36
+ set :server, :puma
37
+ end
38
+
39
+ get '/noop' do
40
+ puts "/check called"
41
+ "OK\n"
42
+ end
43
+ end
44
+
45
+ def generate_uri_from_names(script_name, path)
46
+ puts "generate_uri_from_names: #{script_name}, #{path}"
47
+ if path[0] == "/"
48
+ path = path[1..-1]
49
+ end
50
+
51
+ if script_name && script_name != ""
52
+ name = script_name + "/" + path
53
+ else
54
+ name = path
55
+ end
56
+
57
+ return "/" + name
58
+ end
59
+
60
+ def add_get(script_name, path, options = {}, &block)
61
+ name = generate_uri_from_names(script_name, path)
62
+ puts "adding get at #{name}"
63
+ @app_class.get(name, options, &block)
64
+ end
65
+
66
+ def add_post(script_name, path, options = {}, &block)
67
+ name = generate_uri_from_names(script_name, path)
68
+ @app_class.post(name, options, &block)
69
+ end
70
+
71
+ def initialize(settings_factory)
72
+ settings = settings_factory[:http]
73
+
74
+ @settings = DEFAULT_SETTINGS.merge(settings)
75
+ @stopsignal = Queue.new()
76
+ @thread = nil
77
+
78
+ @app_class = Class.new(SinatraApp)
79
+
80
+ end
81
+
82
+ def start()
83
+ @app = @app_class.new
84
+ if @settings[:Verbose]
85
+ @app = Rack::CommonLogger.new(@app, STDOUT)
86
+ end
87
+
88
+ @thread = Thread.new do
89
+ events_hander = @settings[:Silent] ? ::Puma::Events.strings : ::Puma::Events.stdio
90
+ server = ::Puma::Server.new(@app, events_hander)
91
+
92
+ server.add_tcp_listener @settings[:host], @settings[:port]
93
+ server.min_threads = 0
94
+ server.max_threads = 16
95
+
96
+ server.run
97
+ @stopsignal.pop
98
+ server.stop(true)
99
+ end
100
+ end
101
+
102
+ def stop()
103
+ @stopsignal << "EXIT"
104
+ @thread.join
105
+ end
106
+
107
+ end
108
+ end
109
+ end
110
+ end
data/lib/ocular/ocular.rb CHANGED
@@ -7,3 +7,7 @@ require 'ocular/dsl/logging'
7
7
  require 'ocular/dsl/fog'
8
8
  require 'ocular/dsl/ssh'
9
9
  require 'ocular/dsl/runcontext'
10
+ require 'ocular/inputs/handlers'
11
+ require 'ocular/inputs/base'
12
+ require 'ocular/inputs/http_input'
13
+ require 'ocular/daemon'
@@ -1,5 +1,6 @@
1
1
  require 'singleton'
2
2
  require 'yaml'
3
+ require 'ocular/utils.rb'
3
4
 
4
5
  class Ocular
5
6
  class Settings
@@ -8,12 +9,28 @@ class Ocular
8
9
  include Singleton
9
10
 
10
11
  def initialize()
11
- filename = ENV['OCULAR_SETTINGS']
12
- self.settings = YAML::load_file(filename)
12
+ end
13
+
14
+ def self.find_settings_file_from_system()
15
+ filename = nil
16
+ if ENV['OCULAR_SETTINGS'] != nil
17
+ filename = File.expand_path(ENV['OCULAR_SETTINGS'])
18
+ end
19
+
20
+ if !filename or !File.exists?(filename)
21
+ filename = File.expand_path('~/.ocular.yaml')
22
+ end
23
+
24
+ if !filename or !File.exists?(filename)
25
+ filename = File.expand_path('/etc/ocular.yaml')
26
+ end
27
+
28
+ return filename
13
29
  end
14
30
 
15
31
  def self.load_from_file(filename)
16
- @settings = YAML::load_file(filename)
32
+ #puts "Loaded settings from #{filename}"
33
+ @settings = ::Ocular::deep_symbolize(YAML::load_file(filename))
17
34
  end
18
35
 
19
36
  def self.get(key)
@@ -0,0 +1,7 @@
1
+ class Ocular
2
+ def self.deep_symbolize(obj)
3
+ return obj.inject({}){|memo,(k,v)| memo[k.to_sym] = deep_symbolize(v); memo} if obj.is_a? Hash
4
+ return obj.inject([]){|memo,v | memo << deep_symbolize(v); memo} if obj.is_a? Array
5
+ return obj
6
+ end
7
+ end
@@ -1,3 +1,3 @@
1
1
  class Ocular
2
- Version = "0.1.2"
2
+ Version = "0.1.3"
3
3
  end
@@ -4,7 +4,7 @@ RSpec.describe Ocular::Settings do
4
4
 
5
5
  it "get receiver settings" do
6
6
  ::Ocular::Settings.load_from_file('spec/data/settings.yaml')
7
- a = ::Ocular::Settings.get("test_setting")
7
+ a = ::Ocular::Settings.get(:test_setting)
8
8
  expect(a).to eq("Hello, World!")
9
9
  end
10
10
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ocular
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Juho Mäkinen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-02-22 00:00:00.000000000 Z
11
+ date: 2016-02-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rye
@@ -28,16 +28,58 @@ dependencies:
28
28
  name: fog
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ">="
31
+ - - '='
32
+ - !ruby/object:Gem::Version
33
+ version: 1.37.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '='
39
+ - !ruby/object:Gem::Version
40
+ version: 1.37.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: puma
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '='
32
46
  - !ruby/object:Gem::Version
33
- version: '0'
47
+ version: 2.16.0
34
48
  type: :runtime
35
49
  prerelease: false
36
50
  version_requirements: !ruby/object:Gem::Requirement
37
51
  requirements:
38
- - - ">="
52
+ - - '='
53
+ - !ruby/object:Gem::Version
54
+ version: 2.16.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: sinatra
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '='
60
+ - !ruby/object:Gem::Version
61
+ version: 1.4.7
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '='
67
+ - !ruby/object:Gem::Version
68
+ version: 1.4.7
69
+ - !ruby/object:Gem::Dependency
70
+ name: faraday
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '='
74
+ - !ruby/object:Gem::Version
75
+ version: 0.9.2
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '='
39
81
  - !ruby/object:Gem::Version
40
- version: '0'
82
+ version: 0.9.2
41
83
  - !ruby/object:Gem::Dependency
42
84
  name: rspec
43
85
  requirement: !ruby/object:Gem::Requirement
@@ -60,24 +102,32 @@ description: |+
60
102
  The goal is that a new script could be written really quickly to automate a previously manual infrastructure maintenance job instead of doing the manual job yet another time. Scripts are written in Ruby with a simple Ocular DSL which allows the script to easily respond to multitude different events.
61
103
 
62
104
  email: juho@unity3d.com
63
- executables: []
105
+ executables:
106
+ - ocular
64
107
  extensions: []
65
108
  extra_rdoc_files: []
66
109
  files:
67
110
  - README.md
111
+ - bin/ocular
68
112
  - examples/converge-broken-array.rb
69
113
  - examples/ssh-example.rb
70
114
  - lib/blocktest.rb
71
115
  - lib/ocular.rb
116
+ - lib/ocular/daemon.rb
72
117
  - lib/ocular/dsl/fog.rb
73
118
  - lib/ocular/dsl/logging.rb
74
119
  - lib/ocular/dsl/runcontext.rb
75
120
  - lib/ocular/dsl/ssh.rb
76
121
  - lib/ocular/event/eventbase.rb
77
122
  - lib/ocular/event/eventfactory.rb
123
+ - lib/ocular/event/forker.rb
124
+ - lib/ocular/inputs/base.rb
125
+ - lib/ocular/inputs/handlers.rb
126
+ - lib/ocular/inputs/http_input.rb
78
127
  - lib/ocular/mixin/from_file.rb
79
128
  - lib/ocular/ocular.rb
80
129
  - lib/ocular/settings.rb
130
+ - lib/ocular/utils.rb
81
131
  - lib/ocular/version.rb
82
132
  - spec/blocktest_spec.rb
83
133
  - spec/settings_spec.rb