dkron-rb 0.9.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.
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