legion-data 1.6.20 → 1.6.22
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/.gitignore +1 -0
- data/CHANGELOG.md +24 -0
- data/CLAUDE.md +6 -4
- data/lib/legion/data/migration.rb +5 -0
- data/lib/legion/data/migrations/062_create_tool_embedding_cache.rb +17 -0
- data/lib/legion/data/migrations/063_create_identity_providers.rb +27 -0
- data/lib/legion/data/migrations/064_create_principals.rb +30 -0
- data/lib/legion/data/migrations/065_create_identities.rb +33 -0
- data/lib/legion/data/migrations/066_create_identity_groups.rb +23 -0
- data/lib/legion/data/migrations/067_create_identity_group_memberships.rb +36 -0
- data/lib/legion/data/migrations/068_add_entity_type_to_audit_records.rb +23 -0
- data/lib/legion/data/migrations/069_add_principal_id_to_nodes.rb +22 -0
- data/lib/legion/data/model.rb +2 -1
- data/lib/legion/data/models/identity.rb +19 -0
- data/lib/legion/data/models/identity_group.rb +13 -0
- data/lib/legion/data/models/identity_group_membership.rb +22 -0
- data/lib/legion/data/models/identity_provider.rb +17 -0
- data/lib/legion/data/models/node.rb +1 -0
- data/lib/legion/data/models/principal.rb +22 -0
- data/lib/legion/data/version.rb +1 -1
- data/lib/legion/data.rb +19 -0
- metadata +14 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1f925497f4f43ca263e4cd90d07bb3adddc947e3713bc8cab3a489ae5e162a68
|
|
4
|
+
data.tar.gz: c3eb803e0c3b65459ef74adb5a40d5afdcac41ba6adb64401b70809414c052bf
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 057b2b9fa0518455dae0b1a5907ea303e17c191f4b34306e92124a48a1022a3f10eabfe34b07456085ecd4aca823ba86d352b4562865d94ca23d13ce857b0e6e
|
|
7
|
+
data.tar.gz: 99a7bef85d7f5045d638ea1f06a9c336da33c21b6ab6b46c6421de9e0aac50d3ab394535e539e7bafe2f7585103864f35444ba87dd59a90107831a6eb9f18abc
|
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,30 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [1.6.22] - 2026-04-06
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- Migration 063: `identity_providers` table (provider_type, facing, priority, trust_weight, capabilities)
|
|
9
|
+
- Migration 064: `principals` table (canonical_name regex constraint, kind, unique composite)
|
|
10
|
+
- Migration 065: `identities` table (principal/provider FKs, partial unique index on active)
|
|
11
|
+
- Migration 066: `identity_groups` table (source: ldap/entra/manual)
|
|
12
|
+
- Migration 067: `identity_group_memberships` table (status, trust_weight, discovered_by, tie-break index)
|
|
13
|
+
- Migration 068: `entity_type` column on `audit_records` with index
|
|
14
|
+
- Migration 069: `principal_id` FK on `nodes` table
|
|
15
|
+
- 5 Sequel models: `IdentityProvider`, `Principal`, `Identity`, `IdentityGroup`, `IdentityGroupMembership`
|
|
16
|
+
- `Identity` model wired through `SequelPlugin` `encrypted_column :profile` for at-rest encryption
|
|
17
|
+
- `Node` model gains `many_to_one :principal` association
|
|
18
|
+
|
|
19
|
+
### Changed
|
|
20
|
+
- Migration mode gate: only `:infra` mode runs migrations when `Legion::Mode` is available
|
|
21
|
+
- `auto_migrate` settings check wired into `Data.setup` (skips migrations when `auto_migrate: false`)
|
|
22
|
+
- Mode guard added to both `Data.migrate` and `Migration.migrate` for defense-in-depth
|
|
23
|
+
|
|
24
|
+
## [1.6.21] - 2026-04-05
|
|
25
|
+
|
|
26
|
+
### Added
|
|
27
|
+
- Migration 062: `tool_embedding_cache` table for global embedding persistence
|
|
28
|
+
|
|
5
29
|
## [1.6.20] - 2026-04-03
|
|
6
30
|
|
|
7
31
|
### Fixed
|
data/CLAUDE.md
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
Manages persistent database storage for the LegionIO framework. Supports SQLite (default), MySQL, and PostgreSQL via Sequel ORM. Provides automatic schema migrations and data models for extensions, functions, runners, nodes, tasks, settings, digital workers, task relationships, Apollo shared knowledge tables (PostgreSQL only), tenants, webhooks, audit log, and archive tables. Also provides a parallel local SQLite database (`Legion::Data::Local`) for agentic cognitive state persistence.
|
|
9
9
|
|
|
10
10
|
**GitHub**: https://github.com/LegionIO/legion-data
|
|
11
|
-
**Version**: 1.6.
|
|
11
|
+
**Version**: 1.6.21
|
|
12
12
|
**License**: Apache-2.0
|
|
13
13
|
|
|
14
14
|
## Supported Databases
|
|
@@ -56,7 +56,7 @@ Legion::Data (singleton module)
|
|
|
56
56
|
│ ├── .shutdown # Close local connection
|
|
57
57
|
│ └── .reset! # Clear all state (testing)
|
|
58
58
|
│
|
|
59
|
-
├── Migration # Auto-migration system (
|
|
59
|
+
├── Migration # Auto-migration system (58 migrations, Sequel DSL)
|
|
60
60
|
│ └── migrations/
|
|
61
61
|
│ ├── 001_add_schema_columns
|
|
62
62
|
│ ├── 002_add_nodes
|
|
@@ -114,7 +114,8 @@ Legion::Data (singleton module)
|
|
|
114
114
|
│ ├── 054_add_component_type_to_functions # component_type on functions (runner/hook/absorber, v3.0)
|
|
115
115
|
│ ├── 055_add_definition_to_functions # definition text column on functions (v3.0)
|
|
116
116
|
│ ├── 056_add_absorber_patterns # absorber_patterns table for pattern-matched acquisition
|
|
117
|
-
│
|
|
117
|
+
│ ├── 057_add_routing_key_to_runners # routing_key on runners (v3.0 AMQP)
|
|
118
|
+
│ └── 058_add_tool_embedding_cache # tool_embedding_cache table for global embedding cache tier (Tools::EmbeddingCache L4)
|
|
118
119
|
│
|
|
119
120
|
├── Model # Sequel model loader
|
|
120
121
|
│ └── Models/
|
|
@@ -279,7 +280,7 @@ Per-adapter credential defaults are defined in `Settings::CREDS`:
|
|
|
279
280
|
| `lib/legion/data.rb` | Module entry, setup/shutdown lifecycle |
|
|
280
281
|
| `lib/legion/data/connection.rb` | Sequel database connection (adapter selection) |
|
|
281
282
|
| `lib/legion/data/migration.rb` | Migration runner |
|
|
282
|
-
| `lib/legion/data/migrations/` |
|
|
283
|
+
| `lib/legion/data/migrations/` | 58 numbered migration files (Sequel DSL) |
|
|
283
284
|
| `lib/legion/data/model.rb` | Model autoloader |
|
|
284
285
|
| `lib/legion/data/local.rb` | Local SQLite module for agentic cognitive state |
|
|
285
286
|
| `lib/legion/data/models/` | Sequel models (Extension, Function, Runner, Node, Task, TaskLog, Setting, DigitalWorker, Relationship, ApolloEntry, ApolloRelation, ApolloExpertise, ApolloAccessLog, AuditLog, RbacRoleAssignment, RbacRunnerGrant, RbacCrossTeamGrant) |
|
|
@@ -320,6 +321,7 @@ Optional persistent storage initialized during `Legion::Service` startup (after
|
|
|
320
321
|
13. Archive, memory traces, and tenant partition tables (migrations 021–025)
|
|
321
322
|
14. Function embeddings for semantic runner discovery (migration 026 — description + vector columns on functions table)
|
|
322
323
|
15. Financial logging for UAIS cost recovery (migration 048 — 7 tables: identity, asset, environment, accounting, execution, tags, usage rollup)
|
|
324
|
+
16. Global tool embedding cache (migration 058 — `tool_embedding_cache` table, L4 tier for `Legion::Tools::EmbeddingCache`)
|
|
323
325
|
|
|
324
326
|
---
|
|
325
327
|
|
|
@@ -11,6 +11,11 @@ module Legion
|
|
|
11
11
|
include Legion::Logging::Helper
|
|
12
12
|
|
|
13
13
|
def migrate(connection = Legion::Data.connection, path = "#{__dir__}/migrations", **)
|
|
14
|
+
if defined?(Legion::Mode) && Legion::Mode.respond_to?(:current) && !Legion::Mode.infra?
|
|
15
|
+
log.info "Legion::Data::Migration skipped (mode: #{Legion::Mode.current}, requires: infra)"
|
|
16
|
+
return
|
|
17
|
+
end
|
|
18
|
+
|
|
14
19
|
Legion::Settings[:data][:migrations][:version] = Sequel::Migrator.run(connection, path, **)
|
|
15
20
|
log.info("Legion::Data::Migration ran successfully to version #{Legion::Settings[:data][:migrations][:version]}")
|
|
16
21
|
Legion::Settings[:data][:migrations][:ran] = true
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
Sequel.migration do
|
|
4
|
+
change do
|
|
5
|
+
create_table(:tool_embedding_cache) do
|
|
6
|
+
primary_key :id
|
|
7
|
+
String :content_hash, size: 32, null: false
|
|
8
|
+
String :model, size: 100, null: false
|
|
9
|
+
String :tool_name, size: 200, null: false
|
|
10
|
+
column :vector, :text, null: false
|
|
11
|
+
DateTime :embedded_at, null: false
|
|
12
|
+
DateTime :created_at, null: false, default: Sequel::CURRENT_TIMESTAMP
|
|
13
|
+
unique %i[content_hash model]
|
|
14
|
+
index :tool_name
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
Sequel.migration do
|
|
4
|
+
up do
|
|
5
|
+
next unless adapter_scheme == :postgres
|
|
6
|
+
|
|
7
|
+
create_table(:identity_providers) do
|
|
8
|
+
column :id, :uuid, default: Sequel.lit('gen_random_uuid()'), primary_key: true
|
|
9
|
+
String :name, null: false, unique: true
|
|
10
|
+
String :provider_type, null: false # authenticate, profile, fallback
|
|
11
|
+
String :facing, null: false # human, machine, both
|
|
12
|
+
Integer :priority, null: false, default: 100
|
|
13
|
+
Integer :trust_weight, null: false, default: 50
|
|
14
|
+
column :capabilities, :'text[]', default: Sequel.lit("'{}'")
|
|
15
|
+
String :source, null: false, default: 'gem' # gem, db
|
|
16
|
+
TrueClass :enabled, null: false, default: true
|
|
17
|
+
DateTime :created_at, null: false, default: Sequel::CURRENT_TIMESTAMP
|
|
18
|
+
DateTime :updated_at, null: false, default: Sequel::CURRENT_TIMESTAMP
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
down do
|
|
23
|
+
next unless adapter_scheme == :postgres
|
|
24
|
+
|
|
25
|
+
drop_table?(:identity_providers)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
Sequel.migration do
|
|
4
|
+
up do
|
|
5
|
+
next unless adapter_scheme == :postgres
|
|
6
|
+
|
|
7
|
+
create_table(:principals) do
|
|
8
|
+
column :id, :uuid, default: Sequel.lit('gen_random_uuid()'), primary_key: true
|
|
9
|
+
String :canonical_name, null: false
|
|
10
|
+
String :kind, null: false # human, service, machine
|
|
11
|
+
String :display_name
|
|
12
|
+
TrueClass :active, null: false, default: true
|
|
13
|
+
DateTime :last_seen_at
|
|
14
|
+
DateTime :created_at, null: false, default: Sequel::CURRENT_TIMESTAMP
|
|
15
|
+
DateTime :updated_at, null: false, default: Sequel::CURRENT_TIMESTAMP
|
|
16
|
+
|
|
17
|
+
constraint(:canonical_name_format, Sequel.lit("canonical_name ~ '^[a-z0-9][a-z0-9_-]*$'"))
|
|
18
|
+
unique %i[canonical_name kind]
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
add_index :principals, :canonical_name
|
|
22
|
+
add_index :principals, :kind
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
down do
|
|
26
|
+
next unless adapter_scheme == :postgres
|
|
27
|
+
|
|
28
|
+
drop_table?(:principals)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
Sequel.migration do
|
|
4
|
+
up do
|
|
5
|
+
next unless adapter_scheme == :postgres
|
|
6
|
+
|
|
7
|
+
create_table(:identities) do
|
|
8
|
+
column :id, :uuid, default: Sequel.lit('gen_random_uuid()'), primary_key: true
|
|
9
|
+
foreign_key :principal_id, :principals, type: :uuid, null: false, on_delete: :cascade
|
|
10
|
+
foreign_key :provider_id, :identity_providers, type: :uuid, null: false, on_delete: :cascade
|
|
11
|
+
String :provider_identity, null: false # external ID from provider
|
|
12
|
+
column :profile, :bytea
|
|
13
|
+
TrueClass :active, null: false, default: true
|
|
14
|
+
DateTime :last_authenticated_at
|
|
15
|
+
DateTime :created_at, null: false, default: Sequel::CURRENT_TIMESTAMP
|
|
16
|
+
DateTime :updated_at, null: false, default: Sequel::CURRENT_TIMESTAMP
|
|
17
|
+
|
|
18
|
+
unique %i[principal_id provider_id provider_identity]
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Partial unique index: only one active identity per provider+provider_identity
|
|
22
|
+
run 'CREATE UNIQUE INDEX identities_active_provider_uniq ON identities (provider_id, provider_identity) WHERE active = true'
|
|
23
|
+
|
|
24
|
+
add_index :identities, :principal_id
|
|
25
|
+
add_index :identities, :provider_id
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
down do
|
|
29
|
+
next unless adapter_scheme == :postgres
|
|
30
|
+
|
|
31
|
+
drop_table?(:identities)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
Sequel.migration do
|
|
4
|
+
up do
|
|
5
|
+
next unless adapter_scheme == :postgres
|
|
6
|
+
|
|
7
|
+
create_table(:identity_groups) do
|
|
8
|
+
column :id, :uuid, default: Sequel.lit('gen_random_uuid()'), primary_key: true
|
|
9
|
+
String :name, null: false, unique: true
|
|
10
|
+
String :source, null: false, default: 'ldap' # ldap, entra, manual
|
|
11
|
+
String :description
|
|
12
|
+
TrueClass :active, null: false, default: true
|
|
13
|
+
DateTime :created_at, null: false, default: Sequel::CURRENT_TIMESTAMP
|
|
14
|
+
DateTime :updated_at, null: false, default: Sequel::CURRENT_TIMESTAMP
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
down do
|
|
19
|
+
next unless adapter_scheme == :postgres
|
|
20
|
+
|
|
21
|
+
drop_table?(:identity_groups)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
Sequel.migration do
|
|
4
|
+
up do
|
|
5
|
+
next unless adapter_scheme == :postgres
|
|
6
|
+
|
|
7
|
+
create_table(:identity_group_memberships) do
|
|
8
|
+
column :id, :uuid, default: Sequel.lit('gen_random_uuid()'), primary_key: true
|
|
9
|
+
foreign_key :principal_id, :principals, type: :uuid, null: false, on_delete: :cascade
|
|
10
|
+
foreign_key :group_id, :identity_groups, type: :uuid, null: false, on_delete: :cascade
|
|
11
|
+
String :status, null: false, default: 'active' # active, stale, expired
|
|
12
|
+
String :discovered_by, null: false # provider name that discovered this membership
|
|
13
|
+
Integer :trust_weight, null: false, default: 50
|
|
14
|
+
DateTime :expires_at
|
|
15
|
+
DateTime :created_at, null: false, default: Sequel::CURRENT_TIMESTAMP
|
|
16
|
+
DateTime :updated_at, null: false, default: Sequel::CURRENT_TIMESTAMP
|
|
17
|
+
|
|
18
|
+
unique %i[principal_id group_id discovered_by]
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
add_index :identity_group_memberships, :principal_id
|
|
22
|
+
add_index :identity_group_memberships, :group_id
|
|
23
|
+
add_index :identity_group_memberships, :status
|
|
24
|
+
run <<~SQL
|
|
25
|
+
CREATE INDEX idx_memberships_trust_tiebreak
|
|
26
|
+
ON identity_group_memberships (principal_id, trust_weight ASC,
|
|
27
|
+
CASE status WHEN 'expired' THEN 0 WHEN 'stale' THEN 1 WHEN 'active' THEN 2 END ASC)
|
|
28
|
+
SQL
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
down do
|
|
32
|
+
next unless adapter_scheme == :postgres
|
|
33
|
+
|
|
34
|
+
drop_table?(:identity_group_memberships)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
Sequel.migration do
|
|
4
|
+
up do
|
|
5
|
+
next unless adapter_scheme == :postgres
|
|
6
|
+
next unless table_exists?(:audit_records)
|
|
7
|
+
|
|
8
|
+
alter_table(:audit_records) do
|
|
9
|
+
add_column :entity_type, String, size: 100, null: true
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
add_index :audit_records, :entity_type, name: :idx_audit_records_entity_type
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
down do
|
|
16
|
+
next unless adapter_scheme == :postgres
|
|
17
|
+
next unless table_exists?(:audit_records)
|
|
18
|
+
|
|
19
|
+
alter_table(:audit_records) do
|
|
20
|
+
drop_column :entity_type
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
Sequel.migration do
|
|
4
|
+
up do
|
|
5
|
+
next unless adapter_scheme == :postgres
|
|
6
|
+
|
|
7
|
+
alter_table(:nodes) do
|
|
8
|
+
add_column :principal_id, :uuid
|
|
9
|
+
add_foreign_key [:principal_id], :principals
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
add_index :nodes, :principal_id
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
down do
|
|
16
|
+
next unless adapter_scheme == :postgres
|
|
17
|
+
|
|
18
|
+
alter_table(:nodes) do
|
|
19
|
+
drop_column :principal_id
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
data/lib/legion/data/model.rb
CHANGED
|
@@ -13,7 +13,8 @@ module Legion
|
|
|
13
13
|
def models
|
|
14
14
|
%w[extension function relationship chain task runner node setting digital_worker
|
|
15
15
|
apollo_entry apollo_relation apollo_expertise apollo_access_log audit_log
|
|
16
|
-
audit_record
|
|
16
|
+
audit_record identity_provider principal identity identity_group
|
|
17
|
+
identity_group_membership]
|
|
17
18
|
end
|
|
18
19
|
|
|
19
20
|
def load
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
return unless Legion::Data::Connection.adapter == :postgres
|
|
4
|
+
|
|
5
|
+
module Legion
|
|
6
|
+
module Data
|
|
7
|
+
module Model
|
|
8
|
+
class Identity < Sequel::Model(:identities)
|
|
9
|
+
many_to_one :principal, class: 'Legion::Data::Model::Principal'
|
|
10
|
+
many_to_one :provider, class: 'Legion::Data::Model::IdentityProvider', key: :provider_id
|
|
11
|
+
|
|
12
|
+
if defined?(Legion::Data::Encryption::SequelPlugin)
|
|
13
|
+
plugin Legion::Data::Encryption::SequelPlugin
|
|
14
|
+
encrypted_column :profile
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
return unless Legion::Data::Connection.adapter == :postgres
|
|
4
|
+
|
|
5
|
+
module Legion
|
|
6
|
+
module Data
|
|
7
|
+
module Model
|
|
8
|
+
class IdentityGroup < Sequel::Model(:identity_groups)
|
|
9
|
+
one_to_many :memberships, class: 'Legion::Data::Model::IdentityGroupMembership', key: :group_id
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
return unless Legion::Data::Connection.adapter == :postgres
|
|
4
|
+
|
|
5
|
+
module Legion
|
|
6
|
+
module Data
|
|
7
|
+
module Model
|
|
8
|
+
class IdentityGroupMembership < Sequel::Model(:identity_group_memberships)
|
|
9
|
+
many_to_one :principal, class: 'Legion::Data::Model::Principal'
|
|
10
|
+
many_to_one :group, class: 'Legion::Data::Model::IdentityGroup', key: :group_id
|
|
11
|
+
|
|
12
|
+
def expired?
|
|
13
|
+
status == 'expired' || (expires_at && Time.now >= expires_at)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def stale?
|
|
17
|
+
status == 'stale'
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
return unless Legion::Data::Connection.adapter == :postgres
|
|
4
|
+
|
|
5
|
+
module Legion
|
|
6
|
+
module Data
|
|
7
|
+
module Model
|
|
8
|
+
class IdentityProvider < Sequel::Model(:identity_providers)
|
|
9
|
+
one_to_many :identities, class: 'Legion::Data::Model::Identity'
|
|
10
|
+
|
|
11
|
+
def parsed_capabilities
|
|
12
|
+
Array(capabilities)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
return unless Legion::Data::Connection.adapter == :postgres
|
|
4
|
+
|
|
5
|
+
module Legion
|
|
6
|
+
module Data
|
|
7
|
+
module Model
|
|
8
|
+
class Principal < Sequel::Model(:principals)
|
|
9
|
+
one_to_many :identities, class: 'Legion::Data::Model::Identity'
|
|
10
|
+
one_to_many :group_memberships, class: 'Legion::Data::Model::IdentityGroupMembership'
|
|
11
|
+
|
|
12
|
+
def active_groups
|
|
13
|
+
group_memberships_dataset
|
|
14
|
+
.where(status: 'active')
|
|
15
|
+
.eager(:group)
|
|
16
|
+
.all
|
|
17
|
+
.map(&:group)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
data/lib/legion/data/version.rb
CHANGED
data/lib/legion/data.rb
CHANGED
|
@@ -58,6 +58,8 @@ module Legion
|
|
|
58
58
|
end
|
|
59
59
|
|
|
60
60
|
def migrate
|
|
61
|
+
return if skip_migrations?
|
|
62
|
+
|
|
61
63
|
Legion::Data::Migration.migrate
|
|
62
64
|
end
|
|
63
65
|
|
|
@@ -174,6 +176,23 @@ module Legion
|
|
|
174
176
|
|
|
175
177
|
private
|
|
176
178
|
|
|
179
|
+
def skip_migrations?
|
|
180
|
+
# Check auto_migrate setting
|
|
181
|
+
auto_migrate = Legion::Settings[:data][:migrations][:auto_migrate]
|
|
182
|
+
unless auto_migrate
|
|
183
|
+
log.info 'Legion::Data migrations skipped (auto_migrate: false)'
|
|
184
|
+
return true
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
# Check mode gate: only infra mode runs migrations (when Mode is available)
|
|
188
|
+
if defined?(Legion::Mode) && Legion::Mode.respond_to?(:current) && !Legion::Mode.infra?
|
|
189
|
+
log.info "Legion::Data migrations skipped (mode: #{Legion::Mode.current}, requires: infra)"
|
|
190
|
+
return true
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
false
|
|
194
|
+
end
|
|
195
|
+
|
|
177
196
|
def setup_local
|
|
178
197
|
return if Legion::Settings[:data].dig(:local, :enabled) == false
|
|
179
198
|
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: legion-data
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.6.
|
|
4
|
+
version: 1.6.22
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Esity
|
|
@@ -191,6 +191,14 @@ files:
|
|
|
191
191
|
- lib/legion/data/migrations/059_create_chains.rb
|
|
192
192
|
- lib/legion/data/migrations/060_add_knowledge_tiers.rb
|
|
193
193
|
- lib/legion/data/migrations/061_add_versioning_and_expiry.rb
|
|
194
|
+
- lib/legion/data/migrations/062_create_tool_embedding_cache.rb
|
|
195
|
+
- lib/legion/data/migrations/063_create_identity_providers.rb
|
|
196
|
+
- lib/legion/data/migrations/064_create_principals.rb
|
|
197
|
+
- lib/legion/data/migrations/065_create_identities.rb
|
|
198
|
+
- lib/legion/data/migrations/066_create_identity_groups.rb
|
|
199
|
+
- lib/legion/data/migrations/067_create_identity_group_memberships.rb
|
|
200
|
+
- lib/legion/data/migrations/068_add_entity_type_to_audit_records.rb
|
|
201
|
+
- lib/legion/data/migrations/069_add_principal_id_to_nodes.rb
|
|
194
202
|
- lib/legion/data/model.rb
|
|
195
203
|
- lib/legion/data/models/apollo_access_log.rb
|
|
196
204
|
- lib/legion/data/models/apollo_entry.rb
|
|
@@ -202,7 +210,12 @@ files:
|
|
|
202
210
|
- lib/legion/data/models/digital_worker.rb
|
|
203
211
|
- lib/legion/data/models/extension.rb
|
|
204
212
|
- lib/legion/data/models/function.rb
|
|
213
|
+
- lib/legion/data/models/identity.rb
|
|
214
|
+
- lib/legion/data/models/identity_group.rb
|
|
215
|
+
- lib/legion/data/models/identity_group_membership.rb
|
|
216
|
+
- lib/legion/data/models/identity_provider.rb
|
|
205
217
|
- lib/legion/data/models/node.rb
|
|
218
|
+
- lib/legion/data/models/principal.rb
|
|
206
219
|
- lib/legion/data/models/rbac_cross_team_grant.rb
|
|
207
220
|
- lib/legion/data/models/rbac_role_assignment.rb
|
|
208
221
|
- lib/legion/data/models/rbac_runner_grant.rb
|