ocular 0.1.2 → 0.1.3

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.
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