kessel-sdk 1.8.0 → 1.9.0
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/README.md +189 -81
- data/lib/kessel/console.rb +71 -0
- data/lib/kessel/inventory/v1beta2/inventory_service_pb.rb +3 -1
- data/lib/kessel/inventory/v1beta2/inventory_service_services_pb.rb +11 -0
- data/lib/kessel/inventory/v1beta2/streamed_list_subjects_request_pb.rb +25 -0
- data/lib/kessel/inventory/v1beta2/streamed_list_subjects_response_pb.rb +23 -0
- data/lib/kessel/version.rb +1 -1
- metadata +4 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9408aacf7604105abff5b811ad6548270be6d0c63f6193602fecd703ea79d522
|
|
4
|
+
data.tar.gz: 0237cd7effe27b00ff1ac07b1e8a2121f0275a2cbd48e215ae0a24ad511e8fb3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6a6ee646283375fcb8f535f14475639e1d9b687212de54c06795eab2de4b07abc310a74c0ba9ed5d660efbcf8a039929f3cf6379ebaae18f8859434324fdd565
|
|
7
|
+
data.tar.gz: 6a92e7bb7b73d215fade25f2e818ecfad57638d5f84858c742fd4914294ac90132205cd9e252cb8906729927508fe73ba662e0fe93ee9e6528629be421137448
|
data/README.md
CHANGED
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://github.com/project-kessel/kessel-sdk-ruby/actions/workflows/ci.yml)
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
The official Ruby gRPC client SDK for [Project Kessel](https://github.com/project-kessel) services. It provides generated protobuf/gRPC bindings for the Kessel Inventory API, a fluent client builder with credential validation, OAuth 2.0 Client Credentials authentication (via OIDC), and RBAC convenience helpers for workspace operations.
|
|
6
|
+
|
|
7
|
+
Published on RubyGems as [`kessel-sdk`](https://rubygems.org/gems/kessel-sdk).
|
|
6
8
|
|
|
7
9
|
## Installation
|
|
8
10
|
|
|
@@ -24,7 +26,7 @@ Or install it yourself as:
|
|
|
24
26
|
gem install kessel-sdk
|
|
25
27
|
```
|
|
26
28
|
|
|
27
|
-
|
|
29
|
+
### Authentication (Optional)
|
|
28
30
|
|
|
29
31
|
The SDK supports OAuth 2.0 Client Credentials flow. To use authentication features, add the OpenID Connect gem:
|
|
30
32
|
|
|
@@ -33,21 +35,103 @@ gem 'kessel-sdk'
|
|
|
33
35
|
gem 'openid_connect', '~> 2.0' # Optional - only for authentication
|
|
34
36
|
```
|
|
35
37
|
|
|
38
|
+
The `openid_connect` gem is intentionally not a hard runtime dependency. Consumers who do not need OAuth are not forced to install it or its transitive dependencies.
|
|
39
|
+
|
|
40
|
+
## Project Structure
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
lib/
|
|
44
|
+
kessel-sdk.rb # Single entrypoint (require 'kessel-sdk')
|
|
45
|
+
kessel/
|
|
46
|
+
auth.rb # OAuth2 Client Credentials, OIDC discovery
|
|
47
|
+
grpc.rb # gRPC credential helpers
|
|
48
|
+
inventory.rb # ClientBuilder base class, client_builder_for_stub
|
|
49
|
+
version.rb # Kessel::Inventory::VERSION
|
|
50
|
+
inventory/
|
|
51
|
+
v1/ # Health check service (stable)
|
|
52
|
+
v1beta1/ # Legacy typed K8s resources/relationships
|
|
53
|
+
v1beta2/ # Current unified inventory service (primary API)
|
|
54
|
+
rbac/
|
|
55
|
+
v2.rb # Workspace fetch, list_workspaces enumerator
|
|
56
|
+
v2_helpers.rb # Factory methods for protobuf references
|
|
57
|
+
v2_http.rb # HTTP request helpers for RBAC API
|
|
58
|
+
sig/ # RBS type signatures for hand-written code
|
|
59
|
+
spec/ # RSpec test suite
|
|
60
|
+
examples/ # Working examples with dotenv configuration
|
|
61
|
+
docs/ # Domain-specific guidelines (see Documentation below)
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Files under `lib/kessel/inventory/v*/`, `lib/google/`, and `lib/buf/` are **generated** by `buf generate` and must never be hand-edited. They are automatically regenerated every 6 hours via CI.
|
|
65
|
+
|
|
36
66
|
## Usage
|
|
37
67
|
|
|
38
|
-
|
|
68
|
+
Load the complete SDK via the single entrypoint:
|
|
39
69
|
|
|
40
|
-
|
|
70
|
+
```ruby
|
|
71
|
+
require 'kessel-sdk'
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Building a Client
|
|
75
|
+
|
|
76
|
+
The recommended way to create gRPC clients is with the **`ClientBuilder` fluent API**, which enforces credential validation at configuration time. Every gRPC service module exposes a `ClientBuilder` constant.
|
|
77
|
+
|
|
78
|
+
#### Insecure (Development Only)
|
|
41
79
|
|
|
42
80
|
```ruby
|
|
43
|
-
|
|
81
|
+
include Kessel::Inventory::V1beta2
|
|
44
82
|
|
|
83
|
+
client = KesselInventoryService::ClientBuilder.new('localhost:9000')
|
|
84
|
+
.insecure
|
|
85
|
+
.build
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
#### OAuth2 Client Credentials (Production)
|
|
89
|
+
|
|
90
|
+
```ruby
|
|
45
91
|
include Kessel::Inventory::V1beta2
|
|
92
|
+
include Kessel::Auth
|
|
93
|
+
|
|
94
|
+
# Discover the token endpoint via OIDC
|
|
95
|
+
discovery = fetch_oidc_discovery('https://sso.example.com/auth/realms/my-realm')
|
|
96
|
+
|
|
97
|
+
# Create OAuth2 credentials
|
|
98
|
+
oauth = OAuth2ClientCredentials.new(
|
|
99
|
+
client_id: 'my-app',
|
|
100
|
+
client_secret: 'my-secret',
|
|
101
|
+
token_endpoint: discovery.token_endpoint
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
# Build the client -- tokens are cached and refreshed automatically
|
|
105
|
+
client = KesselInventoryService::ClientBuilder.new('kessel.example.com:443')
|
|
106
|
+
.oauth2_client_authenticated(oauth2_client_credentials: oauth)
|
|
107
|
+
.build
|
|
108
|
+
```
|
|
46
109
|
|
|
47
|
-
|
|
48
|
-
|
|
110
|
+
#### Custom or No Credentials
|
|
111
|
+
|
|
112
|
+
```ruby
|
|
113
|
+
# Custom call/channel credentials
|
|
114
|
+
client = KesselInventoryService::ClientBuilder.new(target)
|
|
115
|
+
.authenticated(call_credentials: creds, channel_credentials: ch_creds)
|
|
116
|
+
.build
|
|
117
|
+
|
|
118
|
+
# No call credentials (TLS channel only)
|
|
119
|
+
client = KesselInventoryService::ClientBuilder.new(target)
|
|
120
|
+
.unauthenticated
|
|
121
|
+
.build
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Build the client **once at application startup and reuse it**. The underlying gRPC channel manages its own HTTP/2 connection pool.
|
|
125
|
+
|
|
126
|
+
### Check Permissions
|
|
127
|
+
|
|
128
|
+
```ruby
|
|
129
|
+
include Kessel::Inventory::V1beta2
|
|
130
|
+
|
|
131
|
+
client = KesselInventoryService::ClientBuilder.new('localhost:9000')
|
|
132
|
+
.insecure
|
|
133
|
+
.build
|
|
49
134
|
|
|
50
|
-
# Create subject reference
|
|
51
135
|
subject_reference = SubjectReference.new(
|
|
52
136
|
resource: ResourceReference.new(
|
|
53
137
|
reporter: ReporterReference.new(type: 'rbac'),
|
|
@@ -56,14 +140,12 @@ subject_reference = SubjectReference.new(
|
|
|
56
140
|
)
|
|
57
141
|
)
|
|
58
142
|
|
|
59
|
-
# Create resource reference
|
|
60
143
|
resource = ResourceReference.new(
|
|
61
144
|
reporter: ReporterReference.new(type: 'rbac'),
|
|
62
145
|
resource_id: 'workspace456',
|
|
63
146
|
resource_type: 'workspace'
|
|
64
147
|
)
|
|
65
148
|
|
|
66
|
-
# Check permissions
|
|
67
149
|
begin
|
|
68
150
|
response = client.check(
|
|
69
151
|
CheckRequest.new(
|
|
@@ -73,80 +155,95 @@ begin
|
|
|
73
155
|
)
|
|
74
156
|
)
|
|
75
157
|
puts "Permission check result: #{response.allowed}"
|
|
76
|
-
rescue => e
|
|
77
|
-
puts "
|
|
158
|
+
rescue GRPC::BadStatus => e
|
|
159
|
+
puts "gRPC error: #{e.message}"
|
|
78
160
|
end
|
|
79
161
|
```
|
|
80
162
|
|
|
81
|
-
###
|
|
163
|
+
### Bulk Permission Checks
|
|
82
164
|
|
|
83
165
|
```ruby
|
|
84
|
-
require 'kessel/inventory/v1beta2/inventory_service_services_pb'
|
|
85
|
-
|
|
86
166
|
include Kessel::Inventory::V1beta2
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
workspace: 'default'
|
|
107
|
-
)
|
|
108
|
-
},
|
|
109
|
-
k8s_manifest: resource_data.to_json
|
|
110
|
-
)
|
|
167
|
+
include Kessel::RBAC::V2
|
|
168
|
+
|
|
169
|
+
client = KesselInventoryService::ClientBuilder.new('localhost:9000')
|
|
170
|
+
.insecure
|
|
171
|
+
.build
|
|
172
|
+
|
|
173
|
+
response = client.check_bulk(
|
|
174
|
+
CheckBulkRequest.new(items: [
|
|
175
|
+
CheckBulkRequestItem.new(
|
|
176
|
+
object: workspace_resource('workspace_123'),
|
|
177
|
+
relation: 'view_widget',
|
|
178
|
+
subject: principal_subject('bob', 'redhat')
|
|
179
|
+
),
|
|
180
|
+
CheckBulkRequestItem.new(
|
|
181
|
+
object: workspace_resource('workspace_456'),
|
|
182
|
+
relation: 'use_widget',
|
|
183
|
+
subject: principal_subject('alice', 'redhat')
|
|
184
|
+
)
|
|
185
|
+
])
|
|
111
186
|
)
|
|
112
187
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
188
|
+
response.pairs.each do |pair|
|
|
189
|
+
if pair.item
|
|
190
|
+
puts "Allowed: #{pair.item.allowed}"
|
|
191
|
+
elsif pair.error
|
|
192
|
+
puts "Error: #{pair.error.message}"
|
|
193
|
+
end
|
|
118
194
|
end
|
|
119
195
|
```
|
|
120
196
|
|
|
121
|
-
###
|
|
197
|
+
### List Workspaces (Streaming with Auto-Pagination)
|
|
198
|
+
|
|
199
|
+
```ruby
|
|
200
|
+
include Kessel::Inventory::V1beta2
|
|
201
|
+
include Kessel::RBAC::V2
|
|
202
|
+
|
|
203
|
+
client = KesselInventoryService::ClientBuilder.new('localhost:9000')
|
|
204
|
+
.insecure
|
|
205
|
+
.build
|
|
206
|
+
|
|
207
|
+
list_workspaces(client, principal_subject('alice', 'redhat'), 'view_document').each do |response|
|
|
208
|
+
puts response
|
|
209
|
+
end
|
|
210
|
+
```
|
|
122
211
|
|
|
123
|
-
|
|
212
|
+
### Available Services (V1beta2)
|
|
124
213
|
|
|
125
|
-
|
|
126
|
-
- `check(CheckRequest)` - Check permissions
|
|
127
|
-
- `check_for_update(CheckForUpdateRequest)` - Check for resource updates
|
|
128
|
-
- `report_resource(ReportResourceRequest)` - Report resource state
|
|
129
|
-
- `delete_resource(DeleteResourceRequest)` - Delete a resource
|
|
130
|
-
- `streamed_list_objects(StreamedListObjectsRequest)` - Stream resource listings
|
|
214
|
+
The primary service is **`KesselInventoryService`** with these RPCs:
|
|
131
215
|
|
|
132
|
-
|
|
216
|
+
| RPC | Description |
|
|
217
|
+
|-----|-------------|
|
|
218
|
+
| `check` | Check if a subject has a relation on a resource |
|
|
219
|
+
| `check_self` | Check using the caller's identity from auth context |
|
|
220
|
+
| `check_for_update` | Strongly consistent check (use before writes) |
|
|
221
|
+
| `check_bulk` | Batch permission checks (up to 1000 items) |
|
|
222
|
+
| `check_self_bulk` | Batch self-checks |
|
|
223
|
+
| `check_for_update_bulk` | Batch strongly consistent checks |
|
|
224
|
+
| `report_resource` | Report resource state to inventory |
|
|
225
|
+
| `delete_resource` | Delete a resource from inventory |
|
|
226
|
+
| `streamed_list_objects` | Stream objects a subject has a relation to |
|
|
227
|
+
| `streamed_list_subjects` | Stream subjects that have a relation to a resource |
|
|
133
228
|
|
|
134
|
-
|
|
229
|
+
### RBAC Helper Methods
|
|
135
230
|
|
|
136
|
-
|
|
137
|
-
- `ReportResourceRequest`, `ReportResourceResponse`
|
|
138
|
-
- `DeleteResourceRequest`, `DeleteResourceResponse`
|
|
139
|
-
- `ResourceReference`, `SubjectReference`
|
|
140
|
-
- `ResourceRepresentations`, `RepresentationMetadata`
|
|
231
|
+
The `Kessel::RBAC::V2` module provides factory methods for common protobuf references (all use `reporter_type: 'rbac'`):
|
|
141
232
|
|
|
142
|
-
|
|
233
|
+
- `workspace_resource(id)` / `role_resource(id)` -- `ResourceReference` factories
|
|
234
|
+
- `principal_resource(id, domain)` -- `ResourceReference` with ID formatted as `"domain/id"`
|
|
235
|
+
- `principal_subject(id, domain)` -- `SubjectReference` wrapping a principal resource
|
|
236
|
+
- `subject(resource_ref, relation)` -- generic `SubjectReference` factory
|
|
237
|
+
- `fetch_default_workspace(endpoint, org_id, auth:, http_client:)` -- fetch default workspace via RBAC HTTP API
|
|
238
|
+
- `fetch_root_workspace(endpoint, org_id, auth:, http_client:)` -- fetch root workspace via RBAC HTTP API
|
|
239
|
+
- `list_workspaces(inventory, subject, relation)` -- lazy `Enumerator` with auto-pagination
|
|
143
240
|
|
|
144
241
|
## Type Safety
|
|
145
242
|
|
|
146
243
|
This library includes RBS type signatures for enhanced type safety in Ruby. The type definitions are located in the `sig/` directory and cover:
|
|
147
244
|
|
|
148
245
|
- Core library interfaces
|
|
149
|
-
- Configuration structures
|
|
246
|
+
- Configuration structures
|
|
150
247
|
- OAuth authentication classes
|
|
151
248
|
- gRPC client builders
|
|
152
249
|
|
|
@@ -156,7 +253,7 @@ To use with type checkers like Steep or Sorbet, ensure the `sig/` directory is i
|
|
|
156
253
|
|
|
157
254
|
### Prerequisites
|
|
158
255
|
|
|
159
|
-
- Ruby 3.3 or higher
|
|
256
|
+
- Ruby 3.3 or higher
|
|
160
257
|
- [buf](https://buf.build) for protobuf/gRPC code generation
|
|
161
258
|
|
|
162
259
|
Install buf:
|
|
@@ -219,34 +316,43 @@ rake install_local
|
|
|
219
316
|
|
|
220
317
|
## Examples
|
|
221
318
|
|
|
222
|
-
The `examples/` directory contains working examples
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
319
|
+
The `examples/` directory contains working examples. Set up environment variables in `examples/.env` before running.
|
|
320
|
+
|
|
321
|
+
| Example | Description |
|
|
322
|
+
|---------|-------------|
|
|
323
|
+
| `auth.rb` | OAuth 2.0 authentication with ClientBuilder |
|
|
324
|
+
| `check.rb` | Permission checking |
|
|
325
|
+
| `check_bulk.rb` | Bulk permission checks |
|
|
326
|
+
| `check_for_update.rb` | Strongly consistent update checks |
|
|
327
|
+
| `check_for_update_bulk.rb` | Bulk strongly consistent update checks |
|
|
328
|
+
| `delete_resource.rb` | Deleting resources |
|
|
329
|
+
| `fetch_workspaces.rb` | Fetching workspaces via RBAC HTTP API |
|
|
330
|
+
| `list_workspaces.rb` | Listing workspaces with auto-pagination |
|
|
331
|
+
| `report_resource.rb` | Reporting resource state |
|
|
332
|
+
| `console_principal.rb` | Building principals from `x-rh-identity` headers |
|
|
333
|
+
| `streamed_list_objects.rb` | Streaming resource lists |
|
|
234
334
|
|
|
235
335
|
Run examples:
|
|
236
336
|
|
|
237
337
|
```bash
|
|
238
338
|
cd examples
|
|
339
|
+
bundle install
|
|
239
340
|
ruby check.rb
|
|
240
341
|
```
|
|
241
342
|
|
|
242
|
-
##
|
|
343
|
+
## Documentation
|
|
243
344
|
|
|
244
|
-
|
|
345
|
+
Detailed domain-specific guidelines are maintained in the `docs/` directory:
|
|
346
|
+
|
|
347
|
+
- **[API Contracts](docs/api-contracts-guidelines.md)** -- Protobuf code generation, module/namespace mapping, ClientBuilder API, request/response patterns, and RBS type signatures
|
|
348
|
+
- **[Integration](docs/integration-guidelines.md)** -- gRPC client construction, authentication flows, RBAC helpers, streaming/pagination, and environment configuration
|
|
349
|
+
- **[Security](docs/security-guidelines.md)** -- Token caching thread safety, gRPC channel security, credential validation, and secrets management
|
|
350
|
+
- **[Performance](docs/performance-guidelines.md)** -- Token caching, gRPC client reuse, bulk vs. individual operations, consistency controls, and streaming pagination
|
|
351
|
+
- **[Error Handling](docs/error-handling-guidelines.md)** -- Custom exception hierarchy, error wrapping conventions, and gRPC error passthrough policy
|
|
352
|
+
- **[Testing](docs/testing-guidelines.md)** -- RSpec configuration, mocking conventions, coverage setup, and CI expectations
|
|
353
|
+
|
|
354
|
+
For AI-assisted development context, see [AGENTS.md](AGENTS.md).
|
|
245
355
|
|
|
246
|
-
- **High-level SDK**: Fluent client builder API
|
|
247
|
-
- **Authentication**: OAuth 2.0 Client Credentials flow
|
|
248
|
-
- **Convenience Methods**: Simplified APIs for common operations*
|
|
249
|
-
*
|
|
250
356
|
## Release Instructions
|
|
251
357
|
|
|
252
358
|
This section provides step-by-step instructions for maintainers to release a new version of the Kessel SDK for Ruby.
|
|
@@ -256,7 +362,7 @@ This section provides step-by-step instructions for maintainers to release a new
|
|
|
256
362
|
This project follows [Semantic Versioning 2.0.0](https://semver.org/). Version numbers use the format `MAJOR.MINOR.PATCH`:
|
|
257
363
|
|
|
258
364
|
- **MAJOR**: Increment for incompatible API changes
|
|
259
|
-
- **MINOR**: Increment for backward-compatible functionality additions
|
|
365
|
+
- **MINOR**: Increment for backward-compatible functionality additions
|
|
260
366
|
- **PATCH**: Increment for backward-compatible bug fixes
|
|
261
367
|
|
|
262
368
|
**Note**: SDK versions across different languages (Ruby, Python, Go, etc.) do not need to be synchronized. Each language SDK can evolve independently based on its specific requirements and release schedule.
|
|
@@ -377,6 +483,8 @@ rake release
|
|
|
377
483
|
4. Push to the branch (`git push origin feature/amazing-feature`)
|
|
378
484
|
5. Open a Pull Request
|
|
379
485
|
|
|
486
|
+
Please review the [domain-specific guidelines](docs/) before contributing. All specs must pass on Ruby 3.3 and 3.4. Fix RuboCop violations before merging, and update RBS type signatures in `sig/kessel/` when modifying hand-written code.
|
|
487
|
+
|
|
380
488
|
## License
|
|
381
489
|
|
|
382
490
|
This project is licensed under the Apache License 2.0 - see the [LICENSE](LICENSE) file for details.
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'json'
|
|
4
|
+
require 'base64'
|
|
5
|
+
require_relative 'rbac/v2_helpers'
|
|
6
|
+
|
|
7
|
+
module Kessel
|
|
8
|
+
module Console
|
|
9
|
+
include Kessel::RBAC::V2
|
|
10
|
+
extend self
|
|
11
|
+
|
|
12
|
+
DEFAULT_DOMAIN = 'redhat'
|
|
13
|
+
|
|
14
|
+
IDENTITY_TYPE_FIELDS = {
|
|
15
|
+
'User' => 'user',
|
|
16
|
+
'ServiceAccount' => 'service_account'
|
|
17
|
+
}.freeze
|
|
18
|
+
|
|
19
|
+
def principal_from_rh_identity(identity, domain: DEFAULT_DOMAIN)
|
|
20
|
+
user_id = extract_user_id(identity)
|
|
21
|
+
principal_subject(user_id, domain)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def principal_from_rh_identity_header(header, domain: DEFAULT_DOMAIN)
|
|
25
|
+
decoded = JSON.parse(Base64.decode64(header))
|
|
26
|
+
rescue StandardError => e
|
|
27
|
+
raise ArgumentError, "Failed to decode identity header: #{e.message}"
|
|
28
|
+
else
|
|
29
|
+
raise ArgumentError, 'Identity header did not decode to a JSON object' unless decoded.is_a?(Hash)
|
|
30
|
+
|
|
31
|
+
identity = decoded['identity']
|
|
32
|
+
raise ArgumentError, "Identity header is missing the 'identity' envelope key" if identity.nil?
|
|
33
|
+
|
|
34
|
+
principal_from_rh_identity(identity, domain: domain)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
private
|
|
38
|
+
|
|
39
|
+
def extract_user_id(identity)
|
|
40
|
+
raise ArgumentError, 'identity must be a Hash' unless identity.is_a?(Hash)
|
|
41
|
+
|
|
42
|
+
identity_type = identity['type']
|
|
43
|
+
field = identity_field_for(identity_type)
|
|
44
|
+
details = identity_details_for(identity, field, identity_type)
|
|
45
|
+
resolve_user_id(details, identity_type)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def identity_field_for(identity_type)
|
|
49
|
+
IDENTITY_TYPE_FIELDS.fetch(identity_type) do
|
|
50
|
+
supported = IDENTITY_TYPE_FIELDS.keys.sort.join(', ')
|
|
51
|
+
raise ArgumentError, "Unsupported identity type: #{identity_type.inspect} (supported: #{supported})"
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def identity_details_for(identity, field, identity_type)
|
|
56
|
+
details = identity[field]
|
|
57
|
+
unless details.is_a?(Hash)
|
|
58
|
+
raise ArgumentError, "Identity type #{identity_type.inspect} is missing the '#{field}' field"
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
details
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def resolve_user_id(details, identity_type)
|
|
65
|
+
user_id = details['user_id'].to_s
|
|
66
|
+
raise ArgumentError, "Unable to resolve user ID from #{identity_type} identity (tried: user_id)" if user_id.empty?
|
|
67
|
+
|
|
68
|
+
user_id
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
@@ -15,6 +15,8 @@ require 'kessel/inventory/v1beta2/delete_resource_request_pb'
|
|
|
15
15
|
require 'kessel/inventory/v1beta2/delete_resource_response_pb'
|
|
16
16
|
require 'kessel/inventory/v1beta2/streamed_list_objects_request_pb'
|
|
17
17
|
require 'kessel/inventory/v1beta2/streamed_list_objects_response_pb'
|
|
18
|
+
require 'kessel/inventory/v1beta2/streamed_list_subjects_request_pb'
|
|
19
|
+
require 'kessel/inventory/v1beta2/streamed_list_subjects_response_pb'
|
|
18
20
|
require 'kessel/inventory/v1beta2/check_bulk_request_pb'
|
|
19
21
|
require 'kessel/inventory/v1beta2/check_bulk_response_pb'
|
|
20
22
|
require 'kessel/inventory/v1beta2/check_self_request_pb'
|
|
@@ -25,7 +27,7 @@ require 'kessel/inventory/v1beta2/check_for_update_bulk_request_pb'
|
|
|
25
27
|
require 'kessel/inventory/v1beta2/check_for_update_bulk_response_pb'
|
|
26
28
|
|
|
27
29
|
|
|
28
|
-
descriptor_data = "\n0kessel/inventory/v1beta2/inventory_service.proto\x12\x18kessel.inventory.v1beta2\x1a\x1cgoogle/api/annotations.proto\x1a,kessel/inventory/v1beta2/check_request.proto\x1a-kessel/inventory/v1beta2/check_response.proto\x1a\x37kessel/inventory/v1beta2/check_for_update_request.proto\x1a\x38kessel/inventory/v1beta2/check_for_update_response.proto\x1a\x36kessel/inventory/v1beta2/report_resource_request.proto\x1a\x37kessel/inventory/v1beta2/report_resource_response.proto\x1a\x36kessel/inventory/v1beta2/delete_resource_request.proto\x1a\x37kessel/inventory/v1beta2/delete_resource_response.proto\x1a<kessel/inventory/v1beta2/streamed_list_objects_request.proto\x1a=kessel/inventory/v1beta2/streamed_list_objects_response.proto\x1a\x31kessel/inventory/v1beta2/check_bulk_request.proto\x1a\x32kessel/inventory/v1beta2/check_bulk_response.proto\x1a\x31kessel/inventory/v1beta2/check_self_request.proto\x1a\x32kessel/inventory/v1beta2/check_self_response.proto\x1a\x36kessel/inventory/v1beta2/check_self_bulk_request.proto\x1a\x37kessel/inventory/v1beta2/check_self_bulk_response.proto\x1a<kessel/inventory/v1beta2/check_for_update_bulk_request.proto\x1a=kessel/inventory/v1beta2/check_for_update_bulk_response.proto2\
|
|
30
|
+
descriptor_data = "\n0kessel/inventory/v1beta2/inventory_service.proto\x12\x18kessel.inventory.v1beta2\x1a\x1cgoogle/api/annotations.proto\x1a,kessel/inventory/v1beta2/check_request.proto\x1a-kessel/inventory/v1beta2/check_response.proto\x1a\x37kessel/inventory/v1beta2/check_for_update_request.proto\x1a\x38kessel/inventory/v1beta2/check_for_update_response.proto\x1a\x36kessel/inventory/v1beta2/report_resource_request.proto\x1a\x37kessel/inventory/v1beta2/report_resource_response.proto\x1a\x36kessel/inventory/v1beta2/delete_resource_request.proto\x1a\x37kessel/inventory/v1beta2/delete_resource_response.proto\x1a<kessel/inventory/v1beta2/streamed_list_objects_request.proto\x1a=kessel/inventory/v1beta2/streamed_list_objects_response.proto\x1a=kessel/inventory/v1beta2/streamed_list_subjects_request.proto\x1a>kessel/inventory/v1beta2/streamed_list_subjects_response.proto\x1a\x31kessel/inventory/v1beta2/check_bulk_request.proto\x1a\x32kessel/inventory/v1beta2/check_bulk_response.proto\x1a\x31kessel/inventory/v1beta2/check_self_request.proto\x1a\x32kessel/inventory/v1beta2/check_self_response.proto\x1a\x36kessel/inventory/v1beta2/check_self_bulk_request.proto\x1a\x37kessel/inventory/v1beta2/check_self_bulk_response.proto\x1a<kessel/inventory/v1beta2/check_for_update_bulk_request.proto\x1a=kessel/inventory/v1beta2/check_for_update_bulk_response.proto2\x86\x0c\n\x16KesselInventoryService\x12~\n\x05\x43heck\x12&.kessel.inventory.v1beta2.CheckRequest\x1a\'.kessel.inventory.v1beta2.CheckResponse\"$\x82\xd3\xe4\x93\x02\x1e\"\x19/api/kessel/v1beta2/check:\x01*\x12\x8e\x01\n\tCheckSelf\x12*.kessel.inventory.v1beta2.CheckSelfRequest\x1a+.kessel.inventory.v1beta2.CheckSelfResponse\"(\x82\xd3\xe4\x93\x02\"\"\x1d/api/kessel/v1beta2/checkself:\x01*\x12\xa2\x01\n\x0e\x43heckForUpdate\x12/.kessel.inventory.v1beta2.CheckForUpdateRequest\x1a\x30.kessel.inventory.v1beta2.CheckForUpdateResponse\"-\x82\xd3\xe4\x93\x02\'\"\"/api/kessel/v1beta2/checkforupdate:\x01*\x12\xb2\x01\n\x12\x43heckForUpdateBulk\x12\x33.kessel.inventory.v1beta2.CheckForUpdateBulkRequest\x1a\x34.kessel.inventory.v1beta2.CheckForUpdateBulkResponse\"1\x82\xd3\xe4\x93\x02+\"&/api/kessel/v1beta2/checkforupdatebulk:\x01*\x12\x8e\x01\n\tCheckBulk\x12*.kessel.inventory.v1beta2.CheckBulkRequest\x1a+.kessel.inventory.v1beta2.CheckBulkResponse\"(\x82\xd3\xe4\x93\x02\"\"\x1d/api/kessel/v1beta2/checkbulk:\x01*\x12\x9e\x01\n\rCheckSelfBulk\x12..kessel.inventory.v1beta2.CheckSelfBulkRequest\x1a/.kessel.inventory.v1beta2.CheckSelfBulkResponse\",\x82\xd3\xe4\x93\x02&\"!/api/kessel/v1beta2/checkselfbulk:\x01*\x12\x9d\x01\n\x0eReportResource\x12/.kessel.inventory.v1beta2.ReportResourceRequest\x1a\x30.kessel.inventory.v1beta2.ReportResourceResponse\"(\x82\xd3\xe4\x93\x02\"\"\x1d/api/kessel/v1beta2/resources:\x01*\x12\x9d\x01\n\x0e\x44\x65leteResource\x12/.kessel.inventory.v1beta2.DeleteResourceRequest\x1a\x30.kessel.inventory.v1beta2.DeleteResourceResponse\"(\x82\xd3\xe4\x93\x02\"*\x1d/api/kessel/v1beta2/resources:\x01*\x12\x84\x01\n\x13StreamedListObjects\x12\x34.kessel.inventory.v1beta2.StreamedListObjectsRequest\x1a\x35.kessel.inventory.v1beta2.StreamedListObjectsResponse0\x01\x12\x87\x01\n\x14StreamedListSubjects\x12\x35.kessel.inventory.v1beta2.StreamedListSubjectsRequest\x1a\x36.kessel.inventory.v1beta2.StreamedListSubjectsResponse0\x01\x42r\n(org.project_kessel.api.inventory.v1beta2P\x01ZDgithub.com/project-kessel/inventory-api/api/kessel/inventory/v1beta2b\x06proto3"
|
|
29
31
|
|
|
30
32
|
pool = ::Google::Protobuf::DescriptorPool.generated_pool
|
|
31
33
|
pool.add_serialized_file(descriptor_data)
|
|
@@ -132,6 +132,17 @@ module Kessel
|
|
|
132
132
|
#
|
|
133
133
|
# Pagination and consistency controls allow fine-tuned performance and data freshness.
|
|
134
134
|
rpc :StreamedListObjects, ::Kessel::Inventory::V1beta2::StreamedListObjectsRequest, stream(::Kessel::Inventory::V1beta2::StreamedListObjectsResponse)
|
|
135
|
+
# Streams a list of subjects that have the specified relation to a resource.
|
|
136
|
+
#
|
|
137
|
+
# This relationship query answers the question:
|
|
138
|
+
# "Which subjects of type *X* have relation *Y* to resource *Z*?"
|
|
139
|
+
#
|
|
140
|
+
# It is often used for access auditing, troubleshooting permissions, or
|
|
141
|
+
# displaying lists of users/principals with specific access to a resource.
|
|
142
|
+
# The result is streamed incrementally to support large datasets.
|
|
143
|
+
#
|
|
144
|
+
# Pagination and consistency controls allow fine-tuned performance and data freshness.
|
|
145
|
+
rpc :StreamedListSubjects, ::Kessel::Inventory::V1beta2::StreamedListSubjectsRequest, stream(::Kessel::Inventory::V1beta2::StreamedListSubjectsResponse)
|
|
135
146
|
end
|
|
136
147
|
|
|
137
148
|
Stub = Service.rpc_stub_class
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
|
3
|
+
# source: kessel/inventory/v1beta2/streamed_list_subjects_request.proto
|
|
4
|
+
|
|
5
|
+
require 'google/protobuf'
|
|
6
|
+
|
|
7
|
+
require 'buf/validate/validate_pb'
|
|
8
|
+
require 'kessel/inventory/v1beta2/resource_reference_pb'
|
|
9
|
+
require 'kessel/inventory/v1beta2/representation_type_pb'
|
|
10
|
+
require 'kessel/inventory/v1beta2/request_pagination_pb'
|
|
11
|
+
require 'kessel/inventory/v1beta2/consistency_pb'
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
descriptor_data = "\n=kessel/inventory/v1beta2/streamed_list_subjects_request.proto\x12\x18kessel.inventory.v1beta2\x1a\x1b\x62uf/validate/validate.proto\x1a\x31kessel/inventory/v1beta2/resource_reference.proto\x1a\x32kessel/inventory/v1beta2/representation_type.proto\x1a\x31kessel/inventory/v1beta2/request_pagination.proto\x1a*kessel/inventory/v1beta2/consistency.proto\"\xf0\x03\n\x1bStreamedListSubjectsRequest\x12O\n\x08resource\x18\x01 \x01(\x0b\x32+.kessel.inventory.v1beta2.ResourceReferenceB\x06\xbaH\x03\xc8\x01\x01R\x08resource\x12#\n\x08relation\x18\x02 \x01(\tB\x07\xbaH\x04r\x02\x10\x01R\x08relation\x12W\n\x0csubject_type\x18\x03 \x01(\x0b\x32,.kessel.inventory.v1beta2.RepresentationTypeB\x06\xbaH\x03\xc8\x01\x01R\x0bsubjectType\x12.\n\x10subject_relation\x18\x04 \x01(\tH\x00R\x0fsubjectRelation\x88\x01\x01\x12P\n\npagination\x18\x05 \x01(\x0b\x32+.kessel.inventory.v1beta2.RequestPaginationH\x01R\npagination\x88\x01\x01\x12L\n\x0b\x63onsistency\x18\x06 \x01(\x0b\x32%.kessel.inventory.v1beta2.ConsistencyH\x02R\x0b\x63onsistency\x88\x01\x01\x42\x13\n\x11_subject_relationB\r\n\x0b_paginationB\x0e\n\x0c_consistencyBr\n(org.project_kessel.api.inventory.v1beta2P\x01ZDgithub.com/project-kessel/inventory-api/api/kessel/inventory/v1beta2b\x06proto3"
|
|
15
|
+
|
|
16
|
+
pool = ::Google::Protobuf::DescriptorPool.generated_pool
|
|
17
|
+
pool.add_serialized_file(descriptor_data)
|
|
18
|
+
|
|
19
|
+
module Kessel
|
|
20
|
+
module Inventory
|
|
21
|
+
module V1beta2
|
|
22
|
+
StreamedListSubjectsRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("kessel.inventory.v1beta2.StreamedListSubjectsRequest").msgclass
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
|
3
|
+
# source: kessel/inventory/v1beta2/streamed_list_subjects_response.proto
|
|
4
|
+
|
|
5
|
+
require 'google/protobuf'
|
|
6
|
+
|
|
7
|
+
require 'kessel/inventory/v1beta2/subject_reference_pb'
|
|
8
|
+
require 'kessel/inventory/v1beta2/response_pagination_pb'
|
|
9
|
+
require 'kessel/inventory/v1beta2/consistency_token_pb'
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
descriptor_data = "\n>kessel/inventory/v1beta2/streamed_list_subjects_response.proto\x12\x18kessel.inventory.v1beta2\x1a\x30kessel/inventory/v1beta2/subject_reference.proto\x1a\x32kessel/inventory/v1beta2/response_pagination.proto\x1a\x30kessel/inventory/v1beta2/consistency_token.proto\"\x8b\x02\n\x1cStreamedListSubjectsResponse\x12\x44\n\x07subject\x18\x01 \x01(\x0b\x32*.kessel.inventory.v1beta2.SubjectReferenceR\x07subject\x12L\n\npagination\x18\x02 \x01(\x0b\x32,.kessel.inventory.v1beta2.ResponsePaginationR\npagination\x12W\n\x11\x63onsistency_token\x18\x03 \x01(\x0b\x32*.kessel.inventory.v1beta2.ConsistencyTokenR\x10\x63onsistencyTokenBr\n(org.project_kessel.api.inventory.v1beta2P\x01ZDgithub.com/project-kessel/inventory-api/api/kessel/inventory/v1beta2b\x06proto3"
|
|
13
|
+
|
|
14
|
+
pool = ::Google::Protobuf::DescriptorPool.generated_pool
|
|
15
|
+
pool.add_serialized_file(descriptor_data)
|
|
16
|
+
|
|
17
|
+
module Kessel
|
|
18
|
+
module Inventory
|
|
19
|
+
module V1beta2
|
|
20
|
+
StreamedListSubjectsResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("kessel.inventory.v1beta2.StreamedListSubjectsResponse").msgclass
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
data/lib/kessel/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: kessel-sdk
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.9.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Project Kessel
|
|
@@ -207,6 +207,7 @@ files:
|
|
|
207
207
|
- lib/google/rpc/status_pb.rb
|
|
208
208
|
- lib/kessel-sdk.rb
|
|
209
209
|
- lib/kessel/auth.rb
|
|
210
|
+
- lib/kessel/console.rb
|
|
210
211
|
- lib/kessel/grpc.rb
|
|
211
212
|
- lib/kessel/inventory.rb
|
|
212
213
|
- lib/kessel/inventory/v1.rb
|
|
@@ -265,6 +266,8 @@ files:
|
|
|
265
266
|
- lib/kessel/inventory/v1beta2/response_pagination_pb.rb
|
|
266
267
|
- lib/kessel/inventory/v1beta2/streamed_list_objects_request_pb.rb
|
|
267
268
|
- lib/kessel/inventory/v1beta2/streamed_list_objects_response_pb.rb
|
|
269
|
+
- lib/kessel/inventory/v1beta2/streamed_list_subjects_request_pb.rb
|
|
270
|
+
- lib/kessel/inventory/v1beta2/streamed_list_subjects_response_pb.rb
|
|
268
271
|
- lib/kessel/inventory/v1beta2/subject_reference_pb.rb
|
|
269
272
|
- lib/kessel/inventory/v1beta2/write_visibility_pb.rb
|
|
270
273
|
- lib/kessel/rbac/v2.rb
|