smplkit 2.0.14 → 2.0.15
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/_generated/audit/lib/smplkit_audit_client/api/actions_api.rb +2 -69
- data/lib/smplkit/_generated/audit/lib/smplkit_audit_client/api/events_api.rb +17 -17
- data/lib/smplkit/_generated/audit/lib/smplkit_audit_client/api/forwarders_api.rb +36 -36
- data/lib/smplkit/_generated/audit/lib/smplkit_audit_client/api/functions_api.rb +2 -2
- data/lib/smplkit/_generated/audit/lib/smplkit_audit_client/api/resource_types_api.rb +2 -72
- data/lib/smplkit/_generated/audit/lib/smplkit_audit_client/api/usage_api.rb +4 -4
- data/lib/smplkit/_generated/audit/lib/smplkit_audit_client/models/event.rb +12 -2
- data/lib/smplkit/_generated/audit/lib/smplkit_audit_client/models/event_list_response.rb +1 -1
- data/lib/smplkit/_generated/audit/lib/smplkit_audit_client/models/event_request.rb +165 -0
- data/lib/smplkit/_generated/audit/lib/smplkit_audit_client/models/event_resource.rb +2 -18
- data/lib/smplkit/_generated/audit/lib/smplkit_audit_client/models/event_response.rb +1 -1
- data/lib/smplkit/_generated/audit/lib/smplkit_audit_client/models/forwarder.rb +17 -17
- data/lib/smplkit/_generated/audit/lib/smplkit_audit_client/models/forwarder_delivery.rb +11 -1
- data/lib/smplkit/_generated/audit/lib/smplkit_audit_client/models/forwarder_delivery_list_response.rb +1 -0
- data/lib/smplkit/_generated/audit/lib/smplkit_audit_client/models/forwarder_delivery_resource.rb +1 -0
- data/lib/smplkit/_generated/audit/lib/smplkit_audit_client/models/forwarder_delivery_response.rb +1 -0
- data/lib/smplkit/_generated/audit/lib/smplkit_audit_client/models/forwarder_http.rb +40 -1
- data/lib/smplkit/_generated/audit/lib/smplkit_audit_client/models/forwarder_list_response.rb +1 -0
- data/lib/smplkit/_generated/audit/lib/smplkit_audit_client/models/forwarder_request.rb +165 -0
- data/lib/smplkit/_generated/audit/lib/smplkit_audit_client/models/forwarder_resource.rb +2 -17
- data/lib/smplkit/_generated/audit/lib/smplkit_audit_client/models/forwarder_response.rb +1 -0
- data/lib/smplkit/_generated/audit/lib/smplkit_audit_client/models/http_header.rb +3 -1
- data/lib/smplkit/_generated/audit/lib/smplkit_audit_client/models/retry_failed_deliveries_summary.rb +4 -0
- data/lib/smplkit/_generated/audit/lib/smplkit_audit_client/models/test_forwarder_request.rb +41 -1
- data/lib/smplkit/_generated/audit/lib/smplkit_audit_client/models/test_forwarder_response.rb +7 -1
- data/lib/smplkit/_generated/audit/lib/smplkit_audit_client/models/usage_attributes.rb +4 -1
- data/lib/smplkit/_generated/audit/lib/smplkit_audit_client/models/wipe_response.rb +3 -0
- data/lib/smplkit/_generated/audit/lib/smplkit_audit_client/models/wipe_tables_summary.rb +7 -0
- data/lib/smplkit/_generated/audit/lib/smplkit_audit_client.rb +2 -0
- data/lib/smplkit/_generated/audit/spec/api/actions_api_spec.rb +1 -14
- data/lib/smplkit/_generated/audit/spec/api/events_api_spec.rb +5 -5
- data/lib/smplkit/_generated/audit/spec/api/forwarders_api_spec.rb +11 -11
- data/lib/smplkit/_generated/audit/spec/api/functions_api_spec.rb +1 -1
- data/lib/smplkit/_generated/audit/spec/api/resource_types_api_spec.rb +1 -15
- data/lib/smplkit/_generated/audit/spec/api/usage_api_spec.rb +2 -2
- data/lib/smplkit/_generated/audit/spec/models/event_request_spec.rb +36 -0
- data/lib/smplkit/_generated/audit/spec/models/forwarder_http_spec.rb +4 -0
- data/lib/smplkit/_generated/audit/spec/models/forwarder_request_spec.rb +36 -0
- data/lib/smplkit/_generated/audit/spec/models/forwarder_spec.rb +0 -6
- data/lib/smplkit/_generated/audit/spec/models/test_forwarder_request_spec.rb +4 -0
- data/lib/smplkit/audit/actions.rb +35 -0
- data/lib/smplkit/audit/client.rb +11 -9
- data/lib/smplkit/audit/events.rb +8 -45
- data/lib/smplkit/audit/models.rb +197 -0
- data/lib/smplkit/audit/resource_types.rb +30 -0
- data/lib/smplkit/errors.rb +5 -0
- data/lib/smplkit/management/audit.rb +111 -0
- data/lib/smplkit/management/client.rb +4 -1
- data/lib/smplkit.rb +7 -5
- metadata +9 -3
- data/lib/smplkit/audit/forwarders.rb +0 -282
- data/lib/smplkit/audit/functions.rb +0 -58
data/lib/smplkit/audit/client.rb
CHANGED
|
@@ -4,11 +4,15 @@ module Smplkit
|
|
|
4
4
|
module Audit
|
|
5
5
|
# Audit-product entry point — accessed via +client.audit+.
|
|
6
6
|
#
|
|
7
|
-
#
|
|
8
|
-
#
|
|
9
|
-
#
|
|
7
|
+
# Owns event recording and read-side queries: fire-and-forget
|
|
8
|
+
# +#events.record+, plus the audit-log +list+ / +get+ and the
|
|
9
|
+
# distinct-value listings that back the Activity tab filter
|
|
10
|
+
# dropdowns. ADR-047 §2.7.
|
|
11
|
+
#
|
|
12
|
+
# SIEM forwarder CRUD lives on {Smplkit::ManagementClient} under
|
|
13
|
+
# +mgmt.audit.forwarders.*+.
|
|
10
14
|
class AuditClient
|
|
11
|
-
attr_reader :events, :
|
|
15
|
+
attr_reader :events, :resource_types, :actions
|
|
12
16
|
|
|
13
17
|
SDK_OWNED_HEADERS = %w[authorization content-type user-agent].freeze
|
|
14
18
|
|
|
@@ -23,11 +27,9 @@ module Smplkit
|
|
|
23
27
|
extra_headers&.each do |k, v|
|
|
24
28
|
api_client.default_headers[k] = v unless SDK_OWNED_HEADERS.include?(k.downcase)
|
|
25
29
|
end
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
@
|
|
29
|
-
@forwarders = Forwarders.new(forwarders_api)
|
|
30
|
-
@functions = Functions.new(forwarders_api)
|
|
30
|
+
@events = Events.new(SmplkitGeneratedClient::Audit::EventsApi.new(api_client))
|
|
31
|
+
@resource_types = ResourceTypes.new(SmplkitGeneratedClient::Audit::ResourceTypesApi.new(api_client))
|
|
32
|
+
@actions = Actions.new(SmplkitGeneratedClient::Audit::ActionsApi.new(api_client))
|
|
31
33
|
end
|
|
32
34
|
|
|
33
35
|
def _close
|
data/lib/smplkit/audit/events.rb
CHANGED
|
@@ -4,9 +4,9 @@ module Smplkit
|
|
|
4
4
|
module Audit
|
|
5
5
|
# Audit events surface — accessed via +client.audit.events+.
|
|
6
6
|
#
|
|
7
|
-
# +#
|
|
7
|
+
# +#record+ is fire-and-forget per ADR-047 §2.6 — the call enqueues
|
|
8
8
|
# the event onto an in-memory bounded buffer and returns
|
|
9
|
-
# immediately. +#list+ and +#get+ are synchronous.
|
|
9
|
+
# immediately. +#list+ and +#get+ are synchronous reads.
|
|
10
10
|
class Events
|
|
11
11
|
def initialize(api)
|
|
12
12
|
@api = api
|
|
@@ -53,16 +53,16 @@ module Smplkit
|
|
|
53
53
|
type: "event",
|
|
54
54
|
attributes: attrs
|
|
55
55
|
)
|
|
56
|
-
body = SmplkitGeneratedClient::Audit::
|
|
56
|
+
body = SmplkitGeneratedClient::Audit::EventRequest.new(data: resource)
|
|
57
57
|
@buffer.enqueue(body, idempotency_key)
|
|
58
58
|
end
|
|
59
59
|
|
|
60
60
|
# Single-event retrieval.
|
|
61
61
|
#
|
|
62
|
-
# Raises
|
|
63
|
-
#
|
|
62
|
+
# Raises {Smplkit::NotFoundError} when no event with that id
|
|
63
|
+
# exists in the caller's account.
|
|
64
64
|
def get(event_id)
|
|
65
|
-
resp = @api.get_event(event_id)
|
|
65
|
+
resp = Smplkit::Audit.call_api { @api.get_event(event_id) }
|
|
66
66
|
AuditEvent.from_resource(resp.data)
|
|
67
67
|
end
|
|
68
68
|
|
|
@@ -88,19 +88,9 @@ module Smplkit
|
|
|
88
88
|
opts[:page_size] = page_size if page_size
|
|
89
89
|
opts[:page_after] = page_after if page_after
|
|
90
90
|
|
|
91
|
-
resp = @api.list_events(opts)
|
|
91
|
+
resp = Smplkit::Audit.call_api { @api.list_events(opts) }
|
|
92
92
|
events = (resp.data || []).map { |r| AuditEvent.from_resource(r) }
|
|
93
|
-
next_cursor
|
|
94
|
-
if resp.links&._next.is_a?(String)
|
|
95
|
-
next_link = resp.links._next
|
|
96
|
-
if (idx = next_link.index("page[after]="))
|
|
97
|
-
next_cursor = next_link[(idx + "page[after]=".length)..]
|
|
98
|
-
if (amp = next_cursor.index("&"))
|
|
99
|
-
next_cursor = next_cursor[0...amp]
|
|
100
|
-
end
|
|
101
|
-
end
|
|
102
|
-
end
|
|
103
|
-
ListEventsPage.new(events, next_cursor)
|
|
93
|
+
ListEventsPage.new(events, Smplkit::Audit.next_cursor(resp.links&._next))
|
|
104
94
|
end
|
|
105
95
|
|
|
106
96
|
# Block until the in-memory buffer is drained or the timeout elapses.
|
|
@@ -114,33 +104,6 @@ module Smplkit
|
|
|
114
104
|
end
|
|
115
105
|
end
|
|
116
106
|
|
|
117
|
-
# Public-facing audit event resource. ADR-047 §2.3.1.
|
|
118
|
-
AuditEvent = Struct.new(
|
|
119
|
-
:id, :action, :resource_type, :resource_id,
|
|
120
|
-
:occurred_at, :created_at,
|
|
121
|
-
:actor_type, :actor_id, :actor_label,
|
|
122
|
-
:data, :idempotency_key, :do_not_forward,
|
|
123
|
-
keyword_init: true
|
|
124
|
-
) do
|
|
125
|
-
def self.from_resource(resource)
|
|
126
|
-
attrs = resource.attributes
|
|
127
|
-
new(
|
|
128
|
-
id: resource.id,
|
|
129
|
-
action: attrs.action,
|
|
130
|
-
resource_type: attrs.resource_type,
|
|
131
|
-
resource_id: attrs.resource_id,
|
|
132
|
-
occurred_at: attrs.occurred_at,
|
|
133
|
-
created_at: attrs.created_at,
|
|
134
|
-
actor_type: attrs.actor_type,
|
|
135
|
-
actor_id: attrs.actor_id,
|
|
136
|
-
actor_label: attrs.actor_label,
|
|
137
|
-
data: Smplkit::Helpers.deep_stringify_keys(attrs.data || {}),
|
|
138
|
-
idempotency_key: attrs.idempotency_key,
|
|
139
|
-
do_not_forward: attrs.do_not_forward || false
|
|
140
|
-
)
|
|
141
|
-
end
|
|
142
|
-
end
|
|
143
|
-
|
|
144
107
|
# One page of events plus a cursor for the next page (nil on the last page).
|
|
145
108
|
ListEventsPage = Struct.new(:events, :next_cursor)
|
|
146
109
|
end
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Smplkit
|
|
4
|
+
module Audit
|
|
5
|
+
# Parse the +page[after]+ cursor out of a JSON:API +links.next+
|
|
6
|
+
# URL. Returns nil for non-string input or when the link carries
|
|
7
|
+
# no cursor parameter; trims trailing query params at the next
|
|
8
|
+
# ampersand so they don't leak into the token.
|
|
9
|
+
# Wrap a generated-audit-API call and translate +ApiError+ into the
|
|
10
|
+
# +Smplkit::Error+ hierarchy. Connection-level failures (no
|
|
11
|
+
# response code) become {Smplkit::ConnectionError}; status-coded
|
|
12
|
+
# failures route through {Smplkit::Errors.raise_for_status}, which
|
|
13
|
+
# emits +PaymentRequiredError+ / +NotFoundError+ / +ConflictError+
|
|
14
|
+
# / +ValidationError+ / +Error+ depending on the JSON:API body.
|
|
15
|
+
def self.call_api
|
|
16
|
+
yield
|
|
17
|
+
rescue SmplkitGeneratedClient::Audit::ApiError => e
|
|
18
|
+
raise Smplkit::ConnectionError, e.message.to_s if e.code.nil? || e.code.zero?
|
|
19
|
+
|
|
20
|
+
Smplkit::Errors.raise_for_status(e.code, e.response_body.to_s)
|
|
21
|
+
# raise_for_status only returns on 2xx; if we get here the
|
|
22
|
+
# generated layer raised on a 2xx (shouldn't happen) — re-raise
|
|
23
|
+
# the original so the caller can inspect.
|
|
24
|
+
raise
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def self.next_cursor(link)
|
|
28
|
+
return nil unless link.is_a?(String)
|
|
29
|
+
|
|
30
|
+
idx = link.index("page[after]=")
|
|
31
|
+
return nil if idx.nil?
|
|
32
|
+
|
|
33
|
+
token = link[(idx + "page[after]=".length)..]
|
|
34
|
+
amp = token.index("&")
|
|
35
|
+
amp ? token[0...amp] : token
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Public-facing enum for SIEM streaming destination types.
|
|
39
|
+
#
|
|
40
|
+
# Mirrors the +ForwarderType+ enum the audit OpenAPI spec emits
|
|
41
|
+
# (ADR-047 §2.12). Customers pass these constants — or any string
|
|
42
|
+
# in {VALUES} — to the management +forwarders+ surface. The wrapper
|
|
43
|
+
# validates membership before round-tripping to the wire.
|
|
44
|
+
module ForwarderType
|
|
45
|
+
HTTP = "HTTP"
|
|
46
|
+
DATADOG = "DATADOG"
|
|
47
|
+
SPLUNK_HEC = "SPLUNK_HEC"
|
|
48
|
+
SUMO_LOGIC = "SUMO_LOGIC"
|
|
49
|
+
NEW_RELIC = "NEW_RELIC"
|
|
50
|
+
HONEYCOMB = "HONEYCOMB"
|
|
51
|
+
ELASTIC = "ELASTIC"
|
|
52
|
+
|
|
53
|
+
VALUES = [HTTP, DATADOG, SPLUNK_HEC, SUMO_LOGIC, NEW_RELIC, HONEYCOMB, ELASTIC].freeze
|
|
54
|
+
|
|
55
|
+
def self.coerce(value)
|
|
56
|
+
return nil if value.nil?
|
|
57
|
+
|
|
58
|
+
s = value.to_s
|
|
59
|
+
return s if VALUES.include?(s)
|
|
60
|
+
|
|
61
|
+
raise ArgumentError,
|
|
62
|
+
"Unknown ForwarderType #{value.inspect}; expected one of #{VALUES.inspect}"
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Public-facing audit event resource. ADR-047 §2.3.1.
|
|
67
|
+
AuditEvent = Struct.new(
|
|
68
|
+
:id, :action, :resource_type, :resource_id,
|
|
69
|
+
:occurred_at, :created_at,
|
|
70
|
+
:actor_type, :actor_id, :actor_label,
|
|
71
|
+
:data, :idempotency_key, :do_not_forward,
|
|
72
|
+
keyword_init: true
|
|
73
|
+
) do
|
|
74
|
+
def self.from_resource(resource)
|
|
75
|
+
attrs = resource.attributes
|
|
76
|
+
new(
|
|
77
|
+
id: resource.id,
|
|
78
|
+
action: attrs.action,
|
|
79
|
+
resource_type: attrs.resource_type,
|
|
80
|
+
resource_id: attrs.resource_id,
|
|
81
|
+
occurred_at: attrs.occurred_at,
|
|
82
|
+
created_at: attrs.created_at,
|
|
83
|
+
actor_type: attrs.actor_type,
|
|
84
|
+
actor_id: attrs.actor_id,
|
|
85
|
+
actor_label: attrs.actor_label,
|
|
86
|
+
data: Smplkit::Helpers.deep_stringify_keys(attrs.data || {}),
|
|
87
|
+
idempotency_key: attrs.idempotency_key,
|
|
88
|
+
do_not_forward: attrs.do_not_forward || false
|
|
89
|
+
)
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# A distinct +resource_type+ slug seen for the account.
|
|
94
|
+
#
|
|
95
|
+
# The +id+ and +resource_type+ are the same value — JSON:API surfaces
|
|
96
|
+
# the customer-facing key as the resource id (ADR-014). The duplication
|
|
97
|
+
# keeps SDK consumers from having to dig into the id field when
|
|
98
|
+
# filtering UI controls; pick whichever name reads better in context.
|
|
99
|
+
ResourceType = Struct.new(:id, :resource_type, :created_at, keyword_init: true) do
|
|
100
|
+
def self.from_resource(resource)
|
|
101
|
+
attrs = resource.attributes
|
|
102
|
+
new(
|
|
103
|
+
id: resource.id,
|
|
104
|
+
resource_type: attrs.resource_type || resource.id,
|
|
105
|
+
created_at: attrs.created_at
|
|
106
|
+
)
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# A distinct +action+ slug seen for the account.
|
|
111
|
+
#
|
|
112
|
+
# Same shape as {ResourceType} — +id+ and +action+ are the same value.
|
|
113
|
+
# +created_at+ is the earliest sighting; when the parent list call
|
|
114
|
+
# filtered by +resource_type+, this is the first sighting of that
|
|
115
|
+
# specific (action, resource_type) triple, not the action overall.
|
|
116
|
+
Action = Struct.new(:id, :action, :created_at, keyword_init: true) do
|
|
117
|
+
def self.from_resource(resource)
|
|
118
|
+
attrs = resource.attributes
|
|
119
|
+
new(
|
|
120
|
+
id: resource.id,
|
|
121
|
+
action: attrs.action || resource.id,
|
|
122
|
+
created_at: attrs.created_at
|
|
123
|
+
)
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
HttpHeader = Struct.new(:name, :value, keyword_init: true)
|
|
128
|
+
|
|
129
|
+
# rubocop:disable Lint/StructNewOverride -- ``:method`` matches the
|
|
130
|
+
# API attribute and shadowing Struct#method is the expected ergonomics.
|
|
131
|
+
ForwarderHttp = Struct.new(:method, :url, :headers, :body, :success_status, keyword_init: true) do
|
|
132
|
+
def initialize(method: "POST", url: "", headers: nil, body: nil, success_status: "2xx")
|
|
133
|
+
super(method: method, url: url, headers: headers || [], body: body, success_status: success_status)
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def self.to_wire(src)
|
|
137
|
+
h = src.is_a?(Hash) ? new(**src) : src
|
|
138
|
+
SmplkitGeneratedClient::Audit::ForwarderHttp.new(
|
|
139
|
+
method: h.method,
|
|
140
|
+
url: h.url,
|
|
141
|
+
headers: (h.headers || []).map do |hdr|
|
|
142
|
+
name, value = if hdr.is_a?(Hash)
|
|
143
|
+
[hdr[:name] || hdr["name"],
|
|
144
|
+
hdr[:value] || hdr["value"]]
|
|
145
|
+
else
|
|
146
|
+
[hdr.name, hdr.value]
|
|
147
|
+
end
|
|
148
|
+
SmplkitGeneratedClient::Audit::HttpHeader.new(name: name, value: value)
|
|
149
|
+
end,
|
|
150
|
+
body: h.body,
|
|
151
|
+
success_status: h.success_status
|
|
152
|
+
)
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
def self.from_wire(src)
|
|
156
|
+
return new if src.nil?
|
|
157
|
+
|
|
158
|
+
new(
|
|
159
|
+
method: src.method || "POST",
|
|
160
|
+
url: src.url || "",
|
|
161
|
+
headers: (src.headers || []).map { |h| HttpHeader.new(name: h.name, value: h.value) },
|
|
162
|
+
body: src.body,
|
|
163
|
+
success_status: src.success_status || "2xx"
|
|
164
|
+
)
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
# rubocop:enable Lint/StructNewOverride
|
|
168
|
+
|
|
169
|
+
# rubocop:disable Lint/StructNewOverride -- ``:filter`` matches the
|
|
170
|
+
# API attribute and shadowing Struct#filter is the expected ergonomics.
|
|
171
|
+
Forwarder = Struct.new(
|
|
172
|
+
:id, :name, :slug, :forwarder_type, :enabled,
|
|
173
|
+
:filter, :transform, :http,
|
|
174
|
+
:created_at, :updated_at, :deleted_at, :version,
|
|
175
|
+
keyword_init: true
|
|
176
|
+
) do
|
|
177
|
+
def self.from_resource(resource)
|
|
178
|
+
a = resource.attributes
|
|
179
|
+
new(
|
|
180
|
+
id: resource.id,
|
|
181
|
+
name: a.name,
|
|
182
|
+
slug: a.slug,
|
|
183
|
+
forwarder_type: a.forwarder_type,
|
|
184
|
+
enabled: a.enabled.nil? || a.enabled,
|
|
185
|
+
filter: a.filter.nil? ? nil : Smplkit::Helpers.deep_stringify_keys(a.filter),
|
|
186
|
+
transform: a.transform,
|
|
187
|
+
http: ForwarderHttp.from_wire(a.http),
|
|
188
|
+
created_at: a.created_at,
|
|
189
|
+
updated_at: a.updated_at,
|
|
190
|
+
deleted_at: a.deleted_at,
|
|
191
|
+
version: a.version
|
|
192
|
+
)
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
# rubocop:enable Lint/StructNewOverride
|
|
196
|
+
end
|
|
197
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Smplkit
|
|
4
|
+
module Audit
|
|
5
|
+
# +client.audit.resource_types.list+ — distinct +resource_type+ slugs
|
|
6
|
+
# seen for the account.
|
|
7
|
+
#
|
|
8
|
+
# Backed by a maintain-by-write side table (ADR-047 §2.5), so the
|
|
9
|
+
# response time is independent of how many years of events the
|
|
10
|
+
# account has accumulated. Sorted alphabetically; cursor pagination
|
|
11
|
+
# via +page_after+.
|
|
12
|
+
class ResourceTypes
|
|
13
|
+
def initialize(api)
|
|
14
|
+
@api = api
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def list(page_size: nil, page_after: nil)
|
|
18
|
+
opts = {}
|
|
19
|
+
opts[:page_size] = page_size if page_size
|
|
20
|
+
opts[:page_after] = page_after if page_after
|
|
21
|
+
|
|
22
|
+
resp = Smplkit::Audit.call_api { @api.list_resource_types(opts) }
|
|
23
|
+
rows = (resp.data || []).map { |r| ResourceType.from_resource(r) }
|
|
24
|
+
ResourceTypeListPage.new(rows, Smplkit::Audit.next_cursor(resp.links&._next))
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
ResourceTypeListPage = Struct.new(:resource_types, :next_cursor)
|
|
29
|
+
end
|
|
30
|
+
end
|
data/lib/smplkit/errors.rb
CHANGED
|
@@ -70,6 +70,10 @@ module Smplkit
|
|
|
70
70
|
class ConflictError < Error; end
|
|
71
71
|
class ValidationError < Error; end
|
|
72
72
|
|
|
73
|
+
# Raised when the server rejects a request because the account's
|
|
74
|
+
# subscription plan does not include the required entitlement.
|
|
75
|
+
class PaymentRequiredError < Error; end
|
|
76
|
+
|
|
73
77
|
module Errors
|
|
74
78
|
module_function
|
|
75
79
|
|
|
@@ -102,6 +106,7 @@ module Smplkit
|
|
|
102
106
|
|
|
103
107
|
exc_cls =
|
|
104
108
|
case status_code
|
|
109
|
+
when 402 then PaymentRequiredError
|
|
105
110
|
when 404 then NotFoundError
|
|
106
111
|
when 409 then ConflictError
|
|
107
112
|
when 400, 422 then ValidationError
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Smplkit
|
|
4
|
+
module Management
|
|
5
|
+
# Audit management surface — accessed via +mgmt.audit.forwarders+.
|
|
6
|
+
#
|
|
7
|
+
# Counterpart to the runtime {Smplkit::Audit::AuditClient}. The
|
|
8
|
+
# runtime client owns event recording and read-side queries; this
|
|
9
|
+
# surface owns SIEM forwarder CRUD. ADR-047 §2.7.
|
|
10
|
+
class AuditNamespace
|
|
11
|
+
attr_reader :forwarders
|
|
12
|
+
|
|
13
|
+
def initialize(api_client)
|
|
14
|
+
@forwarders = ForwardersNamespace.new(
|
|
15
|
+
SmplkitGeneratedClient::Audit::ForwardersApi.new(api_client)
|
|
16
|
+
)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# +mgmt.audit.forwarders.*+ — manage the customer's configured SIEM
|
|
21
|
+
# forwarders.
|
|
22
|
+
class ForwardersNamespace
|
|
23
|
+
def initialize(api)
|
|
24
|
+
@api = api
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Create a forwarder.
|
|
28
|
+
#
|
|
29
|
+
# @param name [String] Display name. The slug is derived
|
|
30
|
+
# server-side.
|
|
31
|
+
# @param forwarder_type [String, Smplkit::Audit::ForwarderType]
|
|
32
|
+
# One of the published {Smplkit::Audit::ForwarderType} constants
|
|
33
|
+
# (or the equivalent string).
|
|
34
|
+
# @param http [Smplkit::Audit::ForwarderHttp, Hash] Destination
|
|
35
|
+
# configuration. Headers carry credentials and are encrypted at
|
|
36
|
+
# rest server-side; reads return them redacted.
|
|
37
|
+
# @param enabled [Boolean] Whether the forwarder is active.
|
|
38
|
+
# @param filter [Hash, nil] Optional JSON Logic filter; events
|
|
39
|
+
# that don't match are recorded as +filtered_out+ deliveries.
|
|
40
|
+
# @param transform [String, nil] Optional JSONata template
|
|
41
|
+
# applied to the event payload before POST. Nil/empty sends the
|
|
42
|
+
# event as-is.
|
|
43
|
+
def create(name:, forwarder_type:, http:, enabled: true,
|
|
44
|
+
filter: nil, transform: nil)
|
|
45
|
+
body = build_body(nil, name: name, forwarder_type: forwarder_type,
|
|
46
|
+
http: http, enabled: enabled,
|
|
47
|
+
filter: filter, transform: transform)
|
|
48
|
+
resp = Smplkit::Audit.call_api { @api.create_forwarder(body) }
|
|
49
|
+
Smplkit::Audit::Forwarder.from_resource(resp.data)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def list(forwarder_type: nil, enabled: nil, page_size: nil, page_after: nil)
|
|
53
|
+
opts = {}
|
|
54
|
+
opts[:filter_forwarder_type] = Smplkit::Audit::ForwarderType.coerce(forwarder_type) if forwarder_type
|
|
55
|
+
opts[:filter_enabled] = enabled unless enabled.nil?
|
|
56
|
+
opts[:page_size] = page_size if page_size
|
|
57
|
+
opts[:page_after] = page_after if page_after
|
|
58
|
+
|
|
59
|
+
resp = Smplkit::Audit.call_api { @api.list_forwarders(opts) }
|
|
60
|
+
forwarders = (resp.data || []).map { |r| Smplkit::Audit::Forwarder.from_resource(r) }
|
|
61
|
+
ForwarderListPage.new(forwarders, Smplkit::Audit.next_cursor(resp.links&._next))
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def get(forwarder_id)
|
|
65
|
+
resp = Smplkit::Audit.call_api { @api.get_forwarder(forwarder_id) }
|
|
66
|
+
Smplkit::Audit::Forwarder.from_resource(resp.data)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Full-replace update. PUT semantics — every field is overwritten.
|
|
70
|
+
#
|
|
71
|
+
# Header values must be re-supplied as plaintext; the GET path
|
|
72
|
+
# redacts them, so a PUT body containing +"<redacted>"+ would
|
|
73
|
+
# persist that literal. Track real header values client-side and
|
|
74
|
+
# round-trip them on update.
|
|
75
|
+
def update(forwarder_id, name:, forwarder_type:, http:, enabled: true,
|
|
76
|
+
filter: nil, transform: nil)
|
|
77
|
+
body = build_body(forwarder_id, name: name, forwarder_type: forwarder_type,
|
|
78
|
+
http: http, enabled: enabled,
|
|
79
|
+
filter: filter, transform: transform)
|
|
80
|
+
resp = Smplkit::Audit.call_api { @api.update_forwarder(forwarder_id, body) }
|
|
81
|
+
Smplkit::Audit::Forwarder.from_resource(resp.data)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def delete(forwarder_id)
|
|
85
|
+
Smplkit::Audit.call_api { @api.delete_forwarder(forwarder_id) }
|
|
86
|
+
nil
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
private
|
|
90
|
+
|
|
91
|
+
def build_body(id, name:, forwarder_type:, http:, enabled:, filter:, transform:)
|
|
92
|
+
attrs = SmplkitGeneratedClient::Audit::Forwarder.new(
|
|
93
|
+
name: name,
|
|
94
|
+
forwarder_type: Smplkit::Audit::ForwarderType.coerce(forwarder_type),
|
|
95
|
+
enabled: enabled,
|
|
96
|
+
http: Smplkit::Audit::ForwarderHttp.to_wire(http),
|
|
97
|
+
filter: filter,
|
|
98
|
+
transform: transform
|
|
99
|
+
)
|
|
100
|
+
resource = SmplkitGeneratedClient::Audit::ForwarderResource.new(
|
|
101
|
+
id: id ? id.to_s : "",
|
|
102
|
+
type: "forwarder",
|
|
103
|
+
attributes: attrs
|
|
104
|
+
)
|
|
105
|
+
SmplkitGeneratedClient::Audit::ForwarderRequest.new(data: resource)
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
ForwarderListPage = Struct.new(:forwarders, :next_cursor)
|
|
110
|
+
end
|
|
111
|
+
end
|
|
@@ -28,7 +28,7 @@ module Smplkit
|
|
|
28
28
|
# +<resource>_from_resource+ helpers.
|
|
29
29
|
class ManagementClient
|
|
30
30
|
attr_reader :contexts, :context_types, :environments, :account_settings,
|
|
31
|
-
:config, :flags, :loggers, :log_groups
|
|
31
|
+
:config, :flags, :loggers, :log_groups, :audit
|
|
32
32
|
|
|
33
33
|
def self.from_resolved(resolved, extra_headers: nil)
|
|
34
34
|
new(_resolved: resolved, extra_headers: extra_headers)
|
|
@@ -50,6 +50,7 @@ module Smplkit
|
|
|
50
50
|
@config_api_client = build_api_client(SmplkitGeneratedClient::Config, "config", cfg)
|
|
51
51
|
@flags_api_client = build_api_client(SmplkitGeneratedClient::Flags, "flags", cfg)
|
|
52
52
|
@logging_api_client = build_api_client(SmplkitGeneratedClient::Logging, "logging", cfg)
|
|
53
|
+
@audit_api_client = build_api_client(SmplkitGeneratedClient::Audit, "audit", cfg)
|
|
53
54
|
|
|
54
55
|
@contexts = ContextsNamespace.new(@app_api_client)
|
|
55
56
|
@context_types = ContextTypesNamespace.new(@app_api_client)
|
|
@@ -59,6 +60,7 @@ module Smplkit
|
|
|
59
60
|
@flags = FlagsNamespace.new(@flags_api_client)
|
|
60
61
|
@loggers = LoggersNamespace.new(@logging_api_client)
|
|
61
62
|
@log_groups = LogGroupsNamespace.new(@logging_api_client)
|
|
63
|
+
@audit = Management::AuditNamespace.new(@audit_api_client)
|
|
62
64
|
end
|
|
63
65
|
|
|
64
66
|
def close
|
|
@@ -71,6 +73,7 @@ module Smplkit
|
|
|
71
73
|
def _config_http = @config_api_client
|
|
72
74
|
def _flags_http = @flags_api_client
|
|
73
75
|
def _logging_http = @logging_api_client
|
|
76
|
+
def _audit_http = @audit_api_client
|
|
74
77
|
|
|
75
78
|
SDK_OWNED_HEADERS = %w[authorization content-type user-agent].freeze
|
|
76
79
|
|
data/lib/smplkit.rb
CHANGED
|
@@ -58,15 +58,17 @@ require_relative "smplkit/logging/helpers"
|
|
|
58
58
|
require_relative "smplkit/logging/adapters/base"
|
|
59
59
|
require_relative "smplkit/logging/adapters/stdlib_logger_adapter"
|
|
60
60
|
require_relative "smplkit/logging/client"
|
|
61
|
+
require_relative "smplkit/audit/models"
|
|
62
|
+
require_relative "smplkit/audit/buffer"
|
|
63
|
+
require_relative "smplkit/audit/events"
|
|
64
|
+
require_relative "smplkit/audit/resource_types"
|
|
65
|
+
require_relative "smplkit/audit/actions"
|
|
66
|
+
require_relative "smplkit/audit/client"
|
|
61
67
|
require_relative "smplkit/management/types"
|
|
62
68
|
require_relative "smplkit/management/models"
|
|
63
69
|
require_relative "smplkit/management/buffer"
|
|
70
|
+
require_relative "smplkit/management/audit"
|
|
64
71
|
require_relative "smplkit/management/client"
|
|
65
|
-
require_relative "smplkit/audit/buffer"
|
|
66
|
-
require_relative "smplkit/audit/events"
|
|
67
|
-
require_relative "smplkit/audit/forwarders"
|
|
68
|
-
require_relative "smplkit/audit/functions"
|
|
69
|
-
require_relative "smplkit/audit/client"
|
|
70
72
|
require_relative "smplkit/client"
|
|
71
73
|
|
|
72
74
|
require_relative "smplkit/railtie" if defined?(Rails::Railtie)
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: smplkit
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.0.
|
|
4
|
+
version: 2.0.15
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Smpl Solutions LLC
|
|
@@ -410,6 +410,7 @@ files:
|
|
|
410
410
|
- lib/smplkit/_generated/audit/lib/smplkit_audit_client/models/event_list_links.rb
|
|
411
411
|
- lib/smplkit/_generated/audit/lib/smplkit_audit_client/models/event_list_meta.rb
|
|
412
412
|
- lib/smplkit/_generated/audit/lib/smplkit_audit_client/models/event_list_response.rb
|
|
413
|
+
- lib/smplkit/_generated/audit/lib/smplkit_audit_client/models/event_request.rb
|
|
413
414
|
- lib/smplkit/_generated/audit/lib/smplkit_audit_client/models/event_resource.rb
|
|
414
415
|
- lib/smplkit/_generated/audit/lib/smplkit_audit_client/models/event_response.rb
|
|
415
416
|
- lib/smplkit/_generated/audit/lib/smplkit_audit_client/models/forwarder.rb
|
|
@@ -421,6 +422,7 @@ files:
|
|
|
421
422
|
- lib/smplkit/_generated/audit/lib/smplkit_audit_client/models/forwarder_list_links.rb
|
|
422
423
|
- lib/smplkit/_generated/audit/lib/smplkit_audit_client/models/forwarder_list_meta.rb
|
|
423
424
|
- lib/smplkit/_generated/audit/lib/smplkit_audit_client/models/forwarder_list_response.rb
|
|
425
|
+
- lib/smplkit/_generated/audit/lib/smplkit_audit_client/models/forwarder_request.rb
|
|
424
426
|
- lib/smplkit/_generated/audit/lib/smplkit_audit_client/models/forwarder_resource.rb
|
|
425
427
|
- lib/smplkit/_generated/audit/lib/smplkit_audit_client/models/forwarder_response.rb
|
|
426
428
|
- lib/smplkit/_generated/audit/lib/smplkit_audit_client/models/forwarder_type.rb
|
|
@@ -453,6 +455,7 @@ files:
|
|
|
453
455
|
- lib/smplkit/_generated/audit/spec/models/event_list_links_spec.rb
|
|
454
456
|
- lib/smplkit/_generated/audit/spec/models/event_list_meta_spec.rb
|
|
455
457
|
- lib/smplkit/_generated/audit/spec/models/event_list_response_spec.rb
|
|
458
|
+
- lib/smplkit/_generated/audit/spec/models/event_request_spec.rb
|
|
456
459
|
- lib/smplkit/_generated/audit/spec/models/event_resource_spec.rb
|
|
457
460
|
- lib/smplkit/_generated/audit/spec/models/event_response_spec.rb
|
|
458
461
|
- lib/smplkit/_generated/audit/spec/models/event_spec.rb
|
|
@@ -464,6 +467,7 @@ files:
|
|
|
464
467
|
- lib/smplkit/_generated/audit/spec/models/forwarder_list_links_spec.rb
|
|
465
468
|
- lib/smplkit/_generated/audit/spec/models/forwarder_list_meta_spec.rb
|
|
466
469
|
- lib/smplkit/_generated/audit/spec/models/forwarder_list_response_spec.rb
|
|
470
|
+
- lib/smplkit/_generated/audit/spec/models/forwarder_request_spec.rb
|
|
467
471
|
- lib/smplkit/_generated/audit/spec/models/forwarder_resource_spec.rb
|
|
468
472
|
- lib/smplkit/_generated/audit/spec/models/forwarder_response_spec.rb
|
|
469
473
|
- lib/smplkit/_generated/audit/spec/models/forwarder_spec.rb
|
|
@@ -638,11 +642,12 @@ files:
|
|
|
638
642
|
- lib/smplkit/_generated/logging/spec/models/usage_list_response_spec.rb
|
|
639
643
|
- lib/smplkit/_generated/logging/spec/models/usage_resource_spec.rb
|
|
640
644
|
- lib/smplkit/_generated/logging/spec/spec_helper.rb
|
|
645
|
+
- lib/smplkit/audit/actions.rb
|
|
641
646
|
- lib/smplkit/audit/buffer.rb
|
|
642
647
|
- lib/smplkit/audit/client.rb
|
|
643
648
|
- lib/smplkit/audit/events.rb
|
|
644
|
-
- lib/smplkit/audit/
|
|
645
|
-
- lib/smplkit/audit/
|
|
649
|
+
- lib/smplkit/audit/models.rb
|
|
650
|
+
- lib/smplkit/audit/resource_types.rb
|
|
646
651
|
- lib/smplkit/client.rb
|
|
647
652
|
- lib/smplkit/config/client.rb
|
|
648
653
|
- lib/smplkit/config/helpers.rb
|
|
@@ -667,6 +672,7 @@ files:
|
|
|
667
672
|
- lib/smplkit/logging/models.rb
|
|
668
673
|
- lib/smplkit/logging/normalize.rb
|
|
669
674
|
- lib/smplkit/logging/sources.rb
|
|
675
|
+
- lib/smplkit/management/audit.rb
|
|
670
676
|
- lib/smplkit/management/buffer.rb
|
|
671
677
|
- lib/smplkit/management/client.rb
|
|
672
678
|
- lib/smplkit/management/models.rb
|