ocular 0.1.16 → 0.1.17

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: 9e7bdc14065534d11c655212e482f3e63f5fe1e3
4
- data.tar.gz: 80bee22324973ce182d65d5c7518949e826bc1d1
3
+ metadata.gz: f2b13556c63053b9d7f15e8382b3803295edc3d4
4
+ data.tar.gz: 8862213d31cabfaee4332bcb33bcacf63601e5d7
5
5
  SHA512:
6
- metadata.gz: 839537f3335286e0269274211824b3dd8560f4857ec4a04789d43796ef2d71637ea99f74357d7cac72b91051e3eeb1e5f23a14d05332ba837d3da9efaf3f928e
7
- data.tar.gz: 55a4b0fdf8c52dcf925740ef367061ceb372c59f677dfc06c1580506f5b18d07310fd2e4ff4d942c813aa1ccb9e162d99ed2676413d63132ece867b832fdf210
6
+ metadata.gz: 1be07d88abd000eb2cb6c70b92b9790b33720d8d72554393f8e0f0bc21ac07a43abc8c511b7f807ed98c40a728f46bbc7613a7d0fd73e9994104a59a0089d91d
7
+ data.tar.gz: bb7edaf144bac5bc7433505b6c05b23e9027f27656c8bbd32a257fff9a319cafc3395947e499831ebdba9a8236b3f1b21ff7bd7a5c020527ad30b14433201c4d
data/README.md CHANGED
@@ -5,11 +5,26 @@ Ocular allows to easily create small scripts which are triggered from multiple d
5
5
 
6
6
  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.
7
7
 
8
- Planned event sources:
8
+ Currently implemented event sources:
9
9
  - HTTP calls
10
10
  - RabbitMQ messages
11
+ - Timers
12
+
13
+ Planned event sources:
11
14
  - SQS/SNS messages
12
- - Graphite item triggers
13
15
  - Zabbix alerts
14
- - Timers
16
+ - NATS broadcast messages
17
+ - salt-stack event bus
18
+
19
+ Currently implemented clients to external services (ie. what you can easily do once your event has been triggered):
20
+ - MySQL
21
+ - etcd
22
+ - RabbitMQ
23
+ - AWS/EC2
24
+ - Kafka (for logging)
25
+ - SSH for remote execution
15
26
 
27
+ Planned clients to external services:
28
+ - Graphite
29
+ - Zabbix configuration
30
+ - salt-stack remote state execution
data/lib/ocular/daemon.rb CHANGED
@@ -37,7 +37,6 @@ class Ocular
37
37
  end
38
38
 
39
39
  def start_input_handlers()
40
- puts "derp"
41
40
  @eventfactory.start_input_handlers()
42
41
  end
43
42
 
@@ -1,5 +1,6 @@
1
1
  require 'logger'
2
2
  require 'etcd'
3
+ require 'pp'
3
4
 
4
5
  class Ocular
5
6
  module DSL
@@ -29,6 +30,67 @@ class Ocular
29
30
  return @@__etcd_instance
30
31
  end
31
32
 
33
+ def ttl_lock(key, ttl:10)
34
+ id = @run_id
35
+ if !id
36
+ id = Process.pid.to_s
37
+ Socket.ip_address_list.each do |addr|
38
+ next if addr.ip_address == "127.0.0.1"
39
+ next if addr.ip_address.start_with?("::1")
40
+ next if addr.ip_address.start_with?("fe80::1")
41
+ id += "-" + addr.ip_address
42
+ end
43
+ end
44
+
45
+ client = etcd()
46
+
47
+ current_lock = locked?(key)
48
+
49
+ if current_lock != id and current_lock != nil
50
+ return nil # Somebody else has lock, can't lock by ourself
51
+ end
52
+
53
+ if current_lock == id and current_lock != nil
54
+ begin
55
+ client.test_and_set("/ocular/locks/#{key}", value: id, prevValue: id, ttl: ttl)
56
+ return id
57
+ rescue ::Etcd::NodeExist => e
58
+ return nil
59
+ end
60
+
61
+ else
62
+ begin
63
+ client.create("/ocular/locks/#{key}", value: id, ttl: ttl)
64
+ return id
65
+ rescue ::Etcd::NodeExist => e
66
+ return nil
67
+ end
68
+ end
69
+ end
70
+
71
+ def unlock(key)
72
+ client = etcd()
73
+ begin
74
+ client.delete("/ocular/locks/#{key}")
75
+ rescue ::Etcd::KeyNotFound
76
+
77
+ end
78
+ return true
79
+ end
80
+
81
+ def locked?(key)
82
+ client = etcd()
83
+ begin
84
+ ret = client.get("/ocular/locks/#{key}")
85
+ if ret.node and ret.node.expiration == nil
86
+ warn("Key #{key} has been locked permanently with value '#{ret.node.value}'!")
87
+ end
88
+ return ret.node.value # Key is locked
89
+ rescue ::Etcd::KeyNotFound => e
90
+ return nil
91
+ end
92
+ end
93
+
32
94
  end
33
95
 
34
96
  end
@@ -46,7 +46,13 @@ class Ocular
46
46
  r.error = error
47
47
  end
48
48
 
49
- Marshal.dump(r, writer)
49
+ begin
50
+ Marshal.dump(r, writer)
51
+ rescue TypeError => e
52
+ ::Ocular.logger.error "TypeError when trying to marshal event handler return value. Reason: #{e}"
53
+ ::Ocular.logger.error "This is usually because you forgot that the last function return value is returned from the handler function. The current type of the returned value is #{r.response.class}. Please make sure your handler returns a proper value which doesn't reference any sockets or otherwise complex unserializable objects."
54
+ ::Ocular.logger.error "The value of the returned value is :#{r.response.pretty_inspect}"
55
+ end
50
56
  writer.close
51
57
  end
52
58
  writer.close
@@ -29,22 +29,28 @@ class Ocular
29
29
  attr_reader :cron_enabled
30
30
 
31
31
  def initialize(settings_factory)
32
- settings = settings_factory[:cron]
32
+ settings = settings_factory.fetch(:cron, {})
33
33
  @cron_enabled = true
34
34
 
35
+ pp settings
35
36
  if settings[:lock]
36
37
  @cron_enabled = false
37
38
  end
38
39
 
40
+ if settings[:enabled] == false
41
+ ::Ocular.logger.info "Cron is disabled from settings"
42
+ @cron_enabled = false
43
+ end
44
+
39
45
  @scheduler = ::Rufus::Scheduler.new
40
46
  ::Ocular.logger.debug "Starting Rufus cron scheduler"
41
47
 
42
- if settings[:lock]
48
+ if settings[:lock] and @cron_enabled == true
49
+ Ocular.logger.debug "Enabling cron locking at pid #{Process.pid.to_s}"
43
50
  @scheduler.every(settings[:lock_delay] || "10s", :overlap => false) do
44
- etcd = ::Ocular::DSL::Etcd.etcd()
51
+ c = Class.new.extend(Ocular::DSL::Etcd)
45
52
 
46
- ret = etcd.get(settings[:lock])
47
- pp ret
53
+ @cron_enabled = c.ttl_lock("cron_input", ttl:20)
48
54
  end
49
55
  end
50
56
  end
@@ -59,7 +65,7 @@ class Ocular
59
65
 
60
66
  def disable()
61
67
  @cron_enabled = false
62
- end
68
+ end
63
69
 
64
70
  def enable()
65
71
  @cron_enabled = true
@@ -445,7 +445,9 @@ class Ocular
445
445
  context.params = indifferent_params(context.request.params)
446
446
 
447
447
  context.response['Content-Type'] = nil
448
- invoke(context) { |context| dispatch(context) }
448
+ invoke(context) do |context|
449
+ dispatch(context)
450
+ end
449
451
 
450
452
  unless context.response['Content-Type']
451
453
  context.response['Content-Type'] = "text/html"
@@ -469,7 +471,6 @@ class Ocular
469
471
 
470
472
  def invoke(context)
471
473
  res = catch(:halt) { yield(context) }
472
-
473
474
  if Array === res and Fixnum === res.first
474
475
  res = res.dup
475
476
  status(context, res.shift)
@@ -488,7 +489,11 @@ class Ocular
488
489
  context.response.status = error.http_status
489
490
 
490
491
  if error.respond_to? :to_s
491
- puts error.to_s
492
+ str = error.to_s
493
+ if !str.end_with?("\n")
494
+ str += "\n"
495
+ end
496
+ context.response.body = str
492
497
  end
493
498
  else
494
499
  context.response.status = 500
@@ -603,7 +608,7 @@ class Ocular
603
608
  pattern, keys = compile("/check")
604
609
 
605
610
  (@routes["GET"] ||= []) << build_signature(pattern, keys) do |context|
606
- [200, "OK"]
611
+ [200, "OK\n"]
607
612
  end
608
613
  end
609
614
 
@@ -71,8 +71,14 @@ class Ocular
71
71
  context.delivery_info = delivery_info
72
72
  context.metadata = metadata
73
73
  context.payload = payload
74
- eventbase.exec(context)
75
- ch.acknowledge(delivery_info.delivery_tag, false)
74
+ begin
75
+ eventbase.exec(context)
76
+ ch.acknowledge(delivery_info.delivery_tag, false)
77
+ rescue
78
+ sleep 1
79
+ warn "Error on RabbitMQ event processing on context #{context}"
80
+ ch.reject(delivery_info.delivery_tag, true)
81
+ end
76
82
  end
77
83
 
78
84
  id = queue + "-" + block.to_s
@@ -28,7 +28,7 @@ class Ocular
28
28
  end
29
29
 
30
30
  def self.load_from_file(filename)
31
- #puts "Loaded settings from #{filename}"
31
+ ::Ocular.logger.debug "Loaded settings from #{filename}"
32
32
  @settings = ::Ocular::deep_symbolize(YAML::load_file(filename))
33
33
  end
34
34
 
@@ -1,3 +1,3 @@
1
1
  class Ocular
2
- Version = "0.1.16"
2
+ Version = "0.1.17"
3
3
  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.16
4
+ version: 0.1.17
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-04-22 00:00:00.000000000 Z
11
+ date: 2016-05-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rye