huginn_ruby_agent 0.1 → 0.2

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
  SHA256:
3
- metadata.gz: 46786fbef6ebd0f956499b17915fa8970f4285795073e3f55a9f6d026e8f9597
4
- data.tar.gz: 21cf1e531eb5652e34eecf0a8b0151458902f4bee65fe69b5c4110cfe5b2c0f5
3
+ metadata.gz: 602117200b2aadebec8c4c6e959c9ab19c4bb585df0a9c72b7926f8b0adc8638
4
+ data.tar.gz: 65d559d7e90b569f74c8cd890786ac830d469fd58923c75f50399af64c914b1e
5
5
  SHA512:
6
- metadata.gz: 2a5c0ebee329f780bdc08637a03803de430cf16753f27f14456380c4cedd598b85a8398a4eb94c1c4355e75a9fc095279e0be90c4032872d8c3159ba934f879b
7
- data.tar.gz: 2ecc2518b29ef5f6edfc432325670f8ad09d7f29bb70cd25bc0d09329a87dae0cf9f8053714fd1a335772ce06fd3e106533d9d273ac29034f607aa6399ed433d
6
+ metadata.gz: 540dd8062b8fed871c15a5f784de8eece0317480a6e59025d4345a86267409660b187f37ca4f03ce48e89b0d8b685b196fc9c095e7ca6c20cb7335b15d42960c
7
+ data.tar.gz: c68d5ef8c376d7af0121378ffc4323cae0bd51a78802716990c0f9b62dd6d11f7646697d74b73934735cc182a6ba12032682b00caaf61a652cd2dcf6dd4f175e
@@ -1,29 +1,238 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'date'
4
+ require 'cgi'
5
+ require 'tempfile'
6
+ require 'base64'
7
+
8
+ # https://stackoverflow.com/questions/23884526/is-there-a-safe-way-to-eval-in-ruby-or-a-better-way-to-do-this
3
9
  module Agents
4
10
  class RubyAgent < Agent
5
- default_schedule '12h'
11
+ include FormConfigurable
12
+
13
+ can_dry_run!
14
+
15
+ default_schedule "never"
16
+
17
+ gem_dependency_check { defined?(MiniRacer) }
6
18
 
7
19
  description <<-MD
8
- Add a Agent description here
20
+ The Ruby Agent allows you to write code in Ruby that can create and receive events. If other Agents aren't meeting your needs, try this one!
21
+
22
+ You should put code in the `code` option.
23
+
24
+ You can implement `Agent.check` and `Agent.receive` as you see fit. The following methods will be available on Agent:
25
+
26
+ * `createEvent(payload)`
27
+ * `incomingEvents()` (the returned event objects will each have a `payload` property)
28
+ * `memory()`
29
+ * `memory(key)`
30
+ * `memory(keyToSet, valueToSet)`
31
+ * `setMemory(object)` (replaces the Agent's memory with the provided object)
32
+ * `deleteKey(key)` (deletes a key from memory and returns the value)
33
+ * `credential(name)`
34
+ * `credential(name, valueToSet)`
35
+ * `options()`
36
+ * `options(key)`
37
+ * `log(message)`
38
+ * `error(message)`
9
39
  MD
10
40
 
41
+ form_configurable :code, type: :text, ace: true
42
+ form_configurable :expected_receive_period_in_days
43
+ form_configurable :expected_update_period_in_days
44
+
45
+ def validate_options
46
+ errors.add(:base, "The 'code' option is required") unless options['code'].present?
47
+ end
48
+
49
+ def working?
50
+ return false if recent_error_logs?
51
+
52
+ if interpolated['expected_update_period_in_days'].present?
53
+ return false unless event_created_within?(interpolated['expected_update_period_in_days'])
54
+ end
55
+
56
+ if interpolated['expected_receive_period_in_days'].present?
57
+ return false unless last_receive_at && last_receive_at > interpolated['expected_receive_period_in_days'].to_i.days.ago
58
+ end
59
+
60
+ true
61
+ end
62
+
63
+ def check
64
+ log_errors do
65
+ execute_check
66
+ end
67
+ end
68
+
69
+ def receive(events)
70
+ log_errors do
71
+ execute_receive(events)
72
+ end
73
+ end
74
+
11
75
  def default_options
12
- {}
76
+ code = <<~CODE
77
+
78
+ require "bundler/inline"
79
+
80
+ gemfile do
81
+ source "https://rubygems.org"
82
+
83
+ # gem "mechanize"
84
+ end
85
+
86
+ class Agent
87
+ def initialize(api)
88
+ @api = api
89
+ end
90
+
91
+ def check
92
+ @api.create_event({ message: 'I made an event!' })
93
+ end
94
+
95
+ def receive(incoming_events)
96
+ incoming_events.each do |event|
97
+ @api.create_event({ message: 'new event', event_was: event[:payload] })
98
+ end
99
+ end
100
+ end
101
+ CODE
102
+
103
+ {
104
+ 'code' => code,
105
+ 'expected_receive_period_in_days' => '2',
106
+ 'expected_update_period_in_days' => '2'
107
+ }
13
108
  end
14
109
 
15
- def validate_options; end
110
+ private
16
111
 
17
- def working?
18
- # Implement me! Maybe one of these next two lines would be a good fit?
19
- # checked_without_error?
20
- # received_event_without_error?
112
+ def execute_check
113
+ Bundler.with_original_env do
114
+ Open3.popen3("ruby", chdir: '/') do |input, output, err, thread|
115
+ input.write sdk_code
116
+ input.write code
117
+ input.write <<~CODE
118
+
119
+ Agent.new(Huginn::API.new).check
120
+
121
+ CODE
122
+ input.close
123
+
124
+
125
+ output.readlines.map { |line| JSON.parse(line, symbolize_names: true) }.each do |data|
126
+ case data[:action]
127
+ when 'create_event'
128
+ create_event(payload: data[:payload])
129
+ when 'log'
130
+ log data[:payload]
131
+ when 'error'
132
+ error data[:payload]
133
+ end
134
+ end
135
+
136
+ errors = err.read
137
+
138
+ error err.read
139
+ log "thread #{thread.value}"
140
+ end
141
+ end
142
+ end
143
+
144
+ def execute_receive(events)
145
+ Bundler.with_original_env do
146
+ Open3.popen3("ruby", chdir: '/') do |input, output, err, thread|
147
+ input.write sdk_code
148
+ input.write code
149
+ input.write <<~CODE
150
+
151
+ api = Huginn::API.new
152
+ begin
153
+ Agent.new(api).receive(
154
+ JSON.parse(
155
+ Base64.decode64(
156
+ "#{Base64.encode64(events.to_json)}"
157
+ ),
158
+ symbolize_names: true
159
+ )
160
+ )
161
+ rescue StandardError => ex
162
+ api.error ex
163
+ end
164
+
165
+ CODE
166
+ input.close
167
+
168
+
169
+ output.readlines.map { |line| JSON.parse(line, symbolize_names: true) }.each do |data|
170
+ case data[:action]
171
+ when 'create_event'
172
+ create_event(payload: data[:payload])
173
+ when 'log'
174
+ log data[:payload]
175
+ when 'error'
176
+ error data[:payload]
177
+ end
178
+ end
179
+
180
+ errors = err.read
181
+
182
+ error err.read
183
+ log "thread #{thread.value}"
184
+ end
185
+ end
186
+ end
187
+
188
+ def code
189
+ interpolated['code']
21
190
  end
22
191
 
23
- # def check
24
- # end
192
+ def sdk_code
193
+ <<~CODE
194
+ require 'json'
195
+ require 'base64'
196
+
197
+ module Huginn
198
+ class API
199
+ def create_event(payload)
200
+ puts(
201
+ {
202
+ action: :create_event,
203
+ payload: payload
204
+ }.to_json
205
+ )
206
+ end
207
+
208
+ def log(message)
209
+ puts(
210
+ {
211
+ action: :log,
212
+ payload: message
213
+ }.to_json
214
+ )
215
+ end
25
216
 
26
- # def receive(incoming_events)
27
- # end
217
+ def error(message)
218
+ puts(
219
+ {
220
+ action: :error,
221
+ payload: message
222
+ }.to_json
223
+ )
224
+ end
225
+ end
226
+ end
227
+ CODE
228
+ end
229
+
230
+ def log_errors
231
+ begin
232
+ yield
233
+ rescue StandardError => e
234
+ error "Runtime error: #{e.message}"
235
+ end
236
+ end
28
237
  end
29
238
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: huginn_ruby_agent
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.1'
4
+ version: '0.2'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sergei O. Udalov
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: huginn_agent
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -94,7 +108,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
94
108
  - !ruby/object:Gem::Version
95
109
  version: '0'
96
110
  requirements: []
97
- rubygems_version: 3.3.7
111
+ rubygems_version: 3.1.6
98
112
  signing_key:
99
113
  specification_version: 4
100
114
  summary: Ruby Agent for Huginn automation platform