smplkit 3.0.95 → 3.0.97
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 +4 -4
- data/lib/smplkit/account/client.rb +128 -0
- data/lib/smplkit/account/models.rb +71 -0
- data/lib/smplkit/api_support.rb +91 -0
- data/lib/smplkit/audit/buffer.rb +3 -1
- data/lib/smplkit/audit/categories.rb +21 -10
- data/lib/smplkit/audit/client.rb +18 -9
- data/lib/smplkit/audit/event_types.rb +26 -10
- data/lib/smplkit/audit/events.rb +93 -17
- data/lib/smplkit/{management/audit.rb → audit/forwarders.rb} +93 -85
- data/lib/smplkit/audit/models.rb +86 -32
- data/lib/smplkit/audit/resource_types.rb +21 -9
- data/lib/smplkit/buffers.rb +250 -0
- data/lib/smplkit/client.rb +161 -70
- data/lib/smplkit/config/client.rb +874 -186
- data/lib/smplkit/config/helpers.rb +44 -6
- data/lib/smplkit/config/models.rb +114 -7
- data/lib/smplkit/config_resolution.rb +17 -9
- data/lib/smplkit/errors.rb +14 -3
- data/lib/smplkit/flags/client.rb +602 -116
- data/lib/smplkit/flags/models.rb +110 -8
- data/lib/smplkit/flags/types.rb +8 -9
- data/lib/smplkit/jobs/client.rb +306 -0
- data/lib/smplkit/jobs/models.rb +47 -18
- data/lib/smplkit/logging/client.rb +755 -191
- data/lib/smplkit/logging/helpers.rb +5 -1
- data/lib/smplkit/logging/levels.rb +3 -1
- data/lib/smplkit/logging/models.rb +163 -6
- data/lib/smplkit/logging/normalize.rb +3 -1
- data/lib/smplkit/logging/resolution.rb +4 -4
- data/lib/smplkit/logging/sources.rb +1 -1
- data/lib/smplkit/platform/client.rb +597 -0
- data/lib/smplkit/platform/models.rb +282 -0
- data/lib/smplkit/{management → platform}/types.rb +21 -4
- data/lib/smplkit/transport.rb +103 -0
- data/lib/smplkit/ws.rb +1 -1
- data/lib/smplkit.rb +18 -6
- metadata +11 -7
- data/lib/smplkit/management/buffer.rb +0 -198
- data/lib/smplkit/management/client.rb +0 -1074
- data/lib/smplkit/management/jobs.rb +0 -226
- data/lib/smplkit/management/models.rb +0 -178
data/lib/smplkit/flags/models.rb
CHANGED
|
@@ -99,11 +99,21 @@ module Smplkit
|
|
|
99
99
|
end
|
|
100
100
|
|
|
101
101
|
# Read-only view of constrained values. +nil+ means unconstrained.
|
|
102
|
+
#
|
|
103
|
+
# Mutate via +add_value+ / +remove_value+ / +clear_values+.
|
|
104
|
+
#
|
|
105
|
+
# @return [Array<FlagValue>, nil] the constrained values, or +nil+ when
|
|
106
|
+
# the flag is unconstrained.
|
|
102
107
|
def values
|
|
103
108
|
@values&.dup
|
|
104
109
|
end
|
|
105
110
|
|
|
106
111
|
# Read-only view of per-environment configuration.
|
|
112
|
+
#
|
|
113
|
+
# Mutate via +add_rule+ / +enable_rules+ / +disable_rules+ /
|
|
114
|
+
# +set_default+ (with +environment:+) / +clear_rules+.
|
|
115
|
+
#
|
|
116
|
+
# @return [Hash{String => FlagEnvironment}] the per-environment configuration.
|
|
107
117
|
def environments
|
|
108
118
|
@environments.dup
|
|
109
119
|
end
|
|
@@ -111,8 +121,10 @@ module Smplkit
|
|
|
111
121
|
# Persist this flag to the server.
|
|
112
122
|
#
|
|
113
123
|
# Creates a new flag if unsaved, or updates the existing one. Requires a
|
|
114
|
-
#
|
|
115
|
-
#
|
|
124
|
+
# client (i.e. the flag was constructed via +client.flags.new_*+ or
|
|
125
|
+
# returned from +client.flags.get+ / +client.flags.list+).
|
|
126
|
+
#
|
|
127
|
+
# @return [self] this flag, with server-assigned fields applied.
|
|
116
128
|
def save
|
|
117
129
|
raise "Flag was constructed without a client; cannot save" if @client.nil?
|
|
118
130
|
|
|
@@ -127,6 +139,10 @@ module Smplkit
|
|
|
127
139
|
end
|
|
128
140
|
alias save! save
|
|
129
141
|
|
|
142
|
+
# Delete this flag from the server.
|
|
143
|
+
#
|
|
144
|
+
# @return [void]
|
|
145
|
+
# @raise [Smplkit::NotFoundError] no flag with this id exists for the account.
|
|
130
146
|
def delete
|
|
131
147
|
raise "Flag was constructed without a client or id; cannot delete" if @client.nil? || @id.nil?
|
|
132
148
|
|
|
@@ -138,6 +154,12 @@ module Smplkit
|
|
|
138
154
|
#
|
|
139
155
|
# The +built_rule+ Hash must include an +"environment"+ key.
|
|
140
156
|
# Call +save+ to persist.
|
|
157
|
+
#
|
|
158
|
+
# @param built_rule [Hash] the Hash produced by
|
|
159
|
+
# +Smplkit::Rule.new(..., environment: ...).when(...).serve(...)+; must
|
|
160
|
+
# include an +"environment"+ key naming the target environment.
|
|
161
|
+
# @return [self] this flag, so calls can be chained.
|
|
162
|
+
# @raise [ArgumentError] the +built_rule+ Hash has no +"environment"+ key.
|
|
141
163
|
def add_rule(built_rule)
|
|
142
164
|
env_key = built_rule["environment"]
|
|
143
165
|
if env_key.nil?
|
|
@@ -156,16 +178,37 @@ module Smplkit
|
|
|
156
178
|
self
|
|
157
179
|
end
|
|
158
180
|
|
|
181
|
+
# Enable rule evaluation. Call +save+ to persist.
|
|
182
|
+
#
|
|
183
|
+
# @param environment [String, nil] name of the environment to enable; when
|
|
184
|
+
# +nil+ (the default), enables rules in every environment configured on
|
|
185
|
+
# this flag.
|
|
186
|
+
# @return [self] this flag, so calls can be chained.
|
|
159
187
|
def enable_rules(environment: nil)
|
|
160
188
|
scoped(environment) { |k| @environments[k] = (@environments[k] || FlagEnvironment.new).with(enabled: true) }
|
|
161
189
|
self
|
|
162
190
|
end
|
|
163
191
|
|
|
192
|
+
# Disable rule evaluation (kill switch). Call +save+ to persist.
|
|
193
|
+
#
|
|
194
|
+
# When disabled, +get+ skips rules and returns the env-specific default
|
|
195
|
+
# (or the flag's base default).
|
|
196
|
+
#
|
|
197
|
+
# @param environment [String, nil] name of the environment to disable; when
|
|
198
|
+
# +nil+ (the default), disables rules in every environment configured on
|
|
199
|
+
# this flag.
|
|
200
|
+
# @return [self] this flag, so calls can be chained.
|
|
164
201
|
def disable_rules(environment: nil)
|
|
165
202
|
scoped(environment) { |k| @environments[k] = (@environments[k] || FlagEnvironment.new).with(enabled: false) }
|
|
166
203
|
self
|
|
167
204
|
end
|
|
168
205
|
|
|
206
|
+
# Remove rules. Call +save+ to persist.
|
|
207
|
+
#
|
|
208
|
+
# @param environment [String, nil] name of the environment whose rules to
|
|
209
|
+
# remove; when +nil+ (the default), removes rules from every environment
|
|
210
|
+
# configured on this flag.
|
|
211
|
+
# @return [self] this flag, so calls can be chained.
|
|
169
212
|
def clear_rules(environment: nil)
|
|
170
213
|
scoped(environment) do |k|
|
|
171
214
|
@environments[k] = (@environments[k] || FlagEnvironment.new).with(rules: [].freeze)
|
|
@@ -173,22 +216,44 @@ module Smplkit
|
|
|
173
216
|
self
|
|
174
217
|
end
|
|
175
218
|
|
|
219
|
+
# Set the flag's per-environment default served value. Call +save+ to persist.
|
|
220
|
+
#
|
|
221
|
+
# @param value [Object] the default value to serve when no rule matches.
|
|
222
|
+
# @param environment [String] name of the environment whose default to set.
|
|
223
|
+
# @return [self] this flag, so calls can be chained.
|
|
176
224
|
def set_default(value, environment:)
|
|
177
225
|
@environments[environment] = (@environments[environment] || FlagEnvironment.new).with(default: value)
|
|
178
226
|
self
|
|
179
227
|
end
|
|
180
228
|
|
|
229
|
+
# Clear the per-environment default override on +environment+.
|
|
230
|
+
#
|
|
231
|
+
# After clearing, the environment falls back to the flag's base default
|
|
232
|
+
# when no rule matches. Call +save+ to persist.
|
|
233
|
+
#
|
|
234
|
+
# @param environment [String] name of the environment whose default
|
|
235
|
+
# override to clear.
|
|
236
|
+
# @return [self] this flag, so calls can be chained.
|
|
181
237
|
def clear_default(environment:)
|
|
182
238
|
@environments[environment] = (@environments[environment] || FlagEnvironment.new).with(default: nil)
|
|
183
239
|
self
|
|
184
240
|
end
|
|
185
241
|
|
|
242
|
+
# Append a constrained value to the flag's values list. Call +save+ to persist.
|
|
243
|
+
#
|
|
244
|
+
# @param flag_value [FlagValue] the value entry to allow the flag to serve.
|
|
245
|
+
# @return [self] this flag, so calls can be chained.
|
|
186
246
|
def add_value(flag_value)
|
|
187
247
|
@values ||= []
|
|
188
248
|
@values << flag_value
|
|
189
249
|
self
|
|
190
250
|
end
|
|
191
251
|
|
|
252
|
+
# Remove the first values entry whose +name+ matches.
|
|
253
|
+
#
|
|
254
|
+
# @param name [String] the value-entry name to remove; the first match is
|
|
255
|
+
# removed and others are left in place.
|
|
256
|
+
# @return [self] this flag, so calls can be chained.
|
|
192
257
|
def remove_value(name)
|
|
193
258
|
return self unless @values
|
|
194
259
|
|
|
@@ -196,6 +261,9 @@ module Smplkit
|
|
|
196
261
|
self
|
|
197
262
|
end
|
|
198
263
|
|
|
264
|
+
# Clear the constrained values list (unconstrained). Call +save+ to persist.
|
|
265
|
+
#
|
|
266
|
+
# @return [self] this flag, so calls can be chained.
|
|
199
267
|
def clear_values
|
|
200
268
|
@values = []
|
|
201
269
|
self
|
|
@@ -225,28 +293,62 @@ module Smplkit
|
|
|
225
293
|
end
|
|
226
294
|
|
|
227
295
|
class BooleanFlag < Flag
|
|
296
|
+
# Evaluate this flag and return its current boolean value.
|
|
297
|
+
#
|
|
298
|
+
# @param context [Array<Smplkit::Context>, nil] optional entities to
|
|
299
|
+
# evaluate targeting rules against; when omitted the ambient request
|
|
300
|
+
# context (if any) is used.
|
|
301
|
+
# @return [Boolean] the evaluated boolean value, or this flag's default
|
|
302
|
+
# when no environment override or rule applies (or the evaluated value
|
|
303
|
+
# is not a boolean).
|
|
228
304
|
def get(context: nil)
|
|
229
|
-
|
|
230
|
-
|
|
305
|
+
value = @client._evaluate_handle(@id, @default, context)
|
|
306
|
+
[true, false].include?(value) ? value : @default
|
|
231
307
|
end
|
|
232
308
|
end
|
|
233
309
|
|
|
234
310
|
class StringFlag < Flag
|
|
311
|
+
# Evaluate this flag and return its current string value.
|
|
312
|
+
#
|
|
313
|
+
# @param context [Array<Smplkit::Context>, nil] optional entities to
|
|
314
|
+
# evaluate targeting rules against; when omitted the ambient request
|
|
315
|
+
# context (if any) is used.
|
|
316
|
+
# @return [String] the evaluated string value, or this flag's default
|
|
317
|
+
# when no environment override or rule applies (or the evaluated value
|
|
318
|
+
# is not a String).
|
|
235
319
|
def get(context: nil)
|
|
236
|
-
|
|
237
|
-
|
|
320
|
+
value = @client._evaluate_handle(@id, @default, context)
|
|
321
|
+
value.is_a?(String) ? value : @default
|
|
238
322
|
end
|
|
239
323
|
end
|
|
240
324
|
|
|
241
325
|
class NumberFlag < Flag
|
|
326
|
+
# Evaluate this flag and return its current numeric value.
|
|
327
|
+
#
|
|
328
|
+
# @param context [Array<Smplkit::Context>, nil] optional entities to
|
|
329
|
+
# evaluate targeting rules against; when omitted the ambient request
|
|
330
|
+
# context (if any) is used.
|
|
331
|
+
# @return [Numeric] the evaluated numeric value, or this flag's default
|
|
332
|
+
# when no environment override or rule applies (or the evaluated value
|
|
333
|
+
# is not a Numeric).
|
|
242
334
|
def get(context: nil)
|
|
243
|
-
@client._evaluate_handle(@id, @default, context)
|
|
335
|
+
value = @client._evaluate_handle(@id, @default, context)
|
|
336
|
+
value.is_a?(Numeric) ? value : @default
|
|
244
337
|
end
|
|
245
338
|
end
|
|
246
339
|
|
|
247
340
|
class JsonFlag < Flag
|
|
341
|
+
# Evaluate this flag and return its current JSON value.
|
|
342
|
+
#
|
|
343
|
+
# @param context [Array<Smplkit::Context>, nil] optional entities to
|
|
344
|
+
# evaluate targeting rules against; when omitted the ambient request
|
|
345
|
+
# context (if any) is used.
|
|
346
|
+
# @return [Hash] the evaluated JSON object, or this flag's default when no
|
|
347
|
+
# environment override or rule applies (or the evaluated value is not a
|
|
348
|
+
# Hash).
|
|
248
349
|
def get(context: nil)
|
|
249
|
-
@client._evaluate_handle(@id, @default, context)
|
|
350
|
+
value = @client._evaluate_handle(@id, @default, context)
|
|
351
|
+
value.is_a?(Hash) ? value : @default
|
|
250
352
|
end
|
|
251
353
|
end
|
|
252
354
|
end
|
data/lib/smplkit/flags/types.rb
CHANGED
|
@@ -26,9 +26,9 @@ module Smplkit
|
|
|
26
26
|
# arguments) carry the data that targeting rules evaluate against.
|
|
27
27
|
#
|
|
28
28
|
# Used for both authoring (+flag.get(context: [...])+,
|
|
29
|
-
# +client.set_context([...])+, +
|
|
30
|
-
# (+
|
|
31
|
-
# +save+ / +delete+ ready to call).
|
|
29
|
+
# +client.set_context([...])+, +client.platform.contexts.register([...])+) and
|
|
30
|
+
# reading (+client.platform.contexts.list/get+ return populated +Context+
|
|
31
|
+
# instances with +save+ / +delete+ ready to call).
|
|
32
32
|
#
|
|
33
33
|
# Examples:
|
|
34
34
|
#
|
|
@@ -67,8 +67,8 @@ module Smplkit
|
|
|
67
67
|
@attributes = stringify_keys(new_attrs || {})
|
|
68
68
|
end
|
|
69
69
|
|
|
70
|
-
#
|
|
71
|
-
#
|
|
70
|
+
# @api private — associate a client with this context so save/delete can
|
|
71
|
+
# route through it.
|
|
72
72
|
def _bind_client(client)
|
|
73
73
|
@client = client
|
|
74
74
|
self
|
|
@@ -141,10 +141,9 @@ module Smplkit
|
|
|
141
141
|
|
|
142
142
|
# Describes a flag declaration for buffered registration.
|
|
143
143
|
#
|
|
144
|
-
# Used by +
|
|
145
|
-
#
|
|
146
|
-
#
|
|
147
|
-
# forwards declarations.
|
|
144
|
+
# Used by +client.flags.register+ to queue declarations for bulk
|
|
145
|
+
# registration. +service+ and +environment+ default to +nil+; the client
|
|
146
|
+
# fills them from the active +Smplkit::Client+ when it forwards declarations.
|
|
148
147
|
class FlagDeclaration
|
|
149
148
|
attr_reader :id, :type, :default, :service, :environment
|
|
150
149
|
|
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# The Smpl Jobs client — one unified +JobsClient+.
|
|
4
|
+
#
|
|
5
|
+
# Smpl Jobs schedules HTTP calls (cron-style +schedule+ + +http+ configuration)
|
|
6
|
+
# and records their run history. Unlike Config/Flags/Logging it installs no
|
|
7
|
+
# in-process machinery, so it has no runtime/management split: a single
|
|
8
|
+
# +JobsClient+ exposes the full surface and is reachable as +client.jobs+ on
|
|
9
|
+
# +Smplkit::Client+ or constructed directly.
|
|
10
|
+
#
|
|
11
|
+
# client.jobs.{new,get,list,delete,run,usage}
|
|
12
|
+
# client.jobs.runs.{list,get,cancel,rerun}
|
|
13
|
+
# Job#{save,delete}
|
|
14
|
+
#
|
|
15
|
+
# The shared model classes (+Job+, +Run+, +Usage+, +HttpConfig+) live in
|
|
16
|
+
# +lib/smplkit/jobs/models.rb+.
|
|
17
|
+
module Smplkit
|
|
18
|
+
module Jobs
|
|
19
|
+
# +client.jobs.runs.*+ — read-only run history plus the cancel / rerun run
|
|
20
|
+
# actions.
|
|
21
|
+
class RunsClient
|
|
22
|
+
def initialize(api)
|
|
23
|
+
@api = api
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# List past runs, most recent first. Cursor paginated: pass +page_size+
|
|
27
|
+
# and the +after+ cursor from the prior page. Pass +job+ to scope to a
|
|
28
|
+
# single job's history.
|
|
29
|
+
#
|
|
30
|
+
# @param job [String, nil] Return only runs of the job with this id.
|
|
31
|
+
# +nil+ lists runs across all jobs in the account.
|
|
32
|
+
# @param page_size [Integer, nil] Maximum number of runs to return in this
|
|
33
|
+
# page. +nil+ uses the server default.
|
|
34
|
+
# @param after [String, nil] Opaque cursor from a previous page; returns
|
|
35
|
+
# the runs that follow it. +nil+ starts from the first page.
|
|
36
|
+
# @return [Array<Smplkit::Jobs::Run>] The runs in this page.
|
|
37
|
+
def list(job: nil, page_size: nil, after: nil)
|
|
38
|
+
opts = {}
|
|
39
|
+
opts[:filter_job] = job unless job.nil?
|
|
40
|
+
opts[:page_size] = page_size unless page_size.nil?
|
|
41
|
+
opts[:page_after] = after unless after.nil?
|
|
42
|
+
|
|
43
|
+
resp = Jobs.call_api { @api.list_runs(opts) }
|
|
44
|
+
(resp.data || []).map { |r| Run.from_resource(r) }
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Fetch a single run by its id.
|
|
48
|
+
#
|
|
49
|
+
# @param run_id [String] Identifier of the run to fetch.
|
|
50
|
+
# @return [Smplkit::Jobs::Run] The matching run.
|
|
51
|
+
# @raise [Smplkit::NotFoundError] when no run with this id exists.
|
|
52
|
+
def get(run_id)
|
|
53
|
+
resp = Jobs.call_api { @api.get_run(run_id) }
|
|
54
|
+
Run.from_resource(resp.data)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Cancel a run that has not finished yet.
|
|
58
|
+
#
|
|
59
|
+
# @param run_id [String] Identifier of the run to cancel.
|
|
60
|
+
# @return [Smplkit::Jobs::Run] The updated run reflecting the cancellation.
|
|
61
|
+
def cancel(run_id)
|
|
62
|
+
resp = Jobs.call_api { @api.cancel_run(run_id) }
|
|
63
|
+
Run.from_resource(resp.data)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Start a new run that repeats a previous one.
|
|
67
|
+
#
|
|
68
|
+
# @param run_id [String] Identifier of the run to repeat.
|
|
69
|
+
# @return [Smplkit::Jobs::Run] The new run, with +rerun_of+ set to the
|
|
70
|
+
# source +run_id+.
|
|
71
|
+
def rerun(run_id)
|
|
72
|
+
resp = Jobs.call_api { @api.rerun_run(run_id) }
|
|
73
|
+
Run.from_resource(resp.data)
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# The Smpl Jobs client — accessed via +client.jobs+.
|
|
78
|
+
#
|
|
79
|
+
# Unlike Config/Flags/Logging, Jobs has no live "phone-home" agent — no
|
|
80
|
+
# environment registration, no WebSocket — so its entire surface lives on
|
|
81
|
+
# one client. Defining a job, triggering a run, and reading run history are
|
|
82
|
+
# all plain request/response calls here:
|
|
83
|
+
#
|
|
84
|
+
# client.jobs.{new,get,list,delete,run,usage}
|
|
85
|
+
# client.jobs.runs.{list,get,cancel,rerun}
|
|
86
|
+
# Job#{save,delete}
|
|
87
|
+
#
|
|
88
|
+
# Build a standalone Smpl Jobs transport from resolved config.
|
|
89
|
+
#
|
|
90
|
+
# Reuses the config resolver (jobs is account-global and never
|
|
91
|
+
# environment-scoped) so a standalone jobs client resolves
|
|
92
|
+
# credentials/base-domain from +~/.smplkit+ / env vars / constructor args
|
|
93
|
+
# exactly like the top-level clients do. Smpl Jobs is JSON:API, so the
|
|
94
|
+
# transport carries the +application/vnd.api+json+ Accept header.
|
|
95
|
+
def self.jobs_transport(api_key:, profile:, base_domain:, scheme:, debug:, extra_headers:)
|
|
96
|
+
cfg = ConfigResolution.resolve_client_config(
|
|
97
|
+
profile: profile, api_key: api_key, base_domain: base_domain, scheme: scheme, debug: debug
|
|
98
|
+
)
|
|
99
|
+
merged = {}
|
|
100
|
+
merged.merge!(cfg.extra_headers || {})
|
|
101
|
+
merged.merge!(extra_headers || {})
|
|
102
|
+
tcfg = ConfigResolution::ResolvedClientConfig.new(
|
|
103
|
+
api_key: cfg.api_key, base_domain: cfg.base_domain, scheme: cfg.scheme,
|
|
104
|
+
debug: cfg.debug, extra_headers: merged
|
|
105
|
+
)
|
|
106
|
+
Transport.build_api_client(SmplkitGeneratedClient::Jobs, "jobs", tcfg, accept: "application/vnd.api+json")
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# The active-record entry point is {#new}: instantiate a draft, mutate
|
|
110
|
+
# fields, then call {Smplkit::Jobs::Job#save}. Run history and the cancel /
|
|
111
|
+
# rerun run actions live on {#runs}.
|
|
112
|
+
#
|
|
113
|
+
# Reachable as +client.jobs+ (+Smplkit::Client+) or constructed directly —
|
|
114
|
+
# +JobsClient.new+ resolves credentials from +~/.smplkit+ / env vars.
|
|
115
|
+
class JobsClient
|
|
116
|
+
# @return [RunsClient] Run history and run actions (+client.jobs.runs+).
|
|
117
|
+
attr_reader :runs
|
|
118
|
+
|
|
119
|
+
# @param api_key [String, nil] API key. When omitted, resolved from
|
|
120
|
+
# +SMPLKIT_API_KEY+ or +~/.smplkit+.
|
|
121
|
+
# @param profile [String, nil] Named +~/.smplkit+ profile section.
|
|
122
|
+
# @param base_domain [String, nil] Base domain for API requests
|
|
123
|
+
# (default +"smplkit.com"+).
|
|
124
|
+
# @param scheme [String, nil] URL scheme (default +"https"+).
|
|
125
|
+
# @param debug [Boolean, nil] Enable SDK debug logging.
|
|
126
|
+
# @param extra_headers [Hash, nil] Extra headers attached to every request.
|
|
127
|
+
# @param auth_client [Object, nil] Internal — a pre-built transport
|
|
128
|
+
# supplied by a top-level client so the jobs surface shares one
|
|
129
|
+
# connection pool. Not for direct use.
|
|
130
|
+
def initialize(api_key = nil, profile: nil, base_domain: nil, scheme: nil,
|
|
131
|
+
debug: nil, extra_headers: nil, auth_client: nil)
|
|
132
|
+
auth = auth_client || Jobs.jobs_transport(
|
|
133
|
+
api_key: api_key, profile: profile, base_domain: base_domain,
|
|
134
|
+
scheme: scheme, debug: debug, extra_headers: extra_headers
|
|
135
|
+
)
|
|
136
|
+
@api = SmplkitGeneratedClient::Jobs::JobsApi.new(auth)
|
|
137
|
+
@runs = RunsClient.new(SmplkitGeneratedClient::Jobs::RunsApi.new(auth))
|
|
138
|
+
@usage_api = SmplkitGeneratedClient::Jobs::UsageApi.new(auth)
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
# The generated ApiClient owns Faraday connections that release on GC;
|
|
142
|
+
# there is no explicit shutdown to call.
|
|
143
|
+
def close
|
|
144
|
+
nil
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
# Construct, yield to the block, and close on exit.
|
|
148
|
+
def self.open(*args, **kwargs)
|
|
149
|
+
client = new(*args, **kwargs)
|
|
150
|
+
begin
|
|
151
|
+
yield client
|
|
152
|
+
ensure
|
|
153
|
+
client.close
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
# Construct an unsaved {Smplkit::Jobs::Job} bound to this client. Call
|
|
158
|
+
# +#save+ on the returned instance to create it.
|
|
159
|
+
#
|
|
160
|
+
# @param id [String] Caller-supplied unique identifier for the job. Unique
|
|
161
|
+
# within the account and immutable; the service returns 409 if another
|
|
162
|
+
# live job already uses this id.
|
|
163
|
+
# @param name [String] Human-readable name for the job.
|
|
164
|
+
# @param schedule [String] An ISO-8601 datetime, a 5-field UTC cron
|
|
165
|
+
# expression, or the literal +"now"+.
|
|
166
|
+
# @param configuration [Smplkit::Jobs::HttpConfig] The HTTP request the
|
|
167
|
+
# job performs.
|
|
168
|
+
# @param description [String, nil] Optional free-text description.
|
|
169
|
+
# @param enabled [Boolean] Whether the job schedules runs. Defaults +true+.
|
|
170
|
+
# @param concurrency_policy [String] How overlapping runs are handled.
|
|
171
|
+
# Defaults to +"ALLOW"+.
|
|
172
|
+
# @return [Smplkit::Jobs::Job]
|
|
173
|
+
def new(id, name:, schedule:, configuration:, description: nil,
|
|
174
|
+
enabled: true, concurrency_policy: "ALLOW")
|
|
175
|
+
Job.new(
|
|
176
|
+
self,
|
|
177
|
+
id: id,
|
|
178
|
+
name: name,
|
|
179
|
+
schedule: schedule,
|
|
180
|
+
configuration: configuration,
|
|
181
|
+
description: description,
|
|
182
|
+
enabled: enabled,
|
|
183
|
+
concurrency_policy: concurrency_policy
|
|
184
|
+
)
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
# List jobs for the authenticated account.
|
|
188
|
+
#
|
|
189
|
+
# @param enabled [Boolean, nil] Filter to jobs matching this enabled state.
|
|
190
|
+
# @param page_number [Integer, nil] 1-based page number to return.
|
|
191
|
+
# @param page_size [Integer, nil] Items per page.
|
|
192
|
+
# @return [Array<Smplkit::Jobs::Job>]
|
|
193
|
+
def list(enabled: nil, page_number: nil, page_size: nil)
|
|
194
|
+
opts = {}
|
|
195
|
+
opts[:filter_enabled] = enabled unless enabled.nil?
|
|
196
|
+
opts[:page_number] = page_number unless page_number.nil?
|
|
197
|
+
opts[:page_size] = page_size unless page_size.nil?
|
|
198
|
+
|
|
199
|
+
resp = Jobs.call_api { @api.list_jobs(opts) }
|
|
200
|
+
(resp.data || []).map { |r| Job.from_resource(r, client: self) }
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
# Fetch a single job by id. The returned instance is bound to this client,
|
|
204
|
+
# so +job.save+ and +job.delete+ work.
|
|
205
|
+
#
|
|
206
|
+
# @param id [String]
|
|
207
|
+
# @return [Smplkit::Jobs::Job]
|
|
208
|
+
def get(id)
|
|
209
|
+
resp = Jobs.call_api { @api.get_job(id) }
|
|
210
|
+
Job.from_resource(resp.data, client: self)
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
# Delete a job by its id.
|
|
214
|
+
#
|
|
215
|
+
# @param id [String] Identifier of the job to delete.
|
|
216
|
+
# @return [nil]
|
|
217
|
+
def delete(id)
|
|
218
|
+
Jobs.call_api { @api.delete_job(id) }
|
|
219
|
+
nil
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
# Trigger one immediate, manual run of a job, ignoring its schedule.
|
|
223
|
+
#
|
|
224
|
+
# This starts an ad-hoc run right now in addition to any scheduled runs;
|
|
225
|
+
# it does not alter the job's schedule. To read or act on existing runs,
|
|
226
|
+
# use +client.jobs.runs+.
|
|
227
|
+
#
|
|
228
|
+
# @param id [String] Identifier of the job to run.
|
|
229
|
+
# @return [Smplkit::Jobs::Run] The run that was started, with +trigger+
|
|
230
|
+
# set to +MANUAL+.
|
|
231
|
+
def run(id)
|
|
232
|
+
resp = Jobs.call_api { @api.run_job_now(id) }
|
|
233
|
+
Run.from_resource(resp.data)
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
# Current-period usage counters for the account.
|
|
237
|
+
#
|
|
238
|
+
# @return [Smplkit::Jobs::Usage]
|
|
239
|
+
def usage
|
|
240
|
+
resp = Jobs.call_api { @usage_api.get_usage }
|
|
241
|
+
Usage.from_resource(resp.data)
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
# @api private — POST a new job. Called by {Smplkit::Jobs::Job#save} on
|
|
245
|
+
# unsaved instances. The jobs service requires a caller-supplied
|
|
246
|
+
# +data.id+ on create and 409s on conflict.
|
|
247
|
+
def _create_job(job)
|
|
248
|
+
raise ArgumentError, "Job.id is required on create (caller-supplied key)" if job.id.nil? || job.id.empty?
|
|
249
|
+
|
|
250
|
+
resp = Jobs.call_api { @api.create_job(build_create_body(job)) }
|
|
251
|
+
Job.from_resource(resp.data, client: self)
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
# @api private — Full-replace PUT for an existing job. Called by
|
|
255
|
+
# {Smplkit::Jobs::Job#save} on instances with +created_at+.
|
|
256
|
+
#
|
|
257
|
+
# Header values come back in plaintext on the GET path, so a fetched job
|
|
258
|
+
# round-trips through this full-replace PUT with its header values intact
|
|
259
|
+
# — no need to re-enter secrets.
|
|
260
|
+
def _update_job(job)
|
|
261
|
+
raise ArgumentError, "cannot update a Job with no id" if job.id.nil?
|
|
262
|
+
|
|
263
|
+
resp = Jobs.call_api { @api.update_job(job.id, build_body(job)) }
|
|
264
|
+
Job.from_resource(resp.data, client: self)
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
private
|
|
268
|
+
|
|
269
|
+
def build_attrs(job)
|
|
270
|
+
SmplkitGeneratedClient::Jobs::Job.new(
|
|
271
|
+
name: job.name,
|
|
272
|
+
description: job.description,
|
|
273
|
+
enabled: job.enabled,
|
|
274
|
+
type: job.type,
|
|
275
|
+
schedule: job.schedule,
|
|
276
|
+
configuration: HttpConfig.to_wire(job.configuration),
|
|
277
|
+
concurrency_policy: job.concurrency_policy
|
|
278
|
+
)
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
def build_create_body(job)
|
|
282
|
+
# Create uses the distinct JobCreateRequest envelope; the jobs service
|
|
283
|
+
# requires data.id (the caller-supplied key) on create and 409s on
|
|
284
|
+
# conflict.
|
|
285
|
+
resource = SmplkitGeneratedClient::Jobs::JobCreateResource.new(
|
|
286
|
+
id: job.id.to_s,
|
|
287
|
+
type: "job",
|
|
288
|
+
attributes: build_attrs(job)
|
|
289
|
+
)
|
|
290
|
+
SmplkitGeneratedClient::Jobs::JobCreateRequest.new(data: resource)
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
def build_body(job)
|
|
294
|
+
# Update path uses the generic JobRequest envelope.
|
|
295
|
+
resource = SmplkitGeneratedClient::Jobs::JobResource.new(
|
|
296
|
+
id: job.id.to_s,
|
|
297
|
+
type: "job",
|
|
298
|
+
attributes: build_attrs(job)
|
|
299
|
+
)
|
|
300
|
+
SmplkitGeneratedClient::Jobs::JobRequest.new(data: resource)
|
|
301
|
+
end
|
|
302
|
+
end
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
JobsClient = Jobs::JobsClient
|
|
306
|
+
end
|