From 993fbe7568d0eceff78ab52a72ea6d1404ac4d90 Mon Sep 17 00:00:00 2001 From: Michael Mraka Date: Wed, 20 May 2026 10:33:39 +0200 Subject: [PATCH 1/2] RHINENG-26529: Revert RHINENG-25147 workspace changes (v3.8.260) --- base/core/gintesting.go | 10 ---- base/database/utils.go | 34 ++++++++----- base/database/utils_test.go | 33 +++++++------ base/inventory/inventory.go | 32 +++++++++++++ base/models/models.go | 8 ++-- base/utils/gin.go | 14 +++--- .../migrations/153_simplify_workspaces.up.sql | 13 ----- database_admin/schema/create_schema.sql | 8 ++-- dev/test_data.sql | 48 +++++++++---------- docs/v3/openapi.json | 48 ------------------- listener/common_test.go | 18 ++----- listener/upload.go | 28 ++--------- listener/upload_test.go | 17 +++---- manager/controllers/advisories.go | 16 +++---- manager/controllers/advisories_export.go | 8 ++-- manager/controllers/advisory_systems.go | 9 ++-- .../controllers/advisory_systems_export.go | 4 +- .../advisory_systems_export_test.go | 9 ++-- manager/controllers/common_attributes.go | 13 +---- manager/controllers/package_systems.go | 9 ++-- manager/controllers/package_systems_export.go | 4 +- .../package_systems_export_test.go | 9 ++-- manager/controllers/package_versions.go | 8 ++-- manager/controllers/packages.go | 17 +++---- manager/controllers/packages_export.go | 6 +-- manager/controllers/system_advisories.go | 8 ++-- .../controllers/system_advisories_export.go | 4 +- manager/controllers/system_detail.go | 8 ++-- manager/controllers/system_packages.go | 8 ++-- manager/controllers/system_packages_export.go | 4 +- manager/controllers/systems.go | 9 ++-- .../controllers/systems_advisories_view.go | 14 +++--- .../systems_advisories_view_test.go | 3 +- manager/controllers/systems_export.go | 4 +- manager/controllers/systems_export_test.go | 5 +- manager/controllers/systemtags.go | 4 +- .../template_subscribed_systems_update.go | 5 +- manager/controllers/template_systems.go | 17 ++++--- .../controllers/template_systems_delete.go | 6 +-- .../controllers/template_systems_export.go | 4 +- .../template_systems_export_test.go | 10 ++-- .../controllers/template_systems_update.go | 24 +++++----- manager/controllers/templates.go | 8 ++-- manager/controllers/utils.go | 13 ++++- manager/controllers/utils_test.go | 16 ++++--- manager/middlewares/kessel.go | 34 +++++++++---- manager/middlewares/kessel_test.go | 21 ++++++-- manager/middlewares/rbac.go | 12 ++--- manager/middlewares/rbac_test.go | 13 ++--- 49 files changed, 315 insertions(+), 362 deletions(-) delete mode 100644 database_admin/migrations/153_simplify_workspaces.up.sql diff --git a/base/core/gintesting.go b/base/core/gintesting.go index 02be78cd1..7108536c2 100644 --- a/base/core/gintesting.go +++ b/base/core/gintesting.go @@ -17,15 +17,6 @@ type ContextKV struct { var V3APICtx = ContextKV{Key: utils.KeyApiver, Value: 3} -var WorkspacesTestCtx = ContextKV{ - Key: utils.KeyInventoryWorkspaces, - Value: []string{ - "00000000-0000-0000-0000-000000000001", - "00000000-0000-0000-0000-000000000002", - "00000000-0000-0000-0000-999999999999", - }, -} - func InitRouter(handler gin.HandlerFunc, contextKVs ...ContextKV) *gin.Engine { return InitRouterWithPath(handler, "/", contextKVs...) } @@ -41,7 +32,6 @@ func InitRouterWithParams(handler gin.HandlerFunc, account int, method, path str router.Use(func(c *gin.Context) { // set default api version for tests to latest c.Set(utils.KeyApiver, LatestAPIVersion) - c.Set(utils.KeyInventoryWorkspaces, WorkspacesTestCtx.Value) for _, kv := range contextKVs { c.Set(kv.Key, kv.Value) } diff --git a/base/database/utils.go b/base/database/utils.go index cb7675051..044d6b676 100644 --- a/base/database/utils.go +++ b/base/database/utils.go @@ -26,16 +26,16 @@ func (j joinsT) apply(tx *gorm.DB) *gorm.DB { return tx } -func Systems(tx *gorm.DB, accountID int, workspaceIDs []string, joins ...join) *gorm.DB { +func Systems(tx *gorm.DB, accountID int, groups map[string]string, joins ...join) *gorm.DB { tx = tx.Table("system_inventory si"). Joins("JOIN system_patch spatch ON si.id = spatch.system_id AND si.rh_account_id = spatch.rh_account_id"). Where("si.rh_account_id = ?", accountID) tx = (joinsT)(joins).apply(tx) - return ApplyInventoryWorkspaceFilter(tx, workspaceIDs) + return ApplyInventoryWorkspaceFilter(tx, groups) } -func SystemAdvisories(tx *gorm.DB, accountID int, workspaceIDs []string, joins ...join) *gorm.DB { - tx = Systems(tx, accountID, workspaceIDs). +func SystemAdvisories(tx *gorm.DB, accountID int, groups map[string]string, joins ...join) *gorm.DB { + tx = Systems(tx, accountID, groups). Joins("JOIN system_advisories sa on sa.system_id = si.id AND sa.rh_account_id = ?", accountID) return (joinsT)(joins).apply(tx) } @@ -46,8 +46,8 @@ func SystemPackagesShort(tx *gorm.DB, accountID int, joins ...join) *gorm.DB { return (joinsT)(joins).apply(tx) } -func SystemPackages(tx *gorm.DB, accountID int, workspaceIDs []string, joins ...join) *gorm.DB { - tx = Systems(tx, accountID, workspaceIDs). +func SystemPackages(tx *gorm.DB, accountID int, groups map[string]string, joins ...join) *gorm.DB { + tx = Systems(tx, accountID, groups). Joins("JOIN system_package2 spkg on spkg.system_id = si.id AND spkg.rh_account_id = ?", accountID). Joins("JOIN package p on p.id = spkg.package_id"). Joins("JOIN package_name pn on pn.id = spkg.name_id") @@ -65,9 +65,9 @@ func PackageByName(tx *gorm.DB, pkgName string, joins ...join) *gorm.DB { return (joinsT)(joins).apply(tx) } -func SystemAdvisoriesByInventoryID(tx *gorm.DB, accountID int, workspaceIDs []string, inventoryID string, +func SystemAdvisoriesByInventoryID(tx *gorm.DB, accountID int, groups map[string]string, inventoryID string, joins ...join) *gorm.DB { - tx = SystemAdvisories(tx, accountID, workspaceIDs).Where("si.inventory_id = ?::uuid", inventoryID) + tx = SystemAdvisories(tx, accountID, groups).Where("si.inventory_id = ?::uuid", inventoryID) return (joinsT)(joins).apply(tx) } @@ -240,11 +240,21 @@ func ReadReplicaConfigured() bool { return len(utils.CoreCfg.DBReadReplicaHost) > 0 && utils.CoreCfg.DBReadReplicaPort != 0 } -func ApplyInventoryWorkspaceFilter(tx *gorm.DB, workspaceIDs []string) *gorm.DB { - if len(workspaceIDs) == 0 { - utils.LogWarn("there should always be some workspaces, at least root workspace") +func ApplyInventoryWorkspaceFilter(tx *gorm.DB, groups map[string]string) *gorm.DB { + if _, ok := groups[utils.KeyGrouped]; !ok { + if _, ok := groups[utils.KeyUngrouped]; ok { + // show only systems with '[]' group + return tx.Where("si.workspaces = '[]'") + } + // return query without WHERE if there are no groups + return tx + } + + db := DB.Where("si.workspaces @> ANY (?::jsonb[])", groups[utils.KeyGrouped]) + if _, ok := groups[utils.KeyUngrouped]; ok { + db = db.Or("si.workspaces = '[]'") } - return tx.Where("si.workspace_id IN (?)", workspaceIDs) + return tx.Where(db) } // LEFT JOIN templates to spatch (system_patch) diff --git a/base/database/utils_test.go b/base/database/utils_test.go index 26cf65d9a..358b3e6c1 100644 --- a/base/database/utils_test.go +++ b/base/database/utils_test.go @@ -11,21 +11,26 @@ var ( // counts of systems from system_inventory (+ system_patch join in Systems()) nGroup1 int64 = 7 nGroup2 int64 = 2 - nUngrouped int64 = 9 + nUngrouped int64 = 7 nAll int64 = 18 ) -var nonExisting = "00000000-0000-0000-3333-000000000000" -var testCases = []map[int64][]string{ - {nGroup1: {"00000000-0000-0000-0000-000000000001"}}, - {nGroup2: {"00000000-0000-0000-0000-000000000002"}}, - {nGroup1 + nGroup2: {"00000000-0000-0000-0000-000000000001", "00000000-0000-0000-0000-000000000002"}}, - {nGroup1 + nUngrouped: {"00000000-0000-0000-0000-000000000001", "00000000-0000-0000-0000-999999999999"}}, - {nUngrouped: {nonExisting, "00000000-0000-0000-0000-999999999999"}}, - {0: {nonExisting}}, - {nUngrouped: {"00000000-0000-0000-0000-999999999999"}}, - {nAll: {"00000000-0000-0000-0000-000000000001", "00000000-0000-0000-0000-000000000002", - "00000000-0000-0000-0000-999999999999"}}, +var testCases = []map[int64]map[string]string{ + {nGroup1: {utils.KeyGrouped: `{"[{\"id\":\"inventory-group-1\"}]"}`}}, + {nGroup2: {utils.KeyGrouped: `{"[{\"id\":\"inventory-group-2\"}]"}`}}, + {nGroup1 + nGroup2: {utils.KeyGrouped: `{"[{\"id\":\"inventory-group-1\"}]","[{\"id\":\"inventory-group-2\"}]"}`}}, + {nGroup1 + nUngrouped: { + utils.KeyGrouped: `{"[{\"id\":\"inventory-group-1\"}]"}`, + utils.KeyUngrouped: "[]", + }}, + {nUngrouped: { + utils.KeyGrouped: `{"[{\"id\":\"non-existing-group\"}]"}`, + utils.KeyUngrouped: "[]", + }}, + {0: {utils.KeyGrouped: `{"[{\"id\":\"non-existing-group\"}]"}`}}, + {nUngrouped: {utils.KeyUngrouped: "[]"}}, + {nAll: {}}, + {nAll: nil}, } func TestApplyInventoryWorkspaceFilter(t *testing.T) { @@ -33,11 +38,11 @@ func TestApplyInventoryWorkspaceFilter(t *testing.T) { Configure() for _, tc := range testCases { - for expectedCount, workspaceIDs := range tc { + for expectedCount, groups := range tc { var count int64 ApplyInventoryWorkspaceFilter(DB.Table("system_inventory si"). Joins("JOIN system_patch spatch ON si.id = spatch.system_id AND si.rh_account_id = spatch.rh_account_id"), - workspaceIDs).Count(&count) + groups).Count(&count) assert.Equal(t, expectedCount, count) } } diff --git a/base/inventory/inventory.go b/base/inventory/inventory.go index e2cfcdc31..db615358f 100644 --- a/base/inventory/inventory.go +++ b/base/inventory/inventory.go @@ -2,6 +2,9 @@ package inventory import ( "app/base/types" + "database/sql/driver" + "encoding/json" + "errors" "github.com/google/uuid" ) @@ -83,6 +86,35 @@ type Group struct { Name string `json:"name"` } +// Groups is a slice of Group that implements driver.Valuer and sql.Scanner +// for storing/loading as JSONB in the database (e.g. system_inventory.workspaces). +type Groups []Group + +// Value implements driver.Valuer for GORM: marshal to JSON for DB write. +func (g *Groups) Value() (driver.Value, error) { + if g == nil { + return nil, nil + } + return json.Marshal(g) +} + +// Scan implements sql.Scanner for GORM: unmarshal from JSON on DB read. +func (g *Groups) Scan(value interface{}) error { + if value == nil { + *g = nil + return nil + } + b, ok := value.([]byte) + if !ok { + return errors.New("inventory.Groups: type assertion to []byte failed") + } + if len(b) == 0 { + *g = nil + return nil + } + return json.Unmarshal(b, g) +} + type Workloads struct { Sap SapWorkload `json:"sap,omitempty"` Ansible AnsibleWorkload `json:"ansible,omitempty"` diff --git a/base/models/models.go b/base/models/models.go index 65d65b864..25771cc6d 100644 --- a/base/models/models.go +++ b/base/models/models.go @@ -1,6 +1,7 @@ package models import ( + "app/base/inventory" "time" "github.com/google/uuid" @@ -70,10 +71,9 @@ type SystemInventory struct { BuiltPkgcache bool `gorm:"column:built_pkgcache"` Arch *string Bootc bool - Tags []byte `gorm:"column:tags"` - Created time.Time // set by trigger system_platform_insert_trigger - WorkspaceID *uuid.UUID `gorm:"column:workspace_id"` - WorkspaceName *string `gorm:"column:workspace_name"` + Tags []byte `gorm:"column:tags"` + Created time.Time // set by trigger system_platform_insert_trigger + Workspaces *inventory.Groups `gorm:"column:workspaces"` StaleTimestamp *time.Time StaleWarningTimestamp *time.Time CulledTimestamp *time.Time diff --git a/base/utils/gin.go b/base/utils/gin.go index 58501973e..73e622384 100644 --- a/base/utils/gin.go +++ b/base/utils/gin.go @@ -13,12 +13,14 @@ import ( ) const ( - KeyApiver = "apiver" - KeyAccount = "account" - KeyOrgID = "org_id" - KeyUser = "user" - KeySystem = "system_cn" - KeyInventoryWorkspaces = "workspaceIDs" + KeyApiver = "apiver" + KeyAccount = "account" + KeyOrgID = "org_id" + KeyUser = "user" + KeySystem = "system_cn" + KeyInventoryGroups = "inventoryGroups" + KeyGrouped = "grouped" + KeyUngrouped = "ungrouped" // ReadHeaderTimeout same as nginx default ReadHeaderTimeout = 60 * time.Second ) diff --git a/database_admin/migrations/153_simplify_workspaces.up.sql b/database_admin/migrations/153_simplify_workspaces.up.sql deleted file mode 100644 index 970fe64f5..000000000 --- a/database_admin/migrations/153_simplify_workspaces.up.sql +++ /dev/null @@ -1,13 +0,0 @@ -ALTER TABLE system_inventory - ADD COLUMN workspace_id UUID, - ADD COLUMN workspace_name TEXT CHECK (NOT empty(workspace_name)); - -UPDATE system_inventory - SET workspace_id = (workspaces->0->>'id')::UUID, - workspace_name = workspaces->0->>'name'; - -CREATE INDEX IF NOT EXISTS system_inventory_workspace_id_index ON system_inventory (workspace_id); -CREATE INDEX IF NOT EXISTS system_inventory_workspace_name_index ON system_inventory (workspace_name); - -ALTER TABLE system_inventory - DROP COLUMN workspaces; diff --git a/database_admin/schema/create_schema.sql b/database_admin/schema/create_schema.sql index 068cbbcc5..28a57e442 100644 --- a/database_admin/schema/create_schema.sql +++ b/database_admin/schema/create_schema.sql @@ -7,7 +7,7 @@ CREATE TABLE IF NOT EXISTS schema_migrations INSERT INTO schema_migrations -VALUES (153, false); +VALUES (152, false); -- --------------------------------------------------------------------------- -- Functions @@ -592,8 +592,7 @@ CREATE TABLE IF NOT EXISTS system_inventory ansible_workload_controller_version TEXT CHECK (NOT empty(ansible_workload_controller_version)), mssql_workload BOOLEAN NOT NULL DEFAULT false, mssql_workload_version TEXT CHECK (NOT empty(mssql_workload_version)), - workspace_id UUID, - workspace_name TEXT CHECK (NOT empty(workspace_name)), + workspaces JSONB, PRIMARY KEY (rh_account_id, id), UNIQUE (rh_account_id, inventory_id) ) PARTITION BY HASH (rh_account_id); @@ -625,8 +624,7 @@ SELECT create_table_partition_triggers('system_inventory_on_update', CREATE INDEX IF NOT EXISTS system_inventory_inventory_id_idx ON system_inventory (inventory_id); CREATE INDEX IF NOT EXISTS system_inventory_tags_index ON system_inventory USING GIN (tags JSONB_PATH_OPS); CREATE INDEX IF NOT EXISTS system_inventory_stale_timestamp_index ON system_inventory (stale_timestamp); -CREATE INDEX IF NOT EXISTS system_inventory_workspace_id_index ON system_inventory (workspace_id); -CREATE INDEX IF NOT EXISTS system_inventory_workspace_name_index ON system_inventory (workspace_name); +CREATE INDEX IF NOT EXISTS system_inventory_workspaces_index ON system_inventory USING GIN (workspaces); CREATE TABLE IF NOT EXISTS deleted_system ( diff --git a/dev/test_data.sql b/dev/test_data.sql index 386e7d17a..c4fb5f544 100644 --- a/dev/test_data.sql +++ b/dev/test_data.sql @@ -24,13 +24,13 @@ INSERT INTO template (id, rh_account_id, uuid, environment_id, name, description (3, 1, '99900000-0000-0000-0000-000000000003', '99900000000000000000000000000003', 'temp3-1', NULL, '{"to_time": "2000-01-01T00:00:00+00:00"}', 'x86_64', '8', 'user3'), (4, 3, '99900000-0000-0000-0000-000000000004', '99900000000000000000000000000004', 'temp4-3', 'desc4', '{"to_time": "2000-01-01T00:00:00+00:00"}', 'x86_64', '8', 'user4'); -INSERT INTO system_inventory (id, inventory_id, rh_account_id, vmaas_json, json_checksum, last_upload, display_name, reporter_id, arch, tags, created, stale_timestamp, stale_warning_timestamp, workspace_id, workspace_name, os_name, os_major, os_minor, rhsm_version, subscription_manager_id, sap_workload, sap_workload_sids, mssql_workload, mssql_workload_version) VALUES -(1, '00000000-0000-0000-0000-000000000001', 1, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2020-09-22 12:00:00-04', '00000000-0000-0000-0000-000000000001', 1, 'x86_64', '[{"key": "k1", "value": "val1", "namespace": "ns1"},{"key": "k2", "value": "val2", "namespace": "ns1"}]', '2018-08-26 12:00:00-04', '2018-08-26 12:00:00-04', '2018-09-02 12:00:00-04', '00000000-0000-0000-0000-000000000001', 'group1', 'RHEL', 8, 10, '8.10', NULL, true, ARRAY['ABC', 'DEF', 'GHI'], false, NULL), -(2, '00000000-0000-0000-0000-000000000002', 1, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2018-09-22 12:00:00-04', '00000000-0000-0000-0000-000000000002', 1, 'x86_64', '[{"key": "k1", "value": "val1", "namespace": "ns1"},{"key": "k2", "value": "val2", "namespace": "ns1"},{"key": "k3", "value": "val3", "namespace": "ns1"}]', '2018-08-26 12:00:00-04', '2018-08-26 12:00:00-04', '2018-09-02 12:00:00-04', '00000000-0000-0000-0000-000000000001', 'group1', 'RHEL', 8, 1, '8.1', NULL, true, ARRAY['ABC'], false, NULL), -(3, '00000000-0000-0000-0000-000000000003', 1, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2018-09-18 12:00:00-04', '00000000-0000-0000-0000-000000000003', 1, 'x86_64', '[{"key": "k1", "value": "val1", "namespace": "ns1"}, {"key": "k3", "value": "val4", "namespace": "ns1"}]', '2018-08-26 12:00:00-04', '2018-08-26 12:00:00-04', '2018-09-02 12:00:00-04', '00000000-0000-0000-0000-000000000001', 'group1', 'RHEL', 8, 1, '8.0', NULL, true, NULL, false, NULL), -(4, '00000000-0000-0000-0000-000000000004', 1, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2018-09-18 12:00:00-04', '00000000-0000-0000-0000-000000000004', 1, 'x86_64', '[{"key": "k3", "value": "val4", "namespace": "ns1"}]', '2018-08-26 12:00:00-04', '2018-08-26 12:00:00-04', '2018-09-02 12:00:00-04', '00000000-0000-0000-0000-000000000001', 'group1', 'RHEL', 8, 2, '8.3', 'cccccccc-0000-0000-0001-000000000004', true, NULL, false, NULL), -(5, '00000000-0000-0000-0000-000000000005', 1, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2018-09-18 12:00:00-04', '00000000-0000-0000-0000-000000000005', 1, 'x86_64', '[{"key": "k1", "value": "val1", "namespace": "ns1"}]', '2018-08-26 12:00:00-04', '2018-08-26 12:00:00-04', '2018-09-02 12:00:00-04', '00000000-0000-0000-0000-000000000001', 'group1', 'RHEL', 8, 3, '8.3', 'cccccccc-0000-0000-0001-000000000005', true, NULL, false, NULL), -(6, '00000000-0000-0000-0000-000000000006', 1, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2018-08-26 12:00:00-04', '00000000-0000-0000-0000-000000000006', 1, 'x86_64', '[{"key": "k1", "value": "val1", "namespace": "ns1"}]', '2018-08-26 12:00:00-04', '2018-08-26 12:00:00-04', '2018-09-02 12:00:00-04', '00000000-0000-0000-0000-000000000001', 'group1', 'RHEL', 7, 3, '7.3', NULL, true, NULL, true, '15.3.0'); +INSERT INTO system_inventory (id, inventory_id, rh_account_id, vmaas_json, json_checksum, last_upload, display_name, reporter_id, arch, tags, created, stale_timestamp, stale_warning_timestamp, workspaces, os_name, os_major, os_minor, rhsm_version, subscription_manager_id, sap_workload, sap_workload_sids, mssql_workload, mssql_workload_version) VALUES +(1, '00000000-0000-0000-0000-000000000001', 1, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2020-09-22 12:00:00-04', '00000000-0000-0000-0000-000000000001', 1, 'x86_64', '[{"key": "k1", "value": "val1", "namespace": "ns1"},{"key": "k2", "value": "val2", "namespace": "ns1"}]', '2018-08-26 12:00:00-04', '2018-08-26 12:00:00-04', '2018-09-02 12:00:00-04', '[{"id": "inventory-group-1", "name": "group1"}]', 'RHEL', 8, 10, '8.10', NULL, true, ARRAY['ABC', 'DEF', 'GHI'], false, NULL), +(2, '00000000-0000-0000-0000-000000000002', 1, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2018-09-22 12:00:00-04', '00000000-0000-0000-0000-000000000002', 1, 'x86_64', '[{"key": "k1", "value": "val1", "namespace": "ns1"},{"key": "k2", "value": "val2", "namespace": "ns1"},{"key": "k3", "value": "val3", "namespace": "ns1"}]', '2018-08-26 12:00:00-04', '2018-08-26 12:00:00-04', '2018-09-02 12:00:00-04', '[{"id": "inventory-group-1", "name": "group1"}]', 'RHEL', 8, 1, '8.1', NULL, true, ARRAY['ABC'], false, NULL), +(3, '00000000-0000-0000-0000-000000000003', 1, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2018-09-18 12:00:00-04', '00000000-0000-0000-0000-000000000003', 1, 'x86_64', '[{"key": "k1", "value": "val1", "namespace": "ns1"}, {"key": "k3", "value": "val4", "namespace": "ns1"}]', '2018-08-26 12:00:00-04', '2018-08-26 12:00:00-04', '2018-09-02 12:00:00-04', '[{"id": "inventory-group-1", "name": "group1"}]', 'RHEL', 8, 1, '8.0', NULL, true, NULL, false, NULL), +(4, '00000000-0000-0000-0000-000000000004', 1, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2018-09-18 12:00:00-04', '00000000-0000-0000-0000-000000000004', 1, 'x86_64', '[{"key": "k3", "value": "val4", "namespace": "ns1"}]', '2018-08-26 12:00:00-04', '2018-08-26 12:00:00-04', '2018-09-02 12:00:00-04', '[{"id": "inventory-group-1", "name": "group1"}]', 'RHEL', 8, 2, '8.3', 'cccccccc-0000-0000-0001-000000000004', true, NULL, false, NULL), +(5, '00000000-0000-0000-0000-000000000005', 1, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2018-09-18 12:00:00-04', '00000000-0000-0000-0000-000000000005', 1, 'x86_64', '[{"key": "k1", "value": "val1", "namespace": "ns1"}]', '2018-08-26 12:00:00-04', '2018-08-26 12:00:00-04', '2018-09-02 12:00:00-04', '[{"id": "inventory-group-1", "name": "group1"}]', 'RHEL', 8, 3, '8.3', 'cccccccc-0000-0000-0001-000000000005', true, NULL, false, NULL), +(6, '00000000-0000-0000-0000-000000000006', 1, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2018-08-26 12:00:00-04', '00000000-0000-0000-0000-000000000006', 1, 'x86_64', '[{"key": "k1", "value": "val1", "namespace": "ns1"}]', '2018-08-26 12:00:00-04', '2018-08-26 12:00:00-04', '2018-09-02 12:00:00-04', '[{"id": "inventory-group-1", "name": "group1"}]', 'RHEL', 7, 3, '7.3', NULL, true, NULL, true, '15.3.0'); INSERT INTO system_patch (system_id, rh_account_id, last_evaluation, third_party, template_id) VALUES (1, 1, '2018-09-22 12:00:00-04', true , 1), (2, 1, '2018-09-22 12:00:00-04', false, 1), @@ -39,17 +39,17 @@ INSERT INTO system_patch (system_id, rh_account_id, last_evaluation, third_party (5, 1, '2018-09-22 12:00:00-04', false, NULL), (6, 1, '2018-09-22 12:00:00-04', false, NULL); -INSERT INTO system_inventory (id, inventory_id, rh_account_id, vmaas_json, json_checksum, last_updated, unchanged_since, last_upload, display_name, arch, tags, created, stale_timestamp, stale_warning_timestamp, workspace_id, workspace_name, os_name, os_major, rhsm_version, subscription_manager_id, sap_workload, ansible_workload, ansible_workload_controller_version) VALUES -(7, '00000000-0000-0000-0000-000000000007', 1, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2018-10-04 14:13:12-04', '2018-09-22 12:00:00-04', '2018-08-26 12:00:00-04', '00000000-0000-0000-0000-000000000007', 'x86_64', '[{"key": "k1", "value": "val1", "namespace": "ns1"}]', '2018-08-26 12:00:00-04', '2018-08-26 12:00:00-04', '2018-09-02 12:00:00-04', '00000000-0000-0000-0000-000000000002', 'group2', 'RHEL', 8, '8.x', 'cccccccc-0000-0000-0001-000000000007', true, true, '1.0'); +INSERT INTO system_inventory (id, inventory_id, rh_account_id, vmaas_json, json_checksum, last_updated, unchanged_since, last_upload, display_name, arch, tags, created, stale_timestamp, stale_warning_timestamp, workspaces, os_name, os_major, rhsm_version, subscription_manager_id, sap_workload, ansible_workload, ansible_workload_controller_version) VALUES +(7, '00000000-0000-0000-0000-000000000007', 1, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2018-10-04 14:13:12-04', '2018-09-22 12:00:00-04', '2018-08-26 12:00:00-04', '00000000-0000-0000-0000-000000000007', 'x86_64', '[{"key": "k1", "value": "val1", "namespace": "ns1"}]', '2018-08-26 12:00:00-04', '2018-08-26 12:00:00-04', '2018-09-02 12:00:00-04', '[{"id": "inventory-group-2", "name": "group2"}]', 'RHEL', 8, '8.x', 'cccccccc-0000-0000-0001-000000000007', true, true, '1.0'); INSERT INTO system_patch (system_id, rh_account_id) VALUES (7, 1); -INSERT INTO system_inventory (id, inventory_id, rh_account_id, vmaas_json, json_checksum, last_upload, display_name, arch, tags, created, stale_timestamp, stale_warning_timestamp, workspace_id, workspace_name, os_name, os_major, os_minor, rhsm_version, subscription_manager_id, sap_workload) VALUES -( 8, '00000000-0000-0000-0000-000000000008', 1, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2018-08-26 12:00:00-04', '00000000-0000-0000-0000-000000000008', 'x86_64', '[{"key": "k1", "value": "val1", "namespace": "ns1"}]', '2018-08-26 12:00:00-04', '2018-08-26 12:00:00-04', '2018-09-02 12:00:00-04', '00000000-0000-0000-0000-000000000002', 'group2', 'RHEL', 8, 3, '8.3', 'cccccccc-0000-0000-0001-000000000008', true), -( 9, '00000000-0000-0000-0000-000000000009', 2, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2018-01-22 12:00:00-04', '00000000-0000-0000-0000-000000000009', 'x86_64', '[{"key": "k1", "value": "val1", "namespace": "ns1"}]', '2018-08-26 12:00:00-04', '2018-08-26 12:00:00-04', '2018-09-02 12:00:00-04', '00000000-0000-0000-0000-999999999999', 'root-ws', 'RHEL', 8, 1, '8.1', NULL, true), -(10, '00000000-0000-0000-0000-000000000010', 2, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2018-01-22 12:00:00-04', '00000000-0000-0000-0000-000000000010', 'x86_64', '[{"key": "k1", "value": "val1", "namespace": "ns1"}]', '2018-08-26 12:00:00-04', '2018-08-26 12:00:00-04', '2018-09-02 12:00:00-04', '00000000-0000-0000-0000-999999999999', 'root-ws', 'RHEL', 8, 2, '8.2', NULL, true), -(11, '00000000-0000-0000-0000-000000000011', 2, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2018-01-22 12:00:00-04', '00000000-0000-0000-0000-000000000011', 'x86_64', '[{"key": "k1", "value": "val1", "namespace": "ns1"}]', '2018-08-26 12:00:00-04', '2018-08-26 12:00:00-04', '2018-09-02 12:00:00-04', '00000000-0000-0000-0000-999999999999', 'root-ws', 'RHEL', 8, 3, '8.3', NULL, true), -(12, '00000000-0000-0000-0000-000000000012', 3, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2018-01-22 12:00:00-04', '00000000-0000-0000-0000-000000000012', 'x86_64', '[{"key": "k1", "value": "val1", "namespace": "ns1"}]', '2018-08-26 12:00:00-04', '2018-08-26 12:00:00-04', '2018-09-02 12:00:00-04', '00000000-0000-0000-0000-999999999999', 'root-ws', 'RHEL', 8, 1, '8.1', NULL, true); +INSERT INTO system_inventory (id, inventory_id, rh_account_id, vmaas_json, json_checksum, last_upload, display_name, arch, tags, created, stale_timestamp, stale_warning_timestamp, workspaces, os_name, os_major, os_minor, rhsm_version, subscription_manager_id, sap_workload) VALUES +( 8, '00000000-0000-0000-0000-000000000008', 1, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2018-08-26 12:00:00-04', '00000000-0000-0000-0000-000000000008', 'x86_64', '[{"key": "k1", "value": "val1", "namespace": "ns1"}]', '2018-08-26 12:00:00-04', '2018-08-26 12:00:00-04', '2018-09-02 12:00:00-04', '[{"id": "inventory-group-2", "name": "group2"}]', 'RHEL', 8, 3, '8.3', 'cccccccc-0000-0000-0001-000000000008', true), +( 9, '00000000-0000-0000-0000-000000000009', 2, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2018-01-22 12:00:00-04', '00000000-0000-0000-0000-000000000009', 'x86_64', '[{"key": "k1", "value": "val1", "namespace": "ns1"}]', '2018-08-26 12:00:00-04', '2018-08-26 12:00:00-04', '2018-09-02 12:00:00-04', NULL, 'RHEL', 8, 1, '8.1', NULL, true), +(10, '00000000-0000-0000-0000-000000000010', 2, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2018-01-22 12:00:00-04', '00000000-0000-0000-0000-000000000010', 'x86_64', '[{"key": "k1", "value": "val1", "namespace": "ns1"}]', '2018-08-26 12:00:00-04', '2018-08-26 12:00:00-04', '2018-09-02 12:00:00-04', NULL, 'RHEL', 8, 2, '8.2', NULL, true), +(11, '00000000-0000-0000-0000-000000000011', 2, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2018-01-22 12:00:00-04', '00000000-0000-0000-0000-000000000011', 'x86_64', '[{"key": "k1", "value": "val1", "namespace": "ns1"}]', '2018-08-26 12:00:00-04', '2018-08-26 12:00:00-04', '2018-09-02 12:00:00-04', '[]', 'RHEL', 8, 3, '8.3', NULL, true), +(12, '00000000-0000-0000-0000-000000000012', 3, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2018-01-22 12:00:00-04', '00000000-0000-0000-0000-000000000012', 'x86_64', '[{"key": "k1", "value": "val1", "namespace": "ns1"}]', '2018-08-26 12:00:00-04', '2018-08-26 12:00:00-04', '2018-09-02 12:00:00-04', '[]', 'RHEL', 8, 1, '8.1', NULL, true); INSERT INTO system_patch (system_id, rh_account_id, last_evaluation, packages_installed, packages_installable, packages_applicable) VALUES ( 8, 1, '2018-09-22 12:00:00-04', 0, 0, 0), ( 9, 2, '2018-09-22 12:00:00-04', 0, 0, 0), @@ -57,24 +57,24 @@ INSERT INTO system_patch (system_id, rh_account_id, last_evaluation, packages_in (11, 2, '2018-09-22 12:00:00-04', 0, 0, 0), (12, 3, '2018-09-22 12:00:00-04', 2, 2, 2); -INSERT INTO system_inventory (id, inventory_id, rh_account_id, vmaas_json, json_checksum, last_upload, display_name, yum_updates, tags, created, stale_timestamp, stale_warning_timestamp, workspace_id, workspace_name, os_name, os_major, os_minor, rhsm_version, sap_workload) VALUES -(13, '00000000-0000-0000-0000-000000000013', 3, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2018-01-22 12:00:00-04', '00000000-0000-0000-0000-000000000013', NULL, '[{"key": "k1", "value": "val1", "namespace": "ns1"}]', '2018-08-26 12:00:00-04', '2018-08-26 12:00:00-04', '2018-09-02 12:00:00-04', '00000000-0000-0000-0000-999999999999', 'root-ws', 'RHEL', 8, 2, '8.2', true), -(14, '00000000-0000-0000-0000-000000000014', 3, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2018-01-22 12:00:00-04', '00000000-0000-0000-0000-000000000014', NULL, '[{"key": "k1", "value": "val1", "namespace": "ns1"}]', '2018-08-26 12:00:00-04', '2018-08-26 12:00:00-04', '2018-09-02 12:00:00-04', '00000000-0000-0000-0000-999999999999', 'root-ws', 'RHEL', 8, 3, NULL, true), -(15, '00000000-0000-0000-0000-000000000015', 3, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2018-01-22 12:00:00-04', '00000000-0000-0000-0000-000000000015', '{"update_list": {"suricata-0:6.0.3-2.fc35.i686": {"available_updates": [{"erratum": "RHSA-2021:3801", "basearch": "i686", "releasever": "ser1", "repository": "group_oisf:suricata-6.0", "package": "suricata-0:6.0.4-2.fc35.i686"}]}}, "basearch": "i686", "releasever": "ser1"}', '[{"key": "k3", "value": "val4", "namespace": "ns1"}]', '2018-08-26 12:00:00-04', '2018-08-26 12:00:00-04', '2018-09-02 12:00:00-04', '00000000-0000-0000-0000-999999999999', 'root-ws', 'RHEL', 8, 1, '8.1', false); +INSERT INTO system_inventory (id, inventory_id, rh_account_id, vmaas_json, json_checksum, last_upload, display_name, yum_updates, tags, created, stale_timestamp, stale_warning_timestamp, workspaces, os_name, os_major, os_minor, rhsm_version, sap_workload) VALUES +(13, '00000000-0000-0000-0000-000000000013', 3, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2018-01-22 12:00:00-04', '00000000-0000-0000-0000-000000000013', NULL, '[{"key": "k1", "value": "val1", "namespace": "ns1"}]', '2018-08-26 12:00:00-04', '2018-08-26 12:00:00-04', '2018-09-02 12:00:00-04', '[]', 'RHEL', 8, 2, '8.2', true), +(14, '00000000-0000-0000-0000-000000000014', 3, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2018-01-22 12:00:00-04', '00000000-0000-0000-0000-000000000014', NULL, '[{"key": "k1", "value": "val1", "namespace": "ns1"}]', '2018-08-26 12:00:00-04', '2018-08-26 12:00:00-04', '2018-09-02 12:00:00-04', '[]', 'RHEL', 8, 3, NULL, true), +(15, '00000000-0000-0000-0000-000000000015', 3, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2018-01-22 12:00:00-04', '00000000-0000-0000-0000-000000000015', '{"update_list": {"suricata-0:6.0.3-2.fc35.i686": {"available_updates": [{"erratum": "RHSA-2021:3801", "basearch": "i686", "releasever": "ser1", "repository": "group_oisf:suricata-6.0", "package": "suricata-0:6.0.4-2.fc35.i686"}]}}, "basearch": "i686", "releasever": "ser1"}', '[{"key": "k3", "value": "val4", "namespace": "ns1"}]', '2018-08-26 12:00:00-04', '2018-08-26 12:00:00-04', '2018-09-02 12:00:00-04', '[]', 'RHEL', 8, 1, '8.1', false); INSERT INTO system_patch (system_id, rh_account_id, last_evaluation, packages_installed) VALUES (13, 3, '2018-09-22 12:00:00-04', 1), (14, 3, '2018-09-22 12:00:00-04', 0), (15, 3, '2018-09-22 12:00:00-04', 0); -INSERT INTO system_inventory (id, inventory_id, rh_account_id, vmaas_json, json_checksum, last_upload, display_name, tags, created, stale_timestamp, stale_warning_timestamp, workspace_id, workspace_name, os_name, os_major, os_minor, rhsm_version, ansible_workload, ansible_workload_controller_version, mssql_workload, mssql_workload_version) VALUES -(16, '00000000-0000-0000-0000-000000000016', 3, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2018-01-22 12:00:00-04', '00000000-0000-0000-0000-000000000016', '[]', '2018-08-26 12:00:00-04', '2018-08-26 12:00:00-04', '2018-09-02 12:00:00-04', '00000000-0000-0000-0000-999999999999', 'root-ws', 'RHEL', 8, 2, '8.2', false, NULL, false, NULL), -(17, '00000000-0000-0000-0000-000000000017', 1, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2018-01-22 12:00:00-04', '00000000-0000-0000-0000-000000000017', '[]', '2018-08-26 12:00:00-04', '2018-08-26 12:00:00-04', '2018-09-02 12:00:00-04', '00000000-0000-0000-0000-999999999999', 'root-ws', 'RHEL', 8, 1, '8.1', true, '1.0', true, '15.3.0'); +INSERT INTO system_inventory (id, inventory_id, rh_account_id, vmaas_json, json_checksum, last_upload, display_name, tags, created, stale_timestamp, stale_warning_timestamp, workspaces, os_name, os_major, os_minor, rhsm_version, ansible_workload, ansible_workload_controller_version, mssql_workload, mssql_workload_version) VALUES +(16, '00000000-0000-0000-0000-000000000016', 3, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2018-01-22 12:00:00-04', '00000000-0000-0000-0000-000000000016', '[]', '2018-08-26 12:00:00-04', '2018-08-26 12:00:00-04', '2018-09-02 12:00:00-04', '[]', 'RHEL', 8, 2, '8.2', false, NULL, false, NULL), +(17, '00000000-0000-0000-0000-000000000017', 1, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2018-01-22 12:00:00-04', '00000000-0000-0000-0000-000000000017', '[]', '2018-08-26 12:00:00-04', '2018-08-26 12:00:00-04', '2018-09-02 12:00:00-04', '[]', 'RHEL', 8, 1, '8.1', true, '1.0', true, '15.3.0'); INSERT INTO system_patch (system_id, rh_account_id, last_evaluation, packages_installed, packages_installable, packages_applicable, template_id) VALUES (16, 3, '2018-09-22 12:00:00-04', 1, 1, 1, 4), (17, 1, '2018-09-22 12:00:00-04', 2, 2, 2, NULL); -INSERT INTO system_inventory (id, inventory_id, rh_account_id, vmaas_json, json_checksum, last_upload, display_name, reporter_id, arch, tags, created, stale_timestamp, stale_warning_timestamp, workspace_id, workspace_name, os_name, os_major, os_minor, rhsm_version, subscription_manager_id, sap_workload) VALUES -(18, '00000000-0000-0000-0000-000000000018', 1, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2020-09-22 12:00:00-04', '00000000-0000-0000-0000-000000000018', 1, 'x86_64', '[{"key": "k3", "value": "val4", "namespace": "ns1"}]', '2018-08-26 12:00:00-04', '2018-08-26 12:00:00-04', '2018-09-02 12:00:00-04', '00000000-0000-0000-0000-000000000001', 'group1', 'RHEL', 8, 2, '8.3', '99999999-9999-9999-9999-999999999404', true); +INSERT INTO system_inventory (id, inventory_id, rh_account_id, vmaas_json, json_checksum, last_upload, display_name, reporter_id, arch, tags, created, stale_timestamp, stale_warning_timestamp, workspaces, os_name, os_major, os_minor, rhsm_version, subscription_manager_id, sap_workload) VALUES +(18, '00000000-0000-0000-0000-000000000018', 1, '{ "package_list": [ "kernel-2.6.32-696.20.1.el6.x86_64" ], "repository_list": [ "rhel-6-server-rpms" ] }', '1', '2020-09-22 12:00:00-04', '00000000-0000-0000-0000-000000000018', 1, 'x86_64', '[{"key": "k3", "value": "val4", "namespace": "ns1"}]', '2018-08-26 12:00:00-04', '2018-08-26 12:00:00-04', '2018-09-02 12:00:00-04', '[{"id": "inventory-group-1", "name": "group1"}]', 'RHEL', 8, 2, '8.3', '99999999-9999-9999-9999-999999999404', true); INSERT INTO system_patch (system_id, rh_account_id, last_evaluation, third_party) VALUES (18, 1, '2018-09-22 12:00:00-04', true); diff --git a/docs/v3/openapi.json b/docs/v3/openapi.json index fbe5238ba..5ac54dbc4 100644 --- a/docs/v3/openapi.json +++ b/docs/v3/openapi.json @@ -6825,12 +6825,6 @@ }, "template_uuid": { "type": "string" - }, - "workspace_id": { - "type": "string" - }, - "workspace_name": { - "type": "string" } } }, @@ -6910,12 +6904,6 @@ }, "template_uuid": { "type": "string" - }, - "workspace_id": { - "type": "string" - }, - "workspace_name": { - "type": "string" } } }, @@ -7223,12 +7211,6 @@ }, "update_status": { "type": "string" - }, - "workspace_id": { - "type": "string" - }, - "workspace_name": { - "type": "string" } } }, @@ -7517,12 +7499,6 @@ }, "template_uuid": { "type": "string" - }, - "workspace_id": { - "type": "string" - }, - "workspace_name": { - "type": "string" } } }, @@ -7669,12 +7645,6 @@ }, "template_uuid": { "type": "string" - }, - "workspace_id": { - "type": "string" - }, - "workspace_name": { - "type": "string" } } }, @@ -7806,12 +7776,6 @@ }, "third_party": { "type": "boolean" - }, - "workspace_id": { - "type": "string" - }, - "workspace_name": { - "type": "string" } } }, @@ -8128,12 +8092,6 @@ "items": { "$ref": "#/components/schemas/controllers.SystemTag" } - }, - "workspace_id": { - "type": "string" - }, - "workspace_name": { - "type": "string" } } }, @@ -8206,12 +8164,6 @@ "items": { "$ref": "#/components/schemas/controllers.SystemTag" } - }, - "workspace_id": { - "type": "string" - }, - "workspace_name": { - "type": "string" } } }, diff --git a/listener/common_test.go b/listener/common_test.go index 883f4c5c3..3df43e157 100644 --- a/listener/common_test.go +++ b/listener/common_test.go @@ -86,7 +86,7 @@ func assertSystemInDB(t *testing.T, inventoryID string, rhAccountID *int, report // assertSystemInventoryProfileMatchesHost checks host-derived system_inventory columns written by // storeOrUpdateSysPlatform (must stay in sync on ON CONFLICT DO UPDATE, not only on first insert). -// nolint: unparam,funlen +// nolint: unparam func assertSystemInventoryProfileMatchesHost(t *testing.T, inventoryID string, host *Host) { t.Helper() var inv models.SystemInventory @@ -94,18 +94,8 @@ func assertSystemInventoryProfileMatchesHost(t *testing.T, inventoryID string, h assert.JSONEq(t, string(utils.MarshalNilToJSONB(host.Tags)), string(inv.Tags)) - if hostWorkspaceID := host.Groups[0].ID; hostWorkspaceID != "" { - require.NotNil(t, inv.WorkspaceID) - assert.Equal(t, hostWorkspaceID, inv.WorkspaceID.String()) - } else { - require.Nil(t, inv.WorkspaceID) - } - if hostWorkspaceName := host.Groups[0].Name; hostWorkspaceName != "" { - require.NotNil(t, inv.WorkspaceName) - assert.Equal(t, hostWorkspaceName, *inv.WorkspaceName) - } else { - require.Nil(t, inv.WorkspaceName) - } + require.NotNil(t, inv.Workspaces) + assert.Equal(t, host.Groups, []inventory.Group(*inv.Workspaces)) if host.SystemProfile.OperatingSystem.Name != "" { require.NotNil(t, inv.OSName) @@ -194,7 +184,7 @@ func createTestUploadEvent(orgID, inventoryID, reporter string, packages, yum bo reporter: {LastCheckIn: types.Rfc3339TimestampWithZ(now)}, }, Tags: []byte(`{"namespace": "insights-client","key": "env","value": "prod"}`), - Groups: []inventory.Group{{ID: "00000000-0000-0000-0000-000000000003", Name: "group3"}}, + Groups: []inventory.Group{{ID: "group1"}}, SystemProfile: inventory.SystemProfile{ OperatingSystem: inventory.OperatingSystem{ Name: "RHEL", diff --git a/listener/upload.go b/listener/upload.go index 8abefa634..9d979994c 100644 --- a/listener/upload.go +++ b/listener/upload.go @@ -22,7 +22,6 @@ import ( "strings" "time" - "github.com/google/uuid" "github.com/lib/pq" stdErrors "errors" @@ -335,8 +334,7 @@ func updateSystemPlatform(tx *gorm.DB, accountID int, host *Host, "arch", "bootc", "tags", - "workspace_id", - "workspace_name", + "workspaces", "os_name", "os_major", "os_minor", @@ -358,26 +356,7 @@ func updateSystemPlatform(tx *gorm.DB, accountID int, host *Host, isBootc := len(host.SystemProfile.BootcStatus.Booted.Image) > 0 updatesReqJSONString := string(updatesReqJSON) - var workspaceID *uuid.UUID - var workspaceName *string - if l := len(host.Groups); l > 0 { - workspace := host.Groups[0] - uuid, err := uuid.Parse(workspace.ID) - if err != nil { - utils.LogError("workspaceID", workspace.ID, "invalid workspace UUID") - return nil, errors.New("received invalid workspace UUID") - } - workspaceID = &uuid - if workspace.Name != "" { - workspaceName = &workspace.Name - } - if l != 1 { - utils.LogWarn( - "host_id", host.ID, "org_id", host.OrgID, "workspaces", host.Groups, - "received a host with multiple workspaces", - ) - } - } + hostWorkspaces := inventory.Groups(host.Groups) systemPlatform := &models.SystemPlatformV2{ Inventory: models.SystemInventory{ InventoryID: inventoryID, @@ -385,8 +364,7 @@ func updateSystemPlatform(tx *gorm.DB, accountID int, host *Host, DisplayName: displayName, Created: host.Created, Tags: utils.MarshalNilToJSONB(host.Tags), - WorkspaceID: workspaceID, - WorkspaceName: workspaceName, + Workspaces: &hostWorkspaces, VmaasJSON: utils.EmptyToNil(&updatesReqJSONString), JSONChecksum: utils.EmptyToNil(&jsonChecksum), LastUpload: host.GetLastUpload(), diff --git a/listener/upload_test.go b/listener/upload_test.go index 0846a9715..8b75e6d43 100644 --- a/listener/upload_test.go +++ b/listener/upload_test.go @@ -477,8 +477,7 @@ func TestStoreOrUpdateSysPlatform(t *testing.T) { vmaasJSON := "this_is_json" // insert new row hostEvent := createTestUploadEvent("1", id, "puptoo", false, true, "created") - workspaceID := uuid.MustParse(hostEvent.Host.Groups[0].ID) - workspaceName := &hostEvent.Host.Groups[0].Name + hostWorkspaces := inventory.Groups(hostEvent.Host.Groups) inStore := &models.SystemPlatformV2{ Inventory: models.SystemInventory{ InventoryID: "99990000-0000-0000-0000-000000000001", @@ -488,8 +487,7 @@ func TestStoreOrUpdateSysPlatform(t *testing.T) { SatelliteManaged: false, Created: hostEvent.Host.Created, Tags: utils.MarshalNilToJSONB(hostEvent.Host.Tags), - WorkspaceID: &workspaceID, - WorkspaceName: workspaceName, + Workspaces: &hostWorkspaces, OSName: utils.EmptyToNil(&hostEvent.Host.SystemProfile.OperatingSystem.Name), OSMajor: &hostEvent.Host.SystemProfile.OperatingSystem.Major, OSMinor: &hostEvent.Host.SystemProfile.OperatingSystem.Minor, @@ -506,7 +504,7 @@ func TestStoreOrUpdateSysPlatform(t *testing.T) { } err := storeOrUpdateSysPlatform(database.DB, inStore, colsToUpdate) - require.Nil(t, err) + assert.Nil(t, err) var outStore models.SystemInventory assert.NoError(t, database.DB.Where("id = ? AND rh_account_id = ?", inStore.Inventory.ID, inStore.Inventory.RhAccountID). // nolint:lll @@ -532,10 +530,8 @@ func TestStoreOrUpdateSysPlatform(t *testing.T) { assert.Contains(t, string(inventoryAfterInsert.Tags), `"key": "env"`) assert.Contains(t, string(inventoryAfterInsert.Tags), `"value": "prod"`) - require.NotNil(t, inventoryAfterInsert.WorkspaceID) - assert.Equal(t, hostEvent.Host.Groups[0].ID, inventoryAfterInsert.WorkspaceID.String()) - require.NotNil(t, inventoryAfterInsert.WorkspaceName) - assert.Equal(t, hostEvent.Host.Groups[0].Name, *inventoryAfterInsert.WorkspaceName) + require.NotNil(t, inventoryAfterInsert.Workspaces) + assert.Equal(t, hostEvent.Host.Groups, []inventory.Group(*inventoryAfterInsert.Workspaces)) assert.Equal(t, hostEvent.Host.SystemProfile.OperatingSystem.Name, *inventoryAfterInsert.OSName) assert.Equal(t, hostEvent.Host.SystemProfile.OperatingSystem.Major, *inventoryAfterInsert.OSMajor) @@ -573,8 +569,7 @@ func TestStoreOrUpdateSysPlatform(t *testing.T) { SatelliteManaged: true, Created: hostEvent.Host.Created, Tags: utils.MarshalNilToJSONB(hostEvent.Host.Tags), - WorkspaceID: &workspaceID, - WorkspaceName: workspaceName, + Workspaces: &hostWorkspaces, OSName: utils.EmptyToNil(&hostEvent.Host.SystemProfile.OperatingSystem.Name), OSMajor: &hostEvent.Host.SystemProfile.OperatingSystem.Major, OSMinor: &hostEvent.Host.SystemProfile.OperatingSystem.Minor, diff --git a/manager/controllers/advisories.go b/manager/controllers/advisories.go index ba8e020ab..e06c88368 100644 --- a/manager/controllers/advisories.go +++ b/manager/controllers/advisories.go @@ -82,18 +82,16 @@ type AdvisoriesResponse struct { func advisoriesCommon(c *gin.Context) (*gorm.DB, *ListMeta, []string, error) { db := middlewares.DBFromContext(c) account := c.GetInt(utils.KeyAccount) - workspaceIDs := c.GetStringSlice(utils.KeyInventoryWorkspaces) + groups := c.GetStringMapString(utils.KeyInventoryGroups) var query *gorm.DB filters, err := ParseAllFilters(c, AdvisoriesOpts) if err != nil { return nil, nil, nil, err } - // TODO: fix below; the condition is always true since moving from groups to workspaces, - // there will always be at least root workspace - if config.DisableCachedCounts || HasInventoryFilter(filters) || len(workspaceIDs) != 0 { + if config.DisableCachedCounts || HasInventoryFilter(filters) || len(groups) != 0 { middlewares.AdvisoryAccountDataCnt.WithLabelValues("miss").Inc() - query = buildQueryAdvisoriesTagged(db, filters, account, workspaceIDs) + query = buildQueryAdvisoriesTagged(db, filters, account, groups) } else { middlewares.AdvisoryAccountDataCnt.WithLabelValues("hit").Inc() query = buildQueryAdvisories(db, account) @@ -218,8 +216,8 @@ func buildQueryAdvisories(db *gorm.DB, account int) *gorm.DB { return query } -func buildAdvisoryAccountDataQuery(db *gorm.DB, account int, workspaceIDs []string) *gorm.DB { - query := database.SystemAdvisories(db, account, workspaceIDs). +func buildAdvisoryAccountDataQuery(db *gorm.DB, account int, groups map[string]string) *gorm.DB { + query := database.SystemAdvisories(db, account, groups). Select(`sa.advisory_id, si.rh_account_id as rh_account_id, count(si.*) filter (where sa.status_id = 0) as systems_installable, count(si.*) as systems_applicable`). @@ -229,9 +227,9 @@ func buildAdvisoryAccountDataQuery(db *gorm.DB, account int, workspaceIDs []stri return query } -func buildQueryAdvisoriesTagged(db *gorm.DB, filters map[string]FilterData, account int, workspaceIDs []string, +func buildQueryAdvisoriesTagged(db *gorm.DB, filters map[string]FilterData, account int, groups map[string]string, ) *gorm.DB { - subq := buildAdvisoryAccountDataQuery(db, account, workspaceIDs) + subq := buildAdvisoryAccountDataQuery(db, account, groups) subq, _ = ApplyInventoryFilter(filters, subq, "si.inventory_id") query := database.AdvisoryMetadata(db). diff --git a/manager/controllers/advisories_export.go b/manager/controllers/advisories_export.go index a9a7af66a..90e34e933 100644 --- a/manager/controllers/advisories_export.go +++ b/manager/controllers/advisories_export.go @@ -31,7 +31,7 @@ import ( // @Router /export/advisories [get] func AdvisoriesExportHandler(c *gin.Context) { account := c.GetInt(utils.KeyAccount) - workspaceIDs := c.GetStringSlice(utils.KeyInventoryWorkspaces) + groups := c.GetStringMapString(utils.KeyInventoryGroups) filters, err := ParseAllFilters(c, AdvisoriesOpts) if err != nil { return @@ -39,10 +39,8 @@ func AdvisoriesExportHandler(c *gin.Context) { db := middlewares.DBFromContext(c) var query *gorm.DB - // TODO: fix below; the condition is always true since moving from groups to workspaces, - // there will always be at least root workspace - if config.DisableCachedCounts || HasInventoryFilter(filters) || len(workspaceIDs) != 0 { - query = buildQueryAdvisoriesTagged(db, filters, account, workspaceIDs) + if config.DisableCachedCounts || HasInventoryFilter(filters) || len(groups) != 0 { + query = buildQueryAdvisoriesTagged(db, filters, account, groups) } else { query = buildQueryAdvisories(db, account) } diff --git a/manager/controllers/advisory_systems.go b/manager/controllers/advisory_systems.go index f1d8ee2a4..d85a2f5c5 100644 --- a/manager/controllers/advisory_systems.go +++ b/manager/controllers/advisory_systems.go @@ -41,7 +41,6 @@ type AdvisorySystemItemAttributes struct { SystemTimestamps SystemTags SystemGroups - SystemWorkspace BaselineIDAttr BaselineNameAttr TemplateAttibutes @@ -71,7 +70,7 @@ var AdvisorySystemOpts = ListOpts{ func advisorySystemsCommon(c *gin.Context) (*gorm.DB, *ListMeta, []string, error) { account := c.GetInt(utils.KeyAccount) - workspaceIDs := c.GetStringSlice(utils.KeyInventoryWorkspaces) + groups := c.GetStringMapString(utils.KeyInventoryGroups) advisoryName := c.Param("advisory_id") if advisoryName == "" { @@ -93,7 +92,7 @@ func advisorySystemsCommon(c *gin.Context) (*gorm.DB, *ListMeta, []string, error return nil, nil, nil, err } - query := buildAdvisorySystemsQuery(db, account, workspaceIDs, advisoryName) + query := buildAdvisorySystemsQuery(db, account, groups, advisoryName) opts := AdvisorySystemOpts filters, err := ParseAllFilters(c, opts) if err != nil { @@ -270,9 +269,9 @@ func AdvisorySystemsListIDsHandler(c *gin.Context) { c.JSON(http.StatusOK, &resp) } -func buildAdvisorySystemsQuery(db *gorm.DB, account int, workspaceIDs []string, advisoryName string) *gorm.DB { +func buildAdvisorySystemsQuery(db *gorm.DB, account int, groups map[string]string, advisoryName string) *gorm.DB { selectQuery := AdvisorySystemsSelect - query := database.SystemAdvisories(db, account, workspaceIDs, database.JoinTemplates, database.JoinAdvisoryMetadata). + query := database.SystemAdvisories(db, account, groups, database.JoinTemplates, database.JoinAdvisoryMetadata). Select(selectQuery). Joins("LEFT JOIN status st ON sa.status_id = st.id"). Where("am.name = ?", advisoryName). diff --git a/manager/controllers/advisory_systems_export.go b/manager/controllers/advisory_systems_export.go index 30b1c1f74..c63592dfb 100644 --- a/manager/controllers/advisory_systems_export.go +++ b/manager/controllers/advisory_systems_export.go @@ -53,7 +53,7 @@ var AdvisorySystemExportOpts = ListOpts{ // @Router /export/advisories/{advisory_id}/systems [get] func AdvisorySystemsExportHandler(c *gin.Context) { account := c.GetInt(utils.KeyAccount) - workspaceIDs := c.GetStringSlice(utils.KeyInventoryWorkspaces) + groups := c.GetStringMapString(utils.KeyInventoryGroups) advisoryName := c.Param("advisory_id") if advisoryName == "" { @@ -73,7 +73,7 @@ func AdvisorySystemsExportHandler(c *gin.Context) { return } - query := buildAdvisorySystemsQuery(db, account, workspaceIDs, advisoryName) + query := buildAdvisorySystemsQuery(db, account, groups, advisoryName) filters, err := ParseAllFilters(c, AdvisorySystemExportOpts) if err != nil { return diff --git a/manager/controllers/advisory_systems_export_test.go b/manager/controllers/advisory_systems_export_test.go index 0754611b1..8804e8b9e 100644 --- a/manager/controllers/advisory_systems_export_test.go +++ b/manager/controllers/advisory_systems_export_test.go @@ -32,13 +32,12 @@ func TestAdvisorySystemsExportCSV(t *testing.T) { assert.Equal(t, 8, len(lines)) assert.Equal(t, "display_name,last_upload,stale,os,rhsm,stale_timestamp,stale_warning_timestamp,culled_timestamp,created,tags,"+ - "groups,workspace_id,workspace_name,baseline_id,baseline_name,template_name,template_uuid,status,"+ - "satellite_managed,built_pkgcache,id", lines[0]) + "groups,baseline_id,baseline_name,template_name,template_uuid,status,satellite_managed,built_pkgcache,id", lines[0]) assert.Equal(t, "00000000-0000-0000-0000-000000000001,2020-09-22T16:00:00Z,false,RHEL 8.10,8.10,2018-08-26T16:00:00Z,"+ "2018-09-02T16:00:00Z,,2018-08-26T16:00:00Z,\"[{'key':'k1','namespace':'ns1','value':'val1'},"+ - "{'key':'k2','namespace':'ns1','value':'val2'}]\",\"[{'id':'00000000-0000-0000-0000-000000000001',"+ - "'name':'group1'}]\",00000000-0000-0000-0000-000000000001,group1,0,,temp1-1,99900000-0000-0000-0000-000000000001,"+ - "Installable,false,false,00000000-0000-0000-0000-000000000001", + "{'key':'k2','namespace':'ns1','value':'val2'}]\",\"[{'id':'inventory-group-1','name':'group1'}]\","+ + "0,,temp1-1,99900000-0000-0000-0000-000000000001,Installable,false,false,"+ + "00000000-0000-0000-0000-000000000001", lines[1]) } diff --git a/manager/controllers/common_attributes.go b/manager/controllers/common_attributes.go index 2f375e870..964ead642 100644 --- a/manager/controllers/common_attributes.go +++ b/manager/controllers/common_attributes.go @@ -1,11 +1,7 @@ // nolint:lll package controllers -import ( - "time" - - "github.com/google/uuid" -) +import "time" type MetaTotalHelper struct { // a helper to get total number of systems @@ -29,12 +25,7 @@ type SystemTags struct { } type SystemGroups struct { - Groups SystemGroupsList `json:"groups" csv:"groups" query:"CASE WHEN si.workspace_id IS NOT NULL THEN jsonb_build_array(jsonb_build_object('id', si.workspace_id, 'name', si.workspace_name)) ELSE '[]'::jsonb END" order_query:"si.workspace_name"` -} - -type SystemWorkspace struct { - WorkspaceID *uuid.UUID `json:"workspace_id" csv:"workspace_id" query:"si.workspace_id" gorm:"column:workspace_id"` - WorkspaceName *string `json:"workspace_name" csv:"workspace_name" query:"si.workspace_name" gorm:"column:workspace_name"` + Groups SystemGroupsList `json:"groups" csv:"groups" query:"si.workspaces" gorm:"column:groups" order_query:"si.workspaces->0->>'name'"` } // baseline attributes are obsoleted and we keep them only for backward API compatibility diff --git a/manager/controllers/package_systems.go b/manager/controllers/package_systems.go index bd7279298..c948e2242 100644 --- a/manager/controllers/package_systems.go +++ b/manager/controllers/package_systems.go @@ -40,7 +40,6 @@ type PackageSystemItem struct { OSAttributes UpdateStatus string `json:"update_status" csv:"update_status" query:"CASE WHEN spkg.installable_id is not null THEN 'Installable' WHEN spkg.applicable_id is not null THEN 'Applicable' ELSE 'None' END" gorm:"column:update_status"` SystemGroups - SystemWorkspace } type PackageSystemDBLookup struct { @@ -55,9 +54,9 @@ type PackageSystemsResponse struct { Meta ListMeta `json:"meta"` } -func packageSystemsQuery(db *gorm.DB, acc int, workspaceIDs []string, packageName string, packageIDs []int, +func packageSystemsQuery(db *gorm.DB, acc int, groups map[string]string, packageName string, packageIDs []int, ) *gorm.DB { - query := database.SystemPackages(db, acc, workspaceIDs, + query := database.SystemPackages(db, acc, groups, database.JoinTemplates, database.JoinInstallableApplicablePackages). Select(PackageSystemsSelect). Where("si.stale = false"). @@ -68,7 +67,7 @@ func packageSystemsQuery(db *gorm.DB, acc int, workspaceIDs []string, packageNam func packageSystemsCommon(db *gorm.DB, c *gin.Context) (*gorm.DB, *ListMeta, []string, error) { account := c.GetInt(utils.KeyAccount) - workspaceIDs := c.GetStringSlice(utils.KeyInventoryWorkspaces) + groups := c.GetStringMapString(utils.KeyInventoryGroups) var filters map[string]FilterData packageName := c.Param("package_name") @@ -88,7 +87,7 @@ func packageSystemsCommon(db *gorm.DB, c *gin.Context) (*gorm.DB, *ListMeta, []s return nil, nil, nil, errors.New("package not found") } - query := packageSystemsQuery(db, account, workspaceIDs, packageName, packageIDs) + query := packageSystemsQuery(db, account, groups, packageName, packageIDs) filters, err := ParseAllFilters(c, PackageSystemsOpts) if err != nil { return nil, nil, nil, err diff --git a/manager/controllers/package_systems_export.go b/manager/controllers/package_systems_export.go index 5bac813c4..65acc3744 100644 --- a/manager/controllers/package_systems_export.go +++ b/manager/controllers/package_systems_export.go @@ -33,7 +33,7 @@ import ( // @Router /export/packages/{package_name}/systems [get] func PackageSystemsExportHandler(c *gin.Context) { account := c.GetInt(utils.KeyAccount) - workspaceIDs := c.GetStringSlice(utils.KeyInventoryWorkspaces) + groups := c.GetStringMapString(utils.KeyInventoryGroups) packageName := c.Param("package_name") if packageName == "" { @@ -53,7 +53,7 @@ func PackageSystemsExportHandler(c *gin.Context) { return } - query := packageSystemsQuery(db, account, workspaceIDs, packageName, packageIDs) + query := packageSystemsQuery(db, account, groups, packageName, packageIDs) filters, err := ParseAllFilters(c, PackageSystemsOpts) if err != nil { return diff --git a/manager/controllers/package_systems_export_test.go b/manager/controllers/package_systems_export_test.go index 728bf0baf..acfc52af1 100644 --- a/manager/controllers/package_systems_export_test.go +++ b/manager/controllers/package_systems_export_test.go @@ -38,17 +38,14 @@ func TestPackageSystemsExportHandlerCSV(t *testing.T) { assert.Equal(t, 5, len(lines)) assert.Equal(t, "id,display_name,installed_evra,available_evra,updatable,tags,"+ "baseline_name,baseline_uptodate,template_name,template_uuid,satellite_managed,baseline_id,os,rhsm,"+ - "update_status,groups,workspace_id,workspace_name", lines[0]) + "update_status,groups", lines[0]) assert.Equal(t, "00000000-0000-0000-0000-000000000012,00000000-0000-0000-0000-000000000012,"+ "5.6.13-200.fc31.x86_64,5.6.13-201.fc31.x86_64,true,"+ - "\"[{'key':'k1','namespace':'ns1','value':'val1'}]\",,,,,false,0,RHEL 8.1,8.1,Installable,"+ - "\"[{'id':'00000000-0000-0000-0000-999999999999','name':'root-ws'}]\","+ - "00000000-0000-0000-0000-999999999999,root-ws", + "\"[{'key':'k1','namespace':'ns1','value':'val1'}]\",,,,,false,0,RHEL 8.1,8.1,Installable,[]", lines[1]) assert.Equal(t, "00000000-0000-0000-0000-000000000013,00000000-0000-0000-0000-000000000013,"+ "5.6.13-200.fc31.x86_64,,false,\"[{'key':'k1','namespace':'ns1','value':'val1'}]\",,,,,"+ - "false,0,RHEL 8.2,8.2,None,\"[{'id':'00000000-0000-0000-0000-999999999999','name':'root-ws'}]\","+ - "00000000-0000-0000-0000-999999999999,root-ws", lines[2]) + "false,0,RHEL 8.2,8.2,None,[]", lines[2]) } func TestPackageSystemsExportInvalidName(t *testing.T) { diff --git a/manager/controllers/package_versions.go b/manager/controllers/package_versions.go index 07df60435..78bf80a8c 100644 --- a/manager/controllers/package_versions.go +++ b/manager/controllers/package_versions.go @@ -45,8 +45,8 @@ func packagesNameID(db *gorm.DB, pkgName string) *gorm.DB { Where("pn.name = ?", pkgName) } -func packageVersionsQuery(db *gorm.DB, acc int, workspaceIDs []string, packageNameIDs []int) *gorm.DB { - query := database.SystemPackages(db, acc, workspaceIDs). +func packageVersionsQuery(db *gorm.DB, acc int, groups map[string]string, packageNameIDs []int) *gorm.DB { + query := database.SystemPackages(db, acc, groups). Distinct(PackageVersionSelect). Where("si.stale = false"). Where("spkg.name_id in (?)", packageNameIDs) @@ -69,7 +69,7 @@ func packageVersionsQuery(db *gorm.DB, acc int, workspaceIDs []string, packageNa // @Router /packages/{package_name}/versions [get] func PackageVersionsListHandler(c *gin.Context) { account := c.GetInt(utils.KeyAccount) - workspaceIDs := c.GetStringSlice(utils.KeyInventoryWorkspaces) + groups := c.GetStringMapString(utils.KeyInventoryGroups) packageName := c.Param("package_name") if packageName == "" { @@ -89,7 +89,7 @@ func PackageVersionsListHandler(c *gin.Context) { return } - query := packageVersionsQuery(db, account, workspaceIDs, packageNameIDs) + query := packageVersionsQuery(db, account, groups, packageNameIDs) // we don't support tags and filters for this endpoint query, meta, params, err := ListCommon(query, c, nil, PackageVersionsOpts) if err != nil { diff --git a/manager/controllers/packages.go b/manager/controllers/packages.go index ea4d14de0..59b8b8eea 100644 --- a/manager/controllers/packages.go +++ b/manager/controllers/packages.go @@ -54,7 +54,7 @@ type queryItem struct { var queryItemSelect = database.MustGetSelect(&queryItem{}) -func packagesQuery(db *gorm.DB, filters map[string]FilterData, acc int, workspaceIDs []string, +func packagesQuery(db *gorm.DB, filters map[string]FilterData, acc int, groups map[string]string, useCache bool) *gorm.DB { if useCache { middlewares.PackageAccountDataCnt.WithLabelValues("hit").Inc() @@ -65,7 +65,7 @@ func packagesQuery(db *gorm.DB, filters map[string]FilterData, acc int, workspac return q } middlewares.PackageAccountDataCnt.WithLabelValues("miss").Inc() - systemsWithPkgsInstalledQ := database.Systems(db, acc, workspaceIDs). + systemsWithPkgsInstalledQ := database.Systems(db, acc, groups). Select("si.id"). Where("si.stale = false AND spatch.packages_installed > 0") @@ -114,7 +114,7 @@ func packagesQuery(db *gorm.DB, filters map[string]FilterData, acc int, workspac func PackagesListHandler(c *gin.Context) { var filters map[string]FilterData account := c.GetInt(utils.KeyAccount) - workspaceIDs := c.GetStringSlice(utils.KeyInventoryWorkspaces) + groups := c.GetStringMapString(utils.KeyInventoryGroups) filters, err := ParseAllFilters(c, PackagesOpts) if err != nil { @@ -122,13 +122,13 @@ func PackagesListHandler(c *gin.Context) { } db := middlewares.DBFromContext(c) - useCache := shouldUseCache(db, account, filters, workspaceIDs) + useCache := shouldUseCache(db, account, filters, groups) if !useCache { db.Exec("SET work_mem TO '?'", utils.CoreCfg.DBWorkMem) defer db.Exec("RESET work_mem") } - query := packagesQuery(db, filters, account, workspaceIDs, useCache) + query := packagesQuery(db, filters, account, groups, useCache) query, meta, params, err := ListCommon(query, c, filters, PackagesOpts) if err != nil { return @@ -167,14 +167,11 @@ func PackageDBLookup2Item(packages []PackageDBLookup) ([]PackageItem, int) { } // use cache only when tag filter is not used, there are no inventory groups and cache is valid -func shouldUseCache(db *gorm.DB, acc int, filters map[string]FilterData, workspaceIDs []string) bool { - // TODO: remove this function, it does not make sense since replacing groups with workspaces, - // because there is always at least the root workspace - +func shouldUseCache(db *gorm.DB, acc int, filters map[string]FilterData, groups map[string]string) bool { if !config.EnabledPackageCache { return false } - if HasInventoryFilter(filters) || len(workspaceIDs) != 0 { + if HasInventoryFilter(filters) || len(groups) != 0 { return false } diff --git a/manager/controllers/packages_export.go b/manager/controllers/packages_export.go index e027af7b0..43c6f607b 100644 --- a/manager/controllers/packages_export.go +++ b/manager/controllers/packages_export.go @@ -27,19 +27,19 @@ import ( // @Router /export/packages [get] func PackagesExportHandler(c *gin.Context) { account := c.GetInt(utils.KeyAccount) - workspaceIDs := c.GetStringSlice(utils.KeyInventoryWorkspaces) + groups := c.GetStringMapString(utils.KeyInventoryGroups) filters, err := ParseAllFilters(c, PackagesOpts) if err != nil { return } db := middlewares.DBFromContext(c) - useCache := shouldUseCache(db, account, filters, workspaceIDs) + useCache := shouldUseCache(db, account, filters, groups) if !useCache { db.Exec("SET work_mem TO '?'", utils.CoreCfg.DBWorkMem) defer db.Exec("RESET work_mem") } - query := packagesQuery(db, filters, account, workspaceIDs, useCache) + query := packagesQuery(db, filters, account, groups, useCache) query, err = ExportListCommon(query, c, PackagesOpts) var data []PackageDBLookup diff --git a/manager/controllers/system_advisories.go b/manager/controllers/system_advisories.go index 34ae6b3bc..2a4e85bf0 100644 --- a/manager/controllers/system_advisories.go +++ b/manager/controllers/system_advisories.go @@ -72,7 +72,7 @@ func (v *RelList) Scan(value interface{}) error { func systemAdvisoriesCommon(c *gin.Context) (*gorm.DB, *ListMeta, []string, error) { account := c.GetInt(utils.KeyAccount) - workspaceIDs := c.GetStringSlice(utils.KeyInventoryWorkspaces) + groups := c.GetStringMapString(utils.KeyInventoryGroups) inventoryID := c.Param("inventory_id") if inventoryID == "" { @@ -105,7 +105,7 @@ func systemAdvisoriesCommon(c *gin.Context) (*gorm.DB, *ListMeta, []string, erro return nil, nil, nil, err } - query := buildSystemAdvisoriesQuery(db, account, workspaceIDs, inventoryID) + query := buildSystemAdvisoriesQuery(db, account, groups, inventoryID) query, meta, params, err := ListCommon(query, c, filters, SystemAdvisoriesOpts) // Error handling and setting of result code & content is done in ListCommon return query, meta, params, err @@ -200,8 +200,8 @@ func SystemAdvisoriesIDsHandler(c *gin.Context) { c.JSON(http.StatusOK, &resp) } -func buildSystemAdvisoriesQuery(db *gorm.DB, account int, workspaceIDs []string, inventoryID string) *gorm.DB { - query := database.SystemAdvisoriesByInventoryID(db, account, workspaceIDs, inventoryID, +func buildSystemAdvisoriesQuery(db *gorm.DB, account int, groups map[string]string, inventoryID string) *gorm.DB { + query := database.SystemAdvisoriesByInventoryID(db, account, groups, inventoryID, database.JoinAdvisoryMetadata, database.JoinAdvisoryType). Joins("JOIN status ON sa.status_id = status.id"). Joins("LEFT JOIN advisory_severity sev ON am.severity_id = sev.id"). diff --git a/manager/controllers/system_advisories_export.go b/manager/controllers/system_advisories_export.go index 62814cdfd..c094841b6 100644 --- a/manager/controllers/system_advisories_export.go +++ b/manager/controllers/system_advisories_export.go @@ -34,7 +34,7 @@ import ( // @Router /export/systems/{inventory_id}/advisories [get] func SystemAdvisoriesExportHandler(c *gin.Context) { account := c.GetInt(utils.KeyAccount) - workspaceIDs := c.GetStringSlice(utils.KeyInventoryWorkspaces) + groups := c.GetStringMapString(utils.KeyInventoryGroups) inventoryID := c.Param("inventory_id") if inventoryID == "" { @@ -60,7 +60,7 @@ func SystemAdvisoriesExportHandler(c *gin.Context) { return } - query := buildSystemAdvisoriesQuery(db, account, workspaceIDs, inventoryID) + query := buildSystemAdvisoriesQuery(db, account, groups, inventoryID) query = query.Order("id") query, err = ExportListCommon(query, c, SystemAdvisoriesOpts) if err != nil { diff --git a/manager/controllers/system_detail.go b/manager/controllers/system_detail.go index 02d6c93a3..faa78bfb8 100644 --- a/manager/controllers/system_detail.go +++ b/manager/controllers/system_detail.go @@ -44,7 +44,7 @@ type SystemYumUpdatesResponse struct { // @Router /systems/{inventory_id} [get] func SystemDetailHandler(c *gin.Context) { account := c.GetInt(utils.KeyAccount) - workspaceIDs := c.GetStringSlice(utils.KeyInventoryWorkspaces) + groups := c.GetStringMapString(utils.KeyInventoryGroups) inventoryID := c.Param("inventory_id") if inventoryID == "" { @@ -63,7 +63,7 @@ func SystemDetailHandler(c *gin.Context) { var systemDetail SystemDetailLookup db := middlewares.DBFromContext(c) - query := database.Systems(db, account, workspaceIDs, database.JoinTemplates). + query := database.Systems(db, account, groups, database.JoinTemplates). Select(database.MustGetSelect(&systemDetail)). Where("si.inventory_id = ?::uuid", inventoryID) @@ -154,7 +154,7 @@ func SystemYumUpdatesHandler(c *gin.Context) { func systemJSONsCommon(c *gin.Context, column string) *models.SystemInventory { account := c.GetInt(utils.KeyAccount) - workspaceIDs := c.GetStringSlice(utils.KeyInventoryWorkspaces) + groups := c.GetStringMapString(utils.KeyInventoryGroups) inventoryID := c.Param("inventory_id") if inventoryID == "" { @@ -173,7 +173,7 @@ func systemJSONsCommon(c *gin.Context, column string) *models.SystemInventory { var system models.SystemInventory db := middlewares.DBFromContext(c) - query := database.Systems(db, account, workspaceIDs). + query := database.Systems(db, account, groups). Select(column). Where("si.inventory_id = ?::uuid", inventoryID) diff --git a/manager/controllers/system_packages.go b/manager/controllers/system_packages.go index 337298a52..fecf585c4 100644 --- a/manager/controllers/system_packages.go +++ b/manager/controllers/system_packages.go @@ -56,8 +56,8 @@ type SystemPackageDBLoad struct { MetaTotalHelper } -func systemPackageQuery(db *gorm.DB, account int, workspaceIDs []string, inventoryID string) *gorm.DB { - query := database.SystemPackages(db, account, workspaceIDs, database.JoinInstallableApplicablePackages). +func systemPackageQuery(db *gorm.DB, account int, groups map[string]string, inventoryID string) *gorm.DB { + query := database.SystemPackages(db, account, groups, database.JoinInstallableApplicablePackages). Joins("LEFT JOIN strings AS descr ON p.description_hash = descr.id"). Joins("LEFT JOIN strings AS sum ON p.summary_hash = sum.id"). Select(SystemPackagesSelect). @@ -89,7 +89,7 @@ func systemPackageQuery(db *gorm.DB, account int, workspaceIDs []string, invento // @Router /systems/{inventory_id}/packages [get] func SystemPackagesHandler(c *gin.Context) { account := c.GetInt(utils.KeyAccount) - workspaceIDs := c.GetStringSlice(utils.KeyInventoryWorkspaces) + groups := c.GetStringMapString(utils.KeyInventoryGroups) inventoryID := c.Param("inventory_id") if inventoryID == "" { @@ -108,7 +108,7 @@ func SystemPackagesHandler(c *gin.Context) { } var loaded []SystemPackageDBLoad db := middlewares.DBFromContext(c) - q := systemPackageQuery(db, account, workspaceIDs, inventoryID) + q := systemPackageQuery(db, account, groups, inventoryID) q, meta, params, err := ListCommon(q, c, filters, SystemPackagesOpts) if err != nil { return diff --git a/manager/controllers/system_packages_export.go b/manager/controllers/system_packages_export.go index 64ba60526..d585307b8 100644 --- a/manager/controllers/system_packages_export.go +++ b/manager/controllers/system_packages_export.go @@ -37,7 +37,7 @@ type SystemPackageInline struct { // @Router /export/systems/{inventory_id}/packages [get] func SystemPackagesExportHandler(c *gin.Context) { account := c.GetInt(utils.KeyAccount) - workspaceIDs := c.GetStringSlice(utils.KeyInventoryWorkspaces) + groups := c.GetStringMapString(utils.KeyInventoryGroups) inventoryID := c.Param("inventory_id") if inventoryID == "" { @@ -52,7 +52,7 @@ func SystemPackagesExportHandler(c *gin.Context) { var loaded []SystemPackageDBLoad db := middlewares.DBFromContext(c) - q := systemPackageQuery(db, account, workspaceIDs, inventoryID) + q := systemPackageQuery(db, account, groups, inventoryID) q, err := ExportListCommon(q, c, SystemPackagesOpts) if err != nil { // Error handling and setting of result code & content is done in ListCommon diff --git a/manager/controllers/systems.go b/manager/controllers/systems.go index 7631ac658..c4305e9aa 100644 --- a/manager/controllers/systems.go +++ b/manager/controllers/systems.go @@ -96,7 +96,6 @@ type SystemItemAttributes struct { BaselineIDAttr TemplateAttibutes SystemGroups - SystemWorkspace SystemArch } @@ -199,9 +198,9 @@ func validateSystemsListIDs(ids []string) error { func systemsCommon(c *gin.Context, ids []string) (*gorm.DB, *ListMeta, []string, error) { account := c.GetInt(utils.KeyAccount) - workspaceIDs := c.GetStringSlice(utils.KeyInventoryWorkspaces) + groups := c.GetStringMapString(utils.KeyInventoryGroups) db := middlewares.DBFromContext(c) - query := querySystems(db, account, workspaceIDs) + query := querySystems(db, account, groups) filters, err := ParseAllFilters(c, SystemOpts) if err != nil { return nil, nil, nil, err @@ -459,6 +458,6 @@ func SystemsListIDsHandler(c *gin.Context) { c.JSON(http.StatusOK, &resp) } -func querySystems(db *gorm.DB, account int, workspaceIDs []string) *gorm.DB { - return database.Systems(db, account, workspaceIDs, database.JoinTemplates).Select(SystemsSelect) +func querySystems(db *gorm.DB, account int, groups map[string]string) *gorm.DB { + return database.Systems(db, account, groups, database.JoinTemplates).Select(SystemsSelect) } diff --git a/manager/controllers/systems_advisories_view.go b/manager/controllers/systems_advisories_view.go index f6166cc6f..7c4b4f885 100644 --- a/manager/controllers/systems_advisories_view.go +++ b/manager/controllers/systems_advisories_view.go @@ -72,14 +72,14 @@ func totalItems(tx *gorm.DB, cols string) (int, error) { return int(count), err } -func systemsAdvisoriesQuery(c *gin.Context, db *gorm.DB, acc int, workspaceIDs []string, +func systemsAdvisoriesQuery(c *gin.Context, db *gorm.DB, acc int, groups map[string]string, req SystemsAdvisoriesRequest) (*gorm.DB, *ListMeta, *Links, error) { systems := req.Systems advisories := req.Advisories sysq := database.ApplyInventoryWorkspaceFilter( db.Table("system_inventory si"). Where("si.rh_account_id = ?", acc), - workspaceIDs). + groups). Distinct("si.rh_account_id, si.id, si.inventory_id"). // we need to join system_advisories to make `limit` work properly // without this join it can happen that we display less items on some pages @@ -122,12 +122,12 @@ func systemsAdvisoriesQuery(c *gin.Context, db *gorm.DB, acc int, workspaceIDs [ return query, meta, links, err } -func advisoriesSystemsQuery(c *gin.Context, db *gorm.DB, acc int, workspaceIDs []string, +func advisoriesSystemsQuery(c *gin.Context, db *gorm.DB, acc int, groups map[string]string, req SystemsAdvisoriesRequest) (*gorm.DB, *ListMeta, *Links, error) { systems := req.Systems advisories := req.Advisories // get all advisories for all systems in the account - advq := database.SystemAdvisories(db, acc, workspaceIDs, database.JoinAdvisoryMetadata). + advq := database.SystemAdvisories(db, acc, groups, database.JoinAdvisoryMetadata). Distinct("am.id, am.name") // we need to join system_advisories to make `limit` work properly // without this join it can happen that we display less items on some pages @@ -180,7 +180,7 @@ func queryDB(c *gin.Context, endpoint string) ([]systemsAdvisoriesDBLoad, *ListM return nil, nil, nil, err } acc := c.GetInt(utils.KeyAccount) - workspaceIDs := c.GetStringSlice(utils.KeyInventoryWorkspaces) + groups := c.GetStringMapString(utils.KeyInventoryGroups) db := middlewares.DBFromContext(c) // backward compatibility, put limit/offset from json into querystring if req.Limit != nil { @@ -191,9 +191,9 @@ func queryDB(c *gin.Context, endpoint string) ([]systemsAdvisoriesDBLoad, *ListM } switch endpoint { case "SystemsAdvisories": - q, meta, links, err = systemsAdvisoriesQuery(c, db, acc, workspaceIDs, req) + q, meta, links, err = systemsAdvisoriesQuery(c, db, acc, groups, req) case "AdvisoriesSystems": - q, meta, links, err = advisoriesSystemsQuery(c, db, acc, workspaceIDs, req) + q, meta, links, err = advisoriesSystemsQuery(c, db, acc, groups, req) default: return nil, nil, nil, fmt.Errorf("unknown endpoint '%s'", endpoint) } diff --git a/manager/controllers/systems_advisories_view_test.go b/manager/controllers/systems_advisories_view_test.go index face8a2ea..6ac238d04 100644 --- a/manager/controllers/systems_advisories_view_test.go +++ b/manager/controllers/systems_advisories_view_test.go @@ -13,8 +13,7 @@ import ( "github.com/stretchr/testify/assert" ) -func doTestView(t *testing.T, handler gin.HandlerFunc, q string, limit, offset *int, -) *httptest.ResponseRecorder { +func doTestView(t *testing.T, handler gin.HandlerFunc, q string, limit, offset *int) *httptest.ResponseRecorder { core.SetupTest(t) body := SystemsAdvisoriesRequest{ Systems: []SystemID{"00000000-0000-0000-0000-000000000001", "00000000-0000-0000-0000-000000000002"}, diff --git a/manager/controllers/systems_export.go b/manager/controllers/systems_export.go index ce1d41328..d3ef42314 100644 --- a/manager/controllers/systems_export.go +++ b/manager/controllers/systems_export.go @@ -56,9 +56,9 @@ import ( // @Router /export/systems [get] func SystemsExportHandler(c *gin.Context) { account := c.GetInt(utils.KeyAccount) - workspaceIDs := c.GetStringSlice(utils.KeyInventoryWorkspaces) + groups := c.GetStringMapString(utils.KeyInventoryGroups) db := middlewares.DBFromContext(c) - query := querySystems(db, account, workspaceIDs) + query := querySystems(db, account, groups) filters, err := ParseAllFilters(c, SystemOpts) if err != nil { return diff --git a/manager/controllers/systems_export_test.go b/manager/controllers/systems_export_test.go index a5bbb3b64..ae99a7cc6 100644 --- a/manager/controllers/systems_export_test.go +++ b/manager/controllers/systems_export_test.go @@ -18,7 +18,7 @@ var SystemCsvHeader = "id,display_name,os,rhsm,tags,last_evaluation," + "satellite_managed,built_pkgcache,packages_installable,packages_applicable," + "installable_rhsa_count,installable_rhba_count,installable_rhea_count,installable_other_count," + "applicable_rhsa_count,applicable_rhba_count,applicable_rhea_count,applicable_other_count," + - "baseline_id,template_name,template_uuid,groups,workspace_id,workspace_name,arch" + "baseline_id,template_name,template_uuid,groups,arch" func makeRequest(t *testing.T, path string, contentType string) *httptest.ResponseRecorder { core.SetupTest(t) @@ -60,8 +60,7 @@ func TestSystemsExportCSV(t *testing.T) { "2018-09-22T16:00:00Z,2,2,1,0,0,,"+ "2020-09-22T16:00:00Z,2018-08-26T16:00:00Z,2018-09-02T16:00:00Z,,2018-08-26T16:00:00Z,"+ "false,false,false,0,0,2,2,1,0,2,3,3,3,0,temp1-1,99900000-0000-0000-0000-000000000001,"+ - "\"[{'id':'00000000-0000-0000-0000-000000000001','name':'group1'}]\","+ - "00000000-0000-0000-0000-000000000001,group1,x86_64", + "\"[{'id':'inventory-group-1','name':'group1'}]\",x86_64", lines[1]) } diff --git a/manager/controllers/systemtags.go b/manager/controllers/systemtags.go index adec630bb..5f02993d9 100644 --- a/manager/controllers/systemtags.go +++ b/manager/controllers/systemtags.go @@ -65,11 +65,11 @@ var SystemTagsOpts = ListOpts{ func SystemTagListHandler(c *gin.Context) { var err error account := c.GetInt(utils.KeyAccount) - workspaceIDs := c.GetStringSlice(utils.KeyInventoryWorkspaces) + groups := c.GetStringMapString(utils.KeyInventoryGroups) db := middlewares.DBFromContext(c) // https://stackoverflow.com/questions/33474778/how-to-group-result-by-array-column-in-postgres - sq := database.Systems(db, account, workspaceIDs). + sq := database.Systems(db, account, groups). Select("jsonb_array_elements(si.tags) AS tag") query := db.Table("(?) AS sq", sq). diff --git a/manager/controllers/template_subscribed_systems_update.go b/manager/controllers/template_subscribed_systems_update.go index bcf2d2af0..5657ed8da 100644 --- a/manager/controllers/template_subscribed_systems_update.go +++ b/manager/controllers/template_subscribed_systems_update.go @@ -26,7 +26,6 @@ import ( // @Router /templates/{template_id}/subscribed-systems [PATCH] func TemplateSubscribedSystemsUpdateHandler(c *gin.Context) { templateUUID := c.Param("template_id") - workspaceIDs := c.GetStringSlice(utils.KeyInventoryWorkspaces) db := middlewares.DBFromContext(c) @@ -42,12 +41,12 @@ func TemplateSubscribedSystemsUpdateHandler(c *gin.Context) { } systemList := []string{systemUUID} - err = checkTemplateSystems(c, db, account, template, systemList, workspaceIDs) + err = checkTemplateSystems(c, db, account, template, systemList, nil) if err != nil { return } - err = assignCandlepinEnvironment(c, db, account, &template.EnvironmentID, systemList, workspaceIDs) + err = assignCandlepinEnvironment(c, db, account, &template.EnvironmentID, systemList, nil) if err != nil { return } diff --git a/manager/controllers/template_systems.go b/manager/controllers/template_systems.go index fd2e4ccee..83d243275 100644 --- a/manager/controllers/template_systems.go +++ b/manager/controllers/template_systems.go @@ -36,7 +36,6 @@ type TemplateSystemAttributes struct { ApplicableAdvisories SystemTags SystemGroups - SystemWorkspace SystemLastUpload } @@ -76,7 +75,7 @@ func getTemplate(c *gin.Context, tx *gorm.DB, account int, uuid string) (*models return &template, nil } -func templateSystemsQuery(c *gin.Context, account int, workspaceIDs []string) (*gorm.DB, Filters, error) { +func templateSystemsQuery(c *gin.Context, account int, groups map[string]string) (*gorm.DB, Filters, error) { templateUUID := c.Param("template_id") db := middlewares.DBFromContext(c) @@ -86,7 +85,7 @@ func templateSystemsQuery(c *gin.Context, account int, workspaceIDs []string) (* return nil, nil, err } - query := database.Systems(db, account, workspaceIDs). + query := database.Systems(db, account, groups). Where("spatch.template_id = ?", template.ID). Select(templateSystemSelect) @@ -98,9 +97,9 @@ func templateSystemsQuery(c *gin.Context, account int, workspaceIDs []string) (* return query, filters, nil } -func templateSystemsCommon(c *gin.Context, account int, workspaceIDs []string, +func templateSystemsCommon(c *gin.Context, account int, groups map[string]string, ) (*gorm.DB, *ListMeta, []string, error) { - query, filters, err := templateSystemsQuery(c, account, workspaceIDs) + query, filters, err := templateSystemsQuery(c, account, groups) if err != nil { return nil, nil, nil, err } // Error handled in method itself @@ -160,9 +159,9 @@ func templateSystemData(templateSystems []TemplateSystemsDBLookup) ([]TemplateSy // @Router /templates/{template_id}/systems [get] func TemplateSystemsListHandler(c *gin.Context) { account := c.GetInt(utils.KeyAccount) - workspaceIDs := c.GetStringSlice(utils.KeyInventoryWorkspaces) + groups := c.GetStringMapString(utils.KeyInventoryGroups) - query, meta, params, err := templateSystemsCommon(c, account, workspaceIDs) + query, meta, params, err := templateSystemsCommon(c, account, groups) if err != nil { return } // Error handled in method itself @@ -209,9 +208,9 @@ func TemplateSystemsListHandler(c *gin.Context) { // @Router /ids/templates/{template_id}/systems [get] func TemplateSystemsListIDsHandler(c *gin.Context) { account := c.GetInt(utils.KeyAccount) - workspaceIDs := c.GetStringSlice(utils.KeyInventoryWorkspaces) + groups := c.GetStringMapString(utils.KeyInventoryGroups) - query, meta, _, err := templateSystemsCommon(c, account, workspaceIDs) + query, meta, _, err := templateSystemsCommon(c, account, groups) if err != nil { return } // Error handled in method itself diff --git a/manager/controllers/template_systems_delete.go b/manager/controllers/template_systems_delete.go index 284a38a26..bf84c7834 100644 --- a/manager/controllers/template_systems_delete.go +++ b/manager/controllers/template_systems_delete.go @@ -24,7 +24,7 @@ import ( // @Router /templates/systems [DELETE] func TemplateSystemsDeleteHandler(c *gin.Context) { account := c.GetInt(utils.KeyAccount) - workspaceIDs := c.GetStringSlice(utils.KeyInventoryWorkspaces) + groups := c.GetStringMapString(utils.KeyInventoryGroups) var req TemplateSystemsUpdateRequest if err := c.ShouldBindJSON(&req); err != nil { @@ -38,12 +38,12 @@ func TemplateSystemsDeleteHandler(c *gin.Context) { db := middlewares.DBFromContext(c) - err := checkTemplateSystems(c, db, account, nil, req.Systems, workspaceIDs) + err := checkTemplateSystems(c, db, account, nil, req.Systems, groups) if err != nil { return } - err = assignCandlepinEnvironment(c, db, account, nil, req.Systems, workspaceIDs) + err = assignCandlepinEnvironment(c, db, account, nil, req.Systems, groups) if err != nil { return } diff --git a/manager/controllers/template_systems_export.go b/manager/controllers/template_systems_export.go index caf3681c7..944b9468d 100644 --- a/manager/controllers/template_systems_export.go +++ b/manager/controllers/template_systems_export.go @@ -33,9 +33,9 @@ import ( // @Router /export/templates/{template_id}/systems [get] func TemplateSystemsExportHandler(c *gin.Context) { account := c.GetInt(utils.KeyAccount) - workspaceIDs := c.GetStringSlice(utils.KeyInventoryWorkspaces) + groups := c.GetStringMapString(utils.KeyInventoryGroups) - query, _, err := templateSystemsQuery(c, account, workspaceIDs) + query, _, err := templateSystemsQuery(c, account, groups) if err != nil { return } // Error handled in method itself diff --git a/manager/controllers/template_systems_export_test.go b/manager/controllers/template_systems_export_test.go index 7cd3dad2a..0d3a312f3 100644 --- a/manager/controllers/template_systems_export_test.go +++ b/manager/controllers/template_systems_export_test.go @@ -14,7 +14,7 @@ import ( var TemplateCsvHeader = "id,display_name,os,rhsm," + "installable_rhsa_count,installable_rhba_count,installable_rhea_count,installable_other_count," + "applicable_rhsa_count,applicable_rhba_count,applicable_rhea_count,applicable_other_count," + - "tags,groups,workspace_id,workspace_name,last_upload" + "tags,groups,last_upload" // nolint: dupl func TestTemplateSystemsExportJSON(t *testing.T) { @@ -68,13 +68,13 @@ func TestTemplateSystemsExportCSV(t *testing.T) { assert.Equal(t, "00000000-0000-0000-0000-000000000002,00000000-0000-0000-0000-000000000002,RHEL 8.1,"+ "8.1,0,0,0,0,0,0,1,0,\"[{'key':'k1','namespace':'ns1','value':'val1'},"+ "{'key':'k2','namespace':'ns1','value':'val2'},{'key':'k3','namespace':'ns1','value':'val3'}]\","+ - "\"[{'id':'00000000-0000-0000-0000-000000000001','name':'group1'}]\","+ - "00000000-0000-0000-0000-000000000001,group1,2018-09-22T16:00:00Z", lines[1]) + "\"[{'id':'inventory-group-1','name':'group1'}]\",2018-09-22T16:00:00Z", + lines[1]) assert.Equal(t, "00000000-0000-0000-0000-000000000001,00000000-0000-0000-0000-000000000001,RHEL 8.10,"+ "8.10,2,2,1,0,2,3,3,0,\"[{'key':'k1','namespace':'ns1','value':'val1'},"+ "{'key':'k2','namespace':'ns1','value':'val2'}]\","+ - "\"[{'id':'00000000-0000-0000-0000-000000000001','name':'group1'}]\","+ - "00000000-0000-0000-0000-000000000001,group1,2020-09-22T16:00:00Z", lines[2]) + "\"[{'id':'inventory-group-1','name':'group1'}]\",2020-09-22T16:00:00Z", + lines[2]) } func TestTemplateSystemsExportWrongFormat(t *testing.T) { diff --git a/manager/controllers/template_systems_update.go b/manager/controllers/template_systems_update.go index 2d4591eab..9ba90f0ee 100644 --- a/manager/controllers/template_systems_update.go +++ b/manager/controllers/template_systems_update.go @@ -54,7 +54,7 @@ type SystemTemplateDBLookup struct { func TemplateSystemsUpdateHandler(c *gin.Context) { account := c.GetInt(utils.KeyAccount) templateUUID := c.Param("template_id") - workspaceIDs := c.GetStringSlice(utils.KeyInventoryWorkspaces) + groups := c.GetStringMapString(utils.KeyInventoryGroups) var req TemplateSystemsUpdateRequest if err := c.ShouldBindJSON(&req); err != nil { @@ -73,12 +73,12 @@ func TemplateSystemsUpdateHandler(c *gin.Context) { return } - err = checkTemplateSystems(c, db, account, template, req.Systems, workspaceIDs) + err = checkTemplateSystems(c, db, account, template, req.Systems, groups) if err != nil { return } - err = assignCandlepinEnvironment(c, db, account, &template.EnvironmentID, req.Systems, workspaceIDs) + err = assignCandlepinEnvironment(c, db, account, &template.EnvironmentID, req.Systems, groups) if err != nil { return } @@ -97,14 +97,14 @@ func TemplateSystemsUpdateHandler(c *gin.Context) { } func checkTemplateSystems(c *gin.Context, db *gorm.DB, accountID int, template *models.Template, - inventoryIDs []string, workspaceIDs []string) error { + inventoryIDs []string, groups map[string]string) error { if len(inventoryIDs) == 0 { err := errors.New(InvalidInventoryIDsErr) utils.LogAndRespBadRequest(c, err, InvalidInventoryIDsErr) return err } - err := checkInventoryIDs(db, accountID, inventoryIDs, workspaceIDs) + err := checkInventoryIDs(db, accountID, inventoryIDs, groups) if err != nil { switch { case errors.Is(err, base.ErrBadRequest): @@ -119,7 +119,7 @@ func checkTemplateSystems(c *gin.Context, db *gorm.DB, accountID int, template * } } - if err := templateArchVersionMatch(db, inventoryIDs, template, accountID, workspaceIDs); err != nil { + if err := templateArchVersionMatch(db, inventoryIDs, template, accountID, groups); err != nil { msg := fmt.Sprintf("Incompatible template and system version or architecture: %s", err.Error()) utils.LogAndRespBadRequest(c, err, msg) return err @@ -164,7 +164,7 @@ func assignTemplateSystems(c *gin.Context, db *gorm.DB, accountID int, template } func templateArchVersionMatch( - db *gorm.DB, inventoryIDs []string, template *models.Template, acc int, workspaceIDs []string, + db *gorm.DB, inventoryIDs []string, template *models.Template, acc int, groups map[string]string, ) error { if template == nil { return nil @@ -175,7 +175,7 @@ func templateArchVersionMatch( Version string }{} var err error - err = database.Systems(db, acc, workspaceIDs). + err = database.Systems(db, acc, groups). Select("si.inventory_id as inventory_id, si.os_major as version, si.arch as arch"). Where("si.inventory_id in (?)", inventoryIDs).Find(&sysArchVersions).Error if err != nil { @@ -220,13 +220,13 @@ func callCandlepin(ctx context.Context, owner string, request *candlepin.Consume } func assignCandlepinEnvironment(c *gin.Context, db *gorm.DB, accountID int, env *string, inventoryIDs []string, - workspaceIDs []string) error { + groups map[string]string) error { var hosts = []struct { InventoryID string Consumer *string }{} - err := database.Systems(db, accountID, workspaceIDs). + err := database.Systems(db, accountID, groups). Select("si.inventory_id as inventory_id, si.subscription_manager_id as consumer"). Where("si.inventory_id in (?)", inventoryIDs).Find(&hosts).Error if err != nil { @@ -270,12 +270,12 @@ func assignCandlepinEnvironment(c *gin.Context, db *gorm.DB, accountID int, env return nil } -func checkInventoryIDs(db *gorm.DB, accountID int, inventoryIDs []string, workspaceIDs []string) (err error) { +func checkInventoryIDs(db *gorm.DB, accountID int, inventoryIDs []string, groups map[string]string) (err error) { var containingSystems []SystemTemplateDBLookup var missingIDs []string var satelliteIDs []string var bootcIDs []string - err = database.Systems(db, accountID, workspaceIDs). + err = database.Systems(db, accountID, groups). Select("si.inventory_id, si.satellite_managed, si.bootc"). Where("si.inventory_id IN (?::uuid)", inventoryIDs). Scan(&containingSystems).Error diff --git a/manager/controllers/templates.go b/manager/controllers/templates.go index d58a92306..75d58c20a 100644 --- a/manager/controllers/templates.go +++ b/manager/controllers/templates.go @@ -77,14 +77,14 @@ type TemplatesResponse struct { // @Router /templates [get] func TemplatesListHandler(c *gin.Context) { account := c.GetInt(utils.KeyAccount) - workspaceIDs := c.GetStringSlice(utils.KeyInventoryWorkspaces) + groups := c.GetStringMapString(utils.KeyInventoryGroups) filters, err := ParseAllFilters(c, TemplateOpts) if err != nil { return } db := middlewares.DBFromContext(c) - query := templatesQuery(db, filters, account, workspaceIDs) + query := templatesQuery(db, filters, account, groups) query, meta, params, err := ListCommon(query, c, filters, TemplateOpts) if err != nil { @@ -123,8 +123,8 @@ func TemplatesListHandler(c *gin.Context) { c.JSON(http.StatusOK, &resp) } -func templatesQuery(db *gorm.DB, filters map[string]FilterData, account int, workspaceIDs []string) *gorm.DB { - subq := database.Systems(db, account, workspaceIDs). +func templatesQuery(db *gorm.DB, filters map[string]FilterData, account int, groups map[string]string) *gorm.DB { + subq := database.Systems(db, account, groups). Select("spatch.template_id, count(*) as systems"). Group("spatch.template_id") diff --git a/manager/controllers/utils.go b/manager/controllers/utils.go index 723eb8003..3c08fa4f5 100644 --- a/manager/controllers/utils.go +++ b/manager/controllers/utils.go @@ -389,7 +389,18 @@ func ApplyInventoryWhere(filters map[string]FilterData, tx *gorm.DB) (*gorm.DB, // returns "(si.mssql_workload_version) = 1.0" func buildInventoryQuery(tx *gorm.DB, key string, values []string) *gorm.DB { if strings.Contains(key, "group_name") { - return tx.Where("si.workspace_name IN (?)", values) + groups := []string{} + for _, v := range values { + name := v + group, err := utils.ParseInventoryGroup(nil, &name) + if err != nil { + // couldn't marshal inventory group to json + continue + } + groups = append(groups, group) + } + jsonq := fmt.Sprintf("{%s}", strings.Join(groups, ",")) + return tx.Where("si.workspaces @> ANY (?::jsonb[])", jsonq) } var cmp string diff --git a/manager/controllers/utils_test.go b/manager/controllers/utils_test.go index 049567255..e4782ff64 100644 --- a/manager/controllers/utils_test.go +++ b/manager/controllers/utils_test.go @@ -24,12 +24,14 @@ func TestGroupNameFilter(t *testing.T) { assert.Nil(t, err) var systems []SystemsID - workspaceIDs := []string{"00000000-0000-0000-0000-000000000001", "00000000-0000-0000-0000-000000000002"} - tx := database.Systems(database.DB, 1, workspaceIDs) + groups := map[string]string{ + utils.KeyGrouped: `{"[{\"id\":\"inventory-group-1\"}]","[{\"id\":\"inventory-group-2\"}]"}`, + } + tx := database.Systems(database.DB, 1, groups) tx, _ = ApplyInventoryFilter(filters, tx, "si.inventory_id") tx.Scan(&systems) - assert.Equal(t, 2, len(systems)) + assert.Equal(t, 2, len(systems)) // 2 systems with `group2` in test_data assert.Equal(t, "00000000-0000-0000-0000-000000000007", systems[0].ID) assert.Equal(t, "00000000-0000-0000-0000-000000000008", systems[1].ID) } @@ -45,12 +47,14 @@ func TestGroupNameFilter2(t *testing.T) { assert.Nil(t, err) var systems []SystemsID - workspaceIDs := []string{"00000000-0000-0000-0000-000000000001", "00000000-0000-0000-0000-000000000002"} - tx := database.Systems(database.DB, 1, workspaceIDs) + groups := map[string]string{ + utils.KeyGrouped: `{"[{\"id\":\"inventory-group-1\"}]","[{\"id\":\"inventory-group-2\"}]"}`, + } + tx := database.Systems(database.DB, 1, groups) tx, _ = ApplyInventoryFilter(filters, tx, "si.inventory_id") tx.Scan(&systems) - assert.Equal(t, 9, len(systems)) + assert.Equal(t, 9, len(systems)) // 2 systems with `group2`, 6 with `group1` in test_data } func TestApplySearchEmpty(t *testing.T) { diff --git a/manager/middlewares/kessel.go b/manager/middlewares/kessel.go index 91aea0b65..6c71ec00b 100644 --- a/manager/middlewares/kessel.go +++ b/manager/middlewares/kessel.go @@ -3,6 +3,7 @@ package middlewares import ( "app/base/utils" "context" + "fmt" "net/http" "strings" "time" @@ -34,6 +35,27 @@ func setupClient() (kesselv2.KesselInventoryServiceClient, *grpc.ClientConn, err return clientBuilder.Build() } +func processWorkspaces(workspaces []*kesselv2.StreamedListObjectsResponse) (map[string]string, error) { + defer func(start time.Time) { + utils.LogDebug("durationMs", time.Since(start).Milliseconds(), "processed workspaces") + }(time.Now()) + + groups := make([]string, 0, len(workspaces)) + for _, workspace := range workspaces { + group, err := utils.ParseInventoryGroup(&workspace.Object.ResourceId, nil) + if err != nil { + // couldn't marshal inventory group to json + continue + } + groups = append(groups, group) + } + + if len(groups) == 0 { + return nil, errors.New("no workspaces found") + } + return map[string]string{utils.KeyGrouped: fmt.Sprintf("{%s}", strings.Join(groups, ","))}, nil +} + func buildPermission(c *gin.Context) string { permission := "patch_system_" nameSplit := strings.Split(c.HandlerName(), ".") @@ -120,17 +142,13 @@ func hasPermissionKessel(c *gin.Context) { return } - workspaceIDs := make([]string, 0, len(workspaces)) - for _, workspace := range workspaces { - workspaceIDs = append(workspaceIDs, workspace.Object.ResourceId) - } - - if len(workspaceIDs) == 0 { - utils.LogWarn(errors.New("no workspaces found")) + inventoryGroups, err := processWorkspaces(workspaces) + if err != nil { + utils.LogWarn(err.Error()) c.AbortWithStatusJSON(http.StatusUnauthorized, utils.ErrorResponse{Error: "Missing permission"}) return } - c.Set(utils.KeyInventoryWorkspaces, workspaceIDs) + c.Set(utils.KeyInventoryGroups, inventoryGroups) } func Kessel() gin.HandlerFunc { diff --git a/manager/middlewares/kessel_test.go b/manager/middlewares/kessel_test.go index 3813c315d..b70da7a9e 100644 --- a/manager/middlewares/kessel_test.go +++ b/manager/middlewares/kessel_test.go @@ -2,7 +2,9 @@ package middlewares import ( "app/base/utils" + "fmt" "net/http" + "strconv" "testing" "google.golang.org/grpc" @@ -64,6 +66,18 @@ func TestSetupClient(t *testing.T) { utils.CoreCfg.KesselAuthClientSecret = originalKesselAuthClientSecret } +func TestProcessWorkspaces(t *testing.T) { + expected := fmt.Sprintf("{%s,%s}", strconv.Quote(`[{"id":"test-1"}]`), strconv.Quote(`[{"id":"test-2"}]`)) + workspaces := []*kesselv2.StreamedListObjectsResponse{ + {Object: &kesselv2.ResourceReference{ResourceId: "test-1"}}, + {Object: &kesselv2.ResourceReference{ResourceId: "test-2"}}, + } + processed, err := processWorkspaces(workspaces) + if assert.NoError(t, err) { + assert.Equal(t, expected, processed[utils.KeyGrouped]) + } +} + func TestBuildPermission(t *testing.T) { c := &gin.Context{Request: &http.Request{Method: http.MethodGet}} permission := buildPermission(c) @@ -95,12 +109,11 @@ func TestHasPermissionKessel(t *testing.T) { c.Request.Header.Set("x-rh-identity", "ewogICAgImVudGl0bGVtZW50cyI6IHsKICAgICAgICAiaW5zaWdodHMiOiB7CiAgICAgICAgICAgICJpc19lbnRpdGxlZCI6IHRydWUKICAgICAgICB9LAogICAgICAgICJjb3N0X21hbmFnZW1lbnQiOiB7CiAgICAgICAgICAgICJpc19lbnRpdGxlZCI6IHRydWUKICAgICAgICB9LAogICAgICAgICJhbnNpYmxlIjogewogICAgICAgICAgICAiaXNfZW50aXRsZWQiOiB0cnVlCiAgICAgICAgfSwKICAgICAgICAib3BlbnNoaWZ0IjogewogICAgICAgICAgICAiaXNfZW50aXRsZWQiOiB0cnVlCiAgICAgICAgfSwKICAgICAgICAic21hcnRfbWFuYWdlbWVudCI6IHsKICAgICAgICAgICAgImlzX2VudGl0bGVkIjogdHJ1ZQogICAgICAgIH0sCiAgICAgICAgIm1pZ3JhdGlvbnMiOiB7CiAgICAgICAgICAgICJpc19lbnRpdGxlZCI6IHRydWUKICAgICAgICB9CiAgICB9LAogICAgImlkZW50aXR5IjogewogICAgICAgICJpbnRlcm5hbCI6IHsKICAgICAgICAgICAgImF1dGhfdGltZSI6IDI5OSwKICAgICAgICAgICAgImF1dGhfdHlwZSI6ICJiYXNpYy1hdXRoIiwKICAgICAgICAgICAgIm9yZ19pZCI6ICIxMTc4OTc3MiIKICAgICAgICB9LAogICAgICAgICJhY2NvdW50X251bWJlciI6ICI2MDg5NzE5IiwKICAgICAgICAidXNlciI6IHsKICAgICAgICAgICAgImZpcnN0X25hbWUiOiAiSW5zaWdodHMiLAogICAgICAgICAgICAiaXNfYWN0aXZlIjogdHJ1ZSwKICAgICAgICAgICAgImlzX2ludGVybmFsIjogZmFsc2UsCiAgICAgICAgICAgICJsYXN0X25hbWUiOiAiUUEiLAogICAgICAgICAgICAibG9jYWxlIjogImVuX1VTIiwKICAgICAgICAgICAgImlzX29yZ19hZG1pbiI6IHRydWUsCiAgICAgICAgICAgICJ1c2VybmFtZSI6ICJpbnNpZ2h0cy1xYSIsCiAgICAgICAgICAgICJlbWFpbCI6ICJqbmVlZGxlK3FhQHJlZGhhdC5jb20iLAogICAgICAgICAgICAidXNlcl9pZCI6ICI2MDg5NzE5IgogICAgICAgIH0sCiAgICAgICAgInR5cGUiOiAiVXNlciIKICAgIH0KfQ==") //nolint:lll hasPermissionKessel(c) - workspaces, found := c.Get(utils.KeyInventoryWorkspaces) + inventoryGroups, found := c.Get(utils.KeyInventoryGroups) require.True(t, found) - workspaceIDs, ok := (workspaces).([]string) + inventoryGroupMap, ok := (inventoryGroups).(map[string]string) require.True(t, ok) - require.Greater(t, len(workspaceIDs), 0) - assert.Equal(t, "inventory-group-1", workspaceIDs[0]) + assert.Equal(t, `{"[{\"id\":\"inventory-group-1\"}]"}`, inventoryGroupMap[utils.KeyGrouped]) } func mockXRHID(userType string) *identity.XRHID { diff --git a/manager/middlewares/rbac.go b/manager/middlewares/rbac.go index f52ee297b..7232aff9d 100644 --- a/manager/middlewares/rbac.go +++ b/manager/middlewares/rbac.go @@ -16,12 +16,6 @@ import ( "golang.org/x/exp/slices" ) -const ( - KeyInventoryGroups = "inventoryGroups" - KeyGrouped = "grouped" - KeyUngrouped = "ungrouped" -) - var ( rbacURL = "" httpClient = &http.Client{} @@ -135,7 +129,7 @@ func isAccessGranted(c *gin.Context) bool { utils.LogError("err", err.Error(), "RBAC") granted = false } - c.Set(KeyInventoryGroups, groups) + c.Set(utils.KeyInventoryGroups, groups) } return granted } @@ -174,7 +168,7 @@ func findInventoryGroups(access *rbac.AccessPagination) (map[string]string, erro } for _, v := range rd.AttributeFilter.Value { if v == nil { - res[KeyUngrouped] = "[]" + res[utils.KeyUngrouped] = "[]" continue } group, err := utils.ParseInventoryGroup(v, nil) @@ -188,7 +182,7 @@ func findInventoryGroups(access *rbac.AccessPagination) (map[string]string, erro } if len(groups) > 0 { - res[KeyGrouped] = fmt.Sprintf("{%s}", strings.Join(groups, ",")) + res[utils.KeyGrouped] = fmt.Sprintf("{%s}", strings.Join(groups, ",")) } utils.LogDebug("group_count", len(groups), "processed groups") return res, nil diff --git a/manager/middlewares/rbac_test.go b/manager/middlewares/rbac_test.go index b63efe1b3..aa41641dd 100644 --- a/manager/middlewares/rbac_test.go +++ b/manager/middlewares/rbac_test.go @@ -2,6 +2,7 @@ package middlewares import ( "app/base/rbac" + "app/base/utils" "encoding/json" "net/http" "net/http/httptest" @@ -258,9 +259,9 @@ func TestFindInventoryGroupsGrouped(t *testing.T) { if assert.NoError(t, err) { assert.Equal(t, `{"[{\"id\":\"df57820e-965c-49a6-b0bc-797b7dd60581\"}]"}`, - groups[KeyGrouped], + groups[utils.KeyGrouped], ) - val, ok := groups[KeyUngrouped] + val, ok := groups[utils.KeyUngrouped] assert.Equal(t, "", val) assert.Equal(t, false, ok) } @@ -281,10 +282,10 @@ func TestFindInventoryGroupsUnrouped(t *testing.T) { } groups, err := findInventoryGroups(access) if assert.NoError(t, err) { - val, ok := groups[KeyGrouped] + val, ok := groups[utils.KeyGrouped] assert.Equal(t, "", val) assert.Equal(t, false, ok) - assert.Equal(t, "[]", groups[KeyUngrouped]) + assert.Equal(t, "[]", groups[utils.KeyUngrouped]) } } @@ -305,9 +306,9 @@ func TestFindInventoryGroups(t *testing.T) { if assert.NoError(t, err) { assert.Equal(t, `{"[{\"id\":\"df57820e-965c-49a6-b0bc-797b7dd60581\"}]","[{\"id\":\"df3f0efd-c853-41b5-80a1-86881d5343d1\"}]"}`, - groups[KeyGrouped], + groups[utils.KeyGrouped], ) - assert.Equal(t, "[]", groups[KeyUngrouped]) + assert.Equal(t, "[]", groups[utils.KeyUngrouped]) } } From 2075163139a171775f7379abf5f8fc1e51623547 Mon Sep 17 00:00:00 2001 From: Michael Mraka Date: Wed, 20 May 2026 13:53:39 +0200 Subject: [PATCH 2/2] RHINENG-26529: undo failed schema migration --- .../migrations/153_simplify_workspaces.up.sql | 1 + .../migrations/154_simplify_workspaces.up.sql | 22 +++++++++++++++++++ database_admin/schema/create_schema.sql | 2 +- 3 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 database_admin/migrations/153_simplify_workspaces.up.sql create mode 100644 database_admin/migrations/154_simplify_workspaces.up.sql diff --git a/database_admin/migrations/153_simplify_workspaces.up.sql b/database_admin/migrations/153_simplify_workspaces.up.sql new file mode 100644 index 000000000..a7b4864ba --- /dev/null +++ b/database_admin/migrations/153_simplify_workspaces.up.sql @@ -0,0 +1 @@ +-- noop \ No newline at end of file diff --git a/database_admin/migrations/154_simplify_workspaces.up.sql b/database_admin/migrations/154_simplify_workspaces.up.sql new file mode 100644 index 000000000..bf1bfea0b --- /dev/null +++ b/database_admin/migrations/154_simplify_workspaces.up.sql @@ -0,0 +1,22 @@ +DO $$ +BEGIN +IF EXISTS (SELECT 1 FROM pg_attribute a + JOIN pg_class c ON c.oid = a.attrelid + JOIN pg_namespace n ON n.oid = c.relnamespace + WHERE n.nspname = 'public' AND c.relname = 'system_inventory' AND a.attname = 'workspace_id' + AND a.attnum > 0 AND NOT a.attisdropped) +THEN + ALTER TABLE system_inventory + ADD COLUMN workspaces JSONB; + + UPDATE system_inventory + SET workspaces = JSONB_BUILD_ARRAY(JSONB_BUILD_OBJECT('id', workspace_id, 'name', workspace_name)); + + CREATE INDEX IF NOT EXISTS system_inventory_workspaces_index ON system_inventory USING GIN (workspaces); + + ALTER TABLE system_inventory + DROP COLUMN workspace_id, + DROP COLUMN workspace_name; +END IF; +END $$; + diff --git a/database_admin/schema/create_schema.sql b/database_admin/schema/create_schema.sql index 28a57e442..9486abf78 100644 --- a/database_admin/schema/create_schema.sql +++ b/database_admin/schema/create_schema.sql @@ -7,7 +7,7 @@ CREATE TABLE IF NOT EXISTS schema_migrations INSERT INTO schema_migrations -VALUES (152, false); +VALUES (154, false); -- --------------------------------------------------------------------------- -- Functions