dkron-rb 0.9.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +3 -0
  3. data/Gemfile.lock +65 -0
  4. data/LICENSE +201 -0
  5. data/README.md +98 -0
  6. data/Rakefile +6 -0
  7. data/bin/console +14 -0
  8. data/bin/setup +8 -0
  9. data/config.json +5 -0
  10. data/dkron-rb-0.0.1.gem +0 -0
  11. data/dkron-rb-0.0.2.gem +0 -0
  12. data/dkron-rb.gemspec +55 -0
  13. data/docs/Agent.md +7 -0
  14. data/docs/DefaultApi.md +131 -0
  15. data/docs/Execution.md +13 -0
  16. data/docs/ExecutionsApi.md +55 -0
  17. data/docs/InlineResponse200.md +10 -0
  18. data/docs/Job.md +24 -0
  19. data/docs/JobsApi.md +237 -0
  20. data/docs/MainApi.md +90 -0
  21. data/docs/Member.md +18 -0
  22. data/docs/MembersApi.md +49 -0
  23. data/docs/Serf.md +7 -0
  24. data/docs/Status.md +7 -0
  25. data/docs/Tags.md +7 -0
  26. data/git_push.sh +67 -0
  27. data/lib/dkron-rb.rb +47 -0
  28. data/lib/dkron-rb/api/default_api.rb +193 -0
  29. data/lib/dkron-rb/api/executions_api.rb +91 -0
  30. data/lib/dkron-rb/api/jobs_api.rb +315 -0
  31. data/lib/dkron-rb/api/members_api.rb +87 -0
  32. data/lib/dkron-rb/api_client.rb +378 -0
  33. data/lib/dkron-rb/api_error.rb +47 -0
  34. data/lib/dkron-rb/configuration.rb +207 -0
  35. data/lib/dkron-rb/cron.rb +152 -0
  36. data/lib/dkron-rb/models/agent.rb +152 -0
  37. data/lib/dkron-rb/models/execution.rb +250 -0
  38. data/lib/dkron-rb/models/inline_response_200.rb +181 -0
  39. data/lib/dkron-rb/models/job.rb +369 -0
  40. data/lib/dkron-rb/models/member.rb +301 -0
  41. data/lib/dkron-rb/models/serf.rb +152 -0
  42. data/lib/dkron-rb/models/status.rb +190 -0
  43. data/lib/dkron-rb/models/tags.rb +152 -0
  44. data/lib/dkron-rb/numeric_seconds.rb +48 -0
  45. data/lib/dkron-rb/version.rb +26 -0
  46. data/lib/dkron.rb +9 -0
  47. data/pkg/dkron-rb-0.9.2.gem +0 -0
  48. data/seeds.rb +18 -0
  49. data/spec/api/default_api_spec.rb +80 -0
  50. data/spec/api/executions_api_spec.rb +51 -0
  51. data/spec/api/jobs_api_spec.rb +114 -0
  52. data/spec/api/main_api_spec.rb +65 -0
  53. data/spec/api/members_api_spec.rb +50 -0
  54. data/spec/api_client_spec.rb +237 -0
  55. data/spec/configuration_spec.rb +53 -0
  56. data/spec/models/agent_spec.rb +36 -0
  57. data/spec/models/execution_spec.rb +96 -0
  58. data/spec/models/inline_response_200_spec.rb +66 -0
  59. data/spec/models/job_spec.rb +186 -0
  60. data/spec/models/member_spec.rb +146 -0
  61. data/spec/models/serf_spec.rb +36 -0
  62. data/spec/models/status_spec.rb +36 -0
  63. data/spec/models/tags_spec.rb +36 -0
  64. data/spec/spec_helper.rb +122 -0
  65. metadata +309 -0
@@ -0,0 +1,152 @@
1
+ require 'chronic'
2
+
3
+ module Dkron
4
+ module Output
5
+ class Cron
6
+ KEYWORDS = [:yearly, :annually, :monthly, :weekly, :daily, :midnight, :hourly, :minutely]
7
+ REGEX = /^(@(#{KEYWORDS.join '|'})|((\*?[\d\/,\-]*)\s*){5})$/
8
+
9
+ attr_accessor :time, :task
10
+
11
+ def initialize(time = nil, task = nil, at = nil)
12
+ @at_given = at
13
+ @time = time
14
+ @task = task
15
+ @at = at.is_a?(String) ? (Chronic.parse(at) || 0) : (at || 0)
16
+ end
17
+
18
+ def self.enumerate(item, detect_cron = true)
19
+ if item and item.is_a?(String)
20
+ items =
21
+ if detect_cron && item =~ REGEX
22
+ [item]
23
+ else
24
+ item.split(',')
25
+ end
26
+ else
27
+ items = item
28
+ items = [items] unless items and items.respond_to?(:each)
29
+ end
30
+ items
31
+ end
32
+
33
+ def self.output(times, job)
34
+ enumerate(times).each do |time|
35
+ enumerate(job.at, false).each do |at|
36
+ yield new(time, job.output, at).output
37
+ end
38
+ end
39
+ end
40
+
41
+ def output
42
+ [time_in_cron_syntax, task].compact.join(' ').strip
43
+ end
44
+
45
+ def time_in_cron_syntax
46
+ @time = @time.to_i if @time.is_a?(Numeric) # Compatibility with `1.day` format using ruby 2.3 and activesupport
47
+ case @time
48
+ when REGEX then @time # raw cron syntax given
49
+ when Symbol then parse_symbol
50
+ when String then parse_as_string
51
+ else parse_time
52
+ end
53
+ end
54
+
55
+ protected
56
+ def day_given?
57
+ months = %w(jan feb mar apr may jun jul aug sep oct nov dec)
58
+ @at_given.is_a?(String) && months.any? { |m| @at_given.downcase.index(m) }
59
+ end
60
+
61
+ def parse_symbol
62
+ shortcut = case @time
63
+ when :year then Dkron.seconds(12, :months)
64
+ when :day then Dkron.seconds(1, :day)
65
+ when :month then Dkron.seconds(1, :month)
66
+ when :week then Dkron.seconds(1, :week)
67
+ when :hour then Dkron.seconds(1, :hour)
68
+ end
69
+
70
+ if shortcut.is_a?(Numeric)
71
+ @time = shortcut
72
+ parse_time
73
+ elsif shortcut
74
+ if @at.is_a?(Time) || (@at.is_a?(Numeric) && @at > 0)
75
+ raise ArgumentError, "You cannot specify an ':at' when using the shortcuts for times."
76
+ else
77
+ return shortcut
78
+ end
79
+ else
80
+ parse_as_string
81
+ end
82
+ end
83
+
84
+ def parse_time
85
+ timing = Array.new(6, '*')
86
+ case @time
87
+ when Dkron.seconds(0, :seconds)...Dkron.seconds(1, :minute)
88
+ raise ArgumentError, "Time must be in minutes or higher"
89
+ when Dkron.seconds(1, :minute)...Dkron.seconds(1, :hour)
90
+ minute_frequency = @time / 60
91
+ timing[0] = comma_separated_timing(minute_frequency, 59, @at || 0)
92
+ when Dkron.seconds(1, :hour)...Dkron.seconds(1, :day)
93
+ hour_frequency = (@time / 60 / 60).round
94
+ timing[0] = @at.is_a?(Time) ? @at.min : @at
95
+ timing[1] = comma_separated_timing(hour_frequency, 23)
96
+ when Dkron.seconds(1, :day)...Dkron.seconds(1, :month)
97
+ day_frequency = (@time / 24 / 60 / 60).round
98
+ timing[0] = @at.is_a?(Time) ? @at.min : 0
99
+ timing[1] = @at.is_a?(Time) ? @at.hour : @at
100
+ timing[2] = comma_separated_timing(day_frequency, 31, 1)
101
+ when Dkron.seconds(1, :month)..Dkron.seconds(12, :months)
102
+ month_frequency = (@time / 30 / 24 / 60 / 60).round
103
+ timing[0] = @at.is_a?(Time) ? @at.min : 0
104
+ timing[1] = @at.is_a?(Time) ? @at.hour : 0
105
+ timing[2] = if @at.is_a?(Time)
106
+ day_given? ? @at.day : 1
107
+ else
108
+ @at.zero? ? 1 : @at
109
+ end
110
+ timing[3] = comma_separated_timing(month_frequency, 12, 1)
111
+ else
112
+ return parse_as_string
113
+ end
114
+ timing.join(' ')
115
+ end
116
+
117
+ def parse_as_string
118
+ return unless @time
119
+ string = @time.to_s
120
+
121
+ timing = Array.new(4, '*')
122
+ timing[0] = @at.is_a?(Time) ? @at.min : 0
123
+ timing[1] = @at.is_a?(Time) ? @at.hour : 0
124
+
125
+ return (timing << '1-5') * " " if string.downcase.index('weekday')
126
+ return (timing << '6,0') * " " if string.downcase.index('weekend')
127
+
128
+ %w(sun mon tue wed thu fri sat).each_with_index do |day, i|
129
+ return (timing << i) * " " if string.downcase.index(day)
130
+ end
131
+
132
+ raise ArgumentError, "Couldn't parse: #{@time}"
133
+ end
134
+
135
+ def comma_separated_timing(frequency, max, start = 0)
136
+ return start if frequency.nil? || frequency == "" || frequency.zero?
137
+ return '*' if frequency == 1
138
+ return frequency if frequency > (max * 0.5).ceil
139
+
140
+ original_start = start
141
+
142
+ start += frequency unless (max + 1).modulo(frequency).zero? || start > 0
143
+ output = (start..max).step(frequency).to_a
144
+
145
+ max_occurances = (max.to_f / (frequency.to_f)).round
146
+ max_occurances += 1 if original_start.zero?
147
+
148
+ output[0, max_occurances].join(',')
149
+ end
150
+ end
151
+ end
152
+ end
@@ -0,0 +1,152 @@
1
+ =begin
2
+ Dkron REST API
3
+
4
+ You can communicate with Dkron using a RESTful JSON API over HTTP. Dkron nodes usually listen on port `8080` for API requests. All examples in this section assume that you've found a running leader at `localhost:8080`.\n\nDkron implements a RESTful JSON API over HTTP to communicate with software clients. Dkron listens in port `8080` by default. All examples in this section assume that you're using the default port.\n\nDefault API responses are unformatted JSON add the `pretty=true` param to format the response.\n
5
+
6
+ OpenAPI spec version: 0.7.2
7
+
8
+ Generated by: https://github.com/swagger-api/swagger-codegen.git
9
+
10
+
11
+ =end
12
+
13
+ require 'date'
14
+
15
+ module Dkron
16
+ # Node basic details
17
+ class Agent
18
+ # Attribute mapping from ruby-style variable name to JSON key.
19
+ def self.attribute_map
20
+ {
21
+
22
+ }
23
+ end
24
+
25
+ # Attribute type mapping.
26
+ def self.swagger_types
27
+ {
28
+
29
+ }
30
+ end
31
+
32
+ def initialize(attributes = {})
33
+ return unless attributes.is_a?(Hash)
34
+
35
+ # convert string to symbol for hash key
36
+ attributes = attributes.inject({}){|memo,(k,v)| memo[k.to_sym] = v; memo}
37
+
38
+
39
+ end
40
+
41
+ # Check equality by comparing each attribute.
42
+ def ==(o)
43
+ return true if self.equal?(o)
44
+ self.class == o.class
45
+ end
46
+
47
+ # @see the `==` method
48
+ def eql?(o)
49
+ self == o
50
+ end
51
+
52
+ # Calculate hash code according to all attributes.
53
+ def hash
54
+ [].hash
55
+ end
56
+
57
+ # build the object from hash
58
+ def build_from_hash(attributes)
59
+ return nil unless attributes.is_a?(Hash)
60
+ self.class.swagger_types.each_pair do |key, type|
61
+ if type =~ /^Array<(.*)>/i
62
+ if attributes[self.class.attribute_map[key]].is_a?(Array)
63
+ self.send("#{key}=", attributes[self.class.attribute_map[key]].map{ |v| _deserialize($1, v) } )
64
+ else
65
+ #TODO show warning in debug mode
66
+ end
67
+ elsif !attributes[self.class.attribute_map[key]].nil?
68
+ self.send("#{key}=", _deserialize(type, attributes[self.class.attribute_map[key]]))
69
+ else
70
+ # data not found in attributes(hash), not an issue as the data can be optional
71
+ end
72
+ end
73
+
74
+ self
75
+ end
76
+
77
+ def _deserialize(type, value)
78
+ case type.to_sym
79
+ when :DateTime
80
+ DateTime.parse(value)
81
+ when :Date
82
+ Date.parse(value)
83
+ when :String
84
+ value.to_s
85
+ when :Integer
86
+ value.to_i
87
+ when :Float
88
+ value.to_f
89
+ when :BOOLEAN
90
+ if value.to_s =~ /^(true|t|yes|y|1)$/i
91
+ true
92
+ else
93
+ false
94
+ end
95
+ when :Object
96
+ # generic object (usually a Hash), return directly
97
+ value
98
+ when /\AArray<(?<inner_type>.+)>\z/
99
+ inner_type = Regexp.last_match[:inner_type]
100
+ value.map { |v| _deserialize(inner_type, v) }
101
+ when /\AHash<(?<k_type>.+), (?<v_type>.+)>\z/
102
+ k_type = Regexp.last_match[:k_type]
103
+ v_type = Regexp.last_match[:v_type]
104
+ {}.tap do |hash|
105
+ value.each do |k, v|
106
+ hash[_deserialize(k_type, k)] = _deserialize(v_type, v)
107
+ end
108
+ end
109
+ else # model
110
+ _model = Dkron.const_get(type).new
111
+ _model.build_from_hash(value)
112
+ end
113
+ end
114
+
115
+ def to_s
116
+ to_hash.to_s
117
+ end
118
+
119
+ # to_body is an alias to to_body (backward compatibility))
120
+ def to_body
121
+ to_hash
122
+ end
123
+
124
+ # return the object in the form of hash
125
+ def to_hash
126
+ hash = {}
127
+ self.class.attribute_map.each_pair do |attr, param|
128
+ value = self.send(attr)
129
+ next if value.nil?
130
+ hash[param] = _to_hash(value)
131
+ end
132
+ hash
133
+ end
134
+
135
+ # Method to output non-array value in the form of hash
136
+ # For object, use to_hash. Otherwise, just return the value
137
+ def _to_hash(value)
138
+ if value.is_a?(Array)
139
+ value.compact.map{ |v| _to_hash(v) }
140
+ elsif value.is_a?(Hash)
141
+ {}.tap do |hash|
142
+ value.each { |k, v| hash[k] = _to_hash(v) }
143
+ end
144
+ elsif value.respond_to? :to_hash
145
+ value.to_hash
146
+ else
147
+ value
148
+ end
149
+ end
150
+
151
+ end
152
+ end
@@ -0,0 +1,250 @@
1
+ =begin
2
+ #Dkron REST API
3
+
4
+ #You can communicate with Dkron using a RESTful JSON API over HTTP. Dkron nodes usually listen on port `8080` for API requests. All examples in this section assume that you've found a running leader at `localhost:8080`. Dkron implements a RESTful JSON API over HTTP to communicate with software clients. Dkron listens in port `8080` by default. All examples in this section assume that you're using the default port. Default API responses are unformatted JSON add the `pretty=true` param to format the response.
5
+
6
+ OpenAPI spec version: 0.9.2
7
+
8
+ Generated by: https://github.com/swagger-api/swagger-codegen.git
9
+
10
+ Licensed under the Apache License, Version 2.0 (the "License");
11
+ you may not use this file except in compliance with the License.
12
+ You may obtain a copy of the License at
13
+
14
+ http://www.apache.org/licenses/LICENSE-2.0
15
+
16
+ Unless required by applicable law or agreed to in writing, software
17
+ distributed under the License is distributed on an "AS IS" BASIS,
18
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19
+ See the License for the specific language governing permissions and
20
+ limitations under the License.
21
+
22
+ =end
23
+
24
+ require 'date'
25
+
26
+ module Dkron
27
+ # An execution represents a timed job run.
28
+ class Execution
29
+ # job name
30
+ attr_accessor :job_name
31
+
32
+ # start time of the execution
33
+ attr_accessor :started_at
34
+
35
+ # when the execution finished running
36
+ attr_accessor :finished_at
37
+
38
+ # the execution run successfuly
39
+ attr_accessor :success
40
+
41
+ # partial output of the command execution
42
+ attr_accessor :output
43
+
44
+ # name of the node that executed the command
45
+ attr_accessor :node_name
46
+
47
+
48
+ # Attribute mapping from ruby-style variable name to JSON key.
49
+ def self.attribute_map
50
+ {
51
+ :'job_name' => :'job_name',
52
+ :'started_at' => :'started_at',
53
+ :'finished_at' => :'finished_at',
54
+ :'success' => :'success',
55
+ :'output' => :'output',
56
+ :'node_name' => :'node_name'
57
+ }
58
+ end
59
+
60
+ # Attribute type mapping.
61
+ def self.swagger_types
62
+ {
63
+ :'job_name' => :'String',
64
+ :'started_at' => :'DateTime',
65
+ :'finished_at' => :'DateTime',
66
+ :'success' => :'BOOLEAN',
67
+ :'output' => :'String',
68
+ :'node_name' => :'String'
69
+ }
70
+ end
71
+
72
+ # Initializes the object
73
+ # @param [Hash] attributes Model attributes in the form of hash
74
+ def initialize(attributes = {})
75
+ return unless attributes.is_a?(Hash)
76
+
77
+ # convert string to symbol for hash key
78
+ attributes = attributes.each_with_object({}){|(k,v), h| h[k.to_sym] = v}
79
+
80
+ if attributes.has_key?(:'job_name')
81
+ self.job_name = attributes[:'job_name']
82
+ end
83
+
84
+ if attributes.has_key?(:'started_at')
85
+ self.started_at = attributes[:'started_at']
86
+ end
87
+
88
+ if attributes.has_key?(:'finished_at')
89
+ self.finished_at = attributes[:'finished_at']
90
+ end
91
+
92
+ if attributes.has_key?(:'success')
93
+ self.success = attributes[:'success']
94
+ end
95
+
96
+ if attributes.has_key?(:'output')
97
+ self.output = attributes[:'output']
98
+ end
99
+
100
+ if attributes.has_key?(:'node_name')
101
+ self.node_name = attributes[:'node_name']
102
+ end
103
+
104
+ end
105
+
106
+ # Show invalid properties with the reasons. Usually used together with valid?
107
+ # @return Array for valid properies with the reasons
108
+ def list_invalid_properties
109
+ invalid_properties = Array.new
110
+ return invalid_properties
111
+ end
112
+
113
+ # Check to see if the all the properties in the model are valid
114
+ # @return true if the model is valid
115
+ def valid?
116
+ return true
117
+ end
118
+
119
+ # Checks equality by comparing each attribute.
120
+ # @param [Object] Object to be compared
121
+ def ==(o)
122
+ return true if self.equal?(o)
123
+ self.class == o.class &&
124
+ job_name == o.job_name &&
125
+ started_at == o.started_at &&
126
+ finished_at == o.finished_at &&
127
+ success == o.success &&
128
+ output == o.output &&
129
+ node_name == o.node_name
130
+ end
131
+
132
+ # @see the `==` method
133
+ # @param [Object] Object to be compared
134
+ def eql?(o)
135
+ self == o
136
+ end
137
+
138
+ # Calculates hash code according to all attributes.
139
+ # @return [Fixnum] Hash code
140
+ def hash
141
+ [job_name, started_at, finished_at, success, output, node_name].hash
142
+ end
143
+
144
+ # Builds the object from hash
145
+ # @param [Hash] attributes Model attributes in the form of hash
146
+ # @return [Object] Returns the model itself
147
+ def build_from_hash(attributes)
148
+ return nil unless attributes.is_a?(Hash)
149
+ self.class.swagger_types.each_pair do |key, type|
150
+ if type =~ /^Array<(.*)>/i
151
+ # check to ensure the input is an array given that the the attribute
152
+ # is documented as an array but the input is not
153
+ if attributes[self.class.attribute_map[key]].is_a?(Array)
154
+ self.send("#{key}=", attributes[self.class.attribute_map[key]].map{ |v| _deserialize($1, v) } )
155
+ end
156
+ elsif !attributes[self.class.attribute_map[key]].nil?
157
+ self.send("#{key}=", _deserialize(type, attributes[self.class.attribute_map[key]]))
158
+ end # or else data not found in attributes(hash), not an issue as the data can be optional
159
+ end
160
+
161
+ self
162
+ end
163
+
164
+ # Deserializes the data based on type
165
+ # @param string type Data type
166
+ # @param string value Value to be deserialized
167
+ # @return [Object] Deserialized data
168
+ def _deserialize(type, value)
169
+ case type.to_sym
170
+ when :DateTime
171
+ DateTime.parse(value)
172
+ when :Date
173
+ Date.parse(value)
174
+ when :String
175
+ value.to_s
176
+ when :Integer
177
+ value.to_i
178
+ when :Float
179
+ value.to_f
180
+ when :BOOLEAN
181
+ if value.to_s =~ /^(true|t|yes|y|1)$/i
182
+ true
183
+ else
184
+ false
185
+ end
186
+ when :Object
187
+ # generic object (usually a Hash), return directly
188
+ value
189
+ when /\AArray<(?<inner_type>.+)>\z/
190
+ inner_type = Regexp.last_match[:inner_type]
191
+ value.map { |v| _deserialize(inner_type, v) }
192
+ when /\AHash<(?<k_type>.+), (?<v_type>.+)>\z/
193
+ k_type = Regexp.last_match[:k_type]
194
+ v_type = Regexp.last_match[:v_type]
195
+ {}.tap do |hash|
196
+ value.each do |k, v|
197
+ hash[_deserialize(k_type, k)] = _deserialize(v_type, v)
198
+ end
199
+ end
200
+ else # model
201
+ temp_model = Dkron.const_get(type).new
202
+ temp_model.build_from_hash(value)
203
+ end
204
+ end
205
+
206
+ # Returns the string representation of the object
207
+ # @return [String] String presentation of the object
208
+ def to_s
209
+ to_hash.to_s
210
+ end
211
+
212
+ # to_body is an alias to to_hash (backward compatibility)
213
+ # @return [Hash] Returns the object in the form of hash
214
+ def to_body
215
+ to_hash
216
+ end
217
+
218
+ # Returns the object in the form of hash
219
+ # @return [Hash] Returns the object in the form of hash
220
+ def to_hash
221
+ hash = {}
222
+ self.class.attribute_map.each_pair do |attr, param|
223
+ value = self.send(attr)
224
+ next if value.nil?
225
+ hash[param] = _to_hash(value)
226
+ end
227
+ hash
228
+ end
229
+
230
+ # Outputs non-array value in the form of hash
231
+ # For object, use to_hash. Otherwise, just return the value
232
+ # @param [Object] value Any valid value
233
+ # @return [Hash] Returns the value in the form of hash
234
+ def _to_hash(value)
235
+ if value.is_a?(Array)
236
+ value.compact.map{ |v| _to_hash(v) }
237
+ elsif value.is_a?(Hash)
238
+ {}.tap do |hash|
239
+ value.each { |k, v| hash[k] = _to_hash(v) }
240
+ end
241
+ elsif value.respond_to? :to_hash
242
+ value.to_hash
243
+ else
244
+ value
245
+ end
246
+ end
247
+
248
+ end
249
+
250
+ end