diff --git a/.gitignore b/.gitignore index 5a79fa32..29b7a34a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .bin *.out.json ginkgo.report -.vscode \ No newline at end of file +.vscode +tests/ diff --git a/models/config.go b/models/config.go index 2506ec5e..826c2489 100644 --- a/models/config.go +++ b/models/config.go @@ -346,7 +346,19 @@ const ( ) type RelatedConfig struct { - Relation string `json:"relation"` - Type RelatedConfigType `json:"relation_type" gorm:"column:relation_type"` - Config types.JSONMap `json:"config"` + Relation string `json:"relation"` + RelationType RelatedConfigType `json:"relation_type"` + ID uuid.UUID `json:"id"` + Name string `json:"name"` + Type string `json:"type"` + Tags types.JSONStringMap `json:"tags"` + Changes *types.JSONMap `json:"changes,omitempty"` + Analysis *types.JSONMap `json:"analysis,omitempty"` + CostPerMinute *float64 `json:"cost_per_minute,omitempty"` + CostTotal1d *float64 `json:"cost_total_1d,omitempty"` + CostTotal7d *float64 `json:"cost_total_7d,omitempty"` + CostTotal30d *float64 `json:"cost_total_30d,omitempty"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + AgentID uuid.UUID `json:"agent_id"` } diff --git a/tests/config_relationship_test.go b/tests/config_relationship_test.go index 217310a0..18ef43e9 100644 --- a/tests/config_relationship_test.go +++ b/tests/config_relationship_test.go @@ -104,7 +104,7 @@ var _ = ginkgo.Describe("Config relationship recursive", ginkgo.Ordered, func() Expect(err).To(BeNil()) Expect(len(relatedConfigs)).To(Equal(1)) - Expect(relatedConfigs[0].Config["id"].(string)).To(Equal(F.ID.String())) + Expect(relatedConfigs[0].ID.String()).To(Equal(F.ID.String())) }) ginkgo.It("should correctly return zero relationships for leaf nodes", func() { @@ -120,7 +120,7 @@ var _ = ginkgo.Describe("Config relationship recursive", ginkgo.Ordered, func() Expect(err).To(BeNil()) Expect(len(relatedConfigs)).To(Equal(7)) - relatedIDs := lo.Map(relatedConfigs, func(rc models.RelatedConfig, _ int) uuid.UUID { return uuid.MustParse(rc.Config["id"].(string)) }) + relatedIDs := lo.Map(relatedConfigs, func(rc models.RelatedConfig, _ int) uuid.UUID { return rc.ID }) Expect(relatedIDs).To(HaveExactElements([]uuid.UUID{B.ID, C.ID, D.ID, E.ID, F.ID, G.ID, H.ID})) }) }) @@ -132,7 +132,7 @@ var _ = ginkgo.Describe("Config relationship recursive", ginkgo.Ordered, func() Expect(err).To(BeNil()) Expect(len(relatedConfigs)).To(Equal(5)) - relatedIDs := lo.Map(relatedConfigs, func(rc models.RelatedConfig, _ int) uuid.UUID { return uuid.MustParse(rc.Config["id"].(string)) }) + relatedIDs := lo.Map(relatedConfigs, func(rc models.RelatedConfig, _ int) uuid.UUID { return rc.ID }) Expect(relatedIDs).To(HaveExactElements([]uuid.UUID{C.ID, A.ID, H.ID, D.ID, B.ID})) }) @@ -141,7 +141,7 @@ var _ = ginkgo.Describe("Config relationship recursive", ginkgo.Ordered, func() err := DefaultContext.DB().Raw("SELECT * FROM related_configs_recursive(?, 'incoming', false)", G.ID).Find(&relatedConfigs).Error Expect(err).To(BeNil()) - relatedIDs := lo.Map(relatedConfigs, func(rc models.RelatedConfig, _ int) uuid.UUID { return uuid.MustParse(rc.Config["id"].(string)) }) + relatedIDs := lo.Map(relatedConfigs, func(rc models.RelatedConfig, _ int) uuid.UUID { return rc.ID }) Expect(relatedIDs).To(HaveExactElements([]uuid.UUID{D.ID, B.ID, A.ID, H.ID})) }) }) @@ -155,7 +155,7 @@ var _ = ginkgo.Describe("Config relationship recursive", ginkgo.Ordered, func() Expect(err).To(BeNil()) Expect(len(relatedConfigs)).To(Equal(5)) - relatedIDs := lo.Map(relatedConfigs, func(rc models.RelatedConfig, _ int) uuid.UUID { return uuid.MustParse(rc.Config["id"].(string)) }) + relatedIDs := lo.Map(relatedConfigs, func(rc models.RelatedConfig, _ int) uuid.UUID { return rc.ID }) Expect(relatedIDs).To(HaveExactElements([]uuid.UUID{V.ID, W.ID, X.ID, Y.ID, Z.ID})) }) }) @@ -174,7 +174,7 @@ var _ = ginkgo.Describe("Config relationship recursive", ginkgo.Ordered, func() Expect(err).To(BeNil()) Expect(len(relatedConfigs)).To(Equal(3)) - relatedIDs := lo.Map(relatedConfigs, func(rc models.RelatedConfig, _ int) uuid.UUID { return uuid.MustParse(rc.Config["id"].(string)) }) + relatedIDs := lo.Map(relatedConfigs, func(rc models.RelatedConfig, _ int) uuid.UUID { return rc.ID }) Expect(relatedIDs).To(HaveExactElements([]uuid.UUID{X.ID, V.ID, U.ID})) }) }) @@ -191,7 +191,7 @@ var _ = ginkgo.Describe("Config relationship", ginkgo.Ordered, func() { for _, rc := range relatedConfigs { Expect(rc.Relation).To(Equal("ClusterNode")) Expect(rc.Type).To(Equal(models.RelatedConfigTypeOutgoing)) - Expect(rc.Config["id"]).To(BeElementOf([]string{dummy.KubernetesNodeA.ID.String(), dummy.KubernetesNodeB.ID.String()})) + Expect(rc.ID.String()).To(BeElementOf([]string{dummy.KubernetesNodeA.ID.String(), dummy.KubernetesNodeB.ID.String()})) } }) @@ -203,6 +203,6 @@ var _ = ginkgo.Describe("Config relationship", ginkgo.Ordered, func() { Expect(len(relatedConfigs)).To(Equal(1)) Expect(relatedConfigs[0].Relation).To(Equal("ClusterNode")) Expect(relatedConfigs[0].Type).To(Equal(models.RelatedConfigTypeIncoming)) - Expect(relatedConfigs[0].Config["id"]).To(Equal(dummy.KubernetesCluster.ID.String())) + Expect(relatedConfigs[0].ID.String()).To(Equal(dummy.KubernetesCluster.ID.String())) }) }) diff --git a/views/006_config_views.sql b/views/006_config_views.sql index 2cb23e25..ec643ed8 100644 --- a/views/006_config_views.sql +++ b/views/006_config_views.sql @@ -491,33 +491,44 @@ CREATE FUNCTION related_configs ( config_id UUID, type_filter TEXT DEFAULT 'all', include_deleted_configs BOOLEAN DEFAULT FALSE -) -RETURNS TABLE ( +) RETURNS TABLE ( relation TEXT, relation_type TEXT, - config JSONB -) AS $$ + id uuid, + NAME TEXT, + TYPE TEXT, + tags jsonb, + changes json, + analysis json, + cost_per_minute NUMERIC(16, 4), + cost_total_1d NUMERIC(16, 4), + cost_total_7d NUMERIC(16, 4), + cost_total_30d NUMERIC(16, 4), + created_at TIMESTAMP WITH TIME ZONE, + updated_at TIMESTAMP WITH TIME ZONE, + agent_id uuid +) + AS $$ BEGIN RETURN query SELECT r.relation, r.relation_type, - jsonb_build_object( - 'id', c.id, - 'name', c.name, - 'type', c.type, - 'tags', c.tags, - 'changes', c.changes, - 'analysis', c.analysis, - 'cost_per_minute', c.cost_per_minute, - 'cost_total_1d', c.cost_total_1d, - 'cost_total_7d', c.cost_total_7d, - 'cost_total_30d', c.cost_total_30d, - 'created_at', c.created_at, - 'updated_at', c.updated_at - ) AS config + configs.id, + configs.name, + configs.type, + configs.tags, + configs.changes, + configs.analysis, + configs.cost_per_minute, + configs.cost_total_1d, + configs.cost_total_7d, + configs.cost_total_30d, + configs.created_at, + configs.updated_at, + configs.agent_id FROM related_config_ids($1, $2, $3) as r - LEFT JOIN configs AS c ON r.id = c.id; + LEFT JOIN configs ON r.id = configs.id; END; $$ LANGUAGE plpgsql; @@ -559,28 +570,43 @@ CREATE FUNCTION related_configs_recursive ( config_id UUID, type_filter TEXT DEFAULT 'outgoing', include_deleted_configs BOOLEAN DEFAULT FALSE -) RETURNS TABLE (relation TEXT, relation_type TEXT, config JSONB) AS $$ +) RETURNS TABLE ( + relation TEXT, + relation_type TEXT, + id uuid, + name TEXT, + type TEXT, + tags jsonb, + changes json, + analysis json, + cost_per_minute NUMERIC(16, 4), + cost_total_1d NUMERIC(16, 4), + cost_total_7d NUMERIC(16, 4), + cost_total_30d NUMERIC(16, 4), + created_at TIMESTAMP WITH TIME ZONE, + updated_at TIMESTAMP WITH TIME ZONE, + agent_id uuid +) AS $$ BEGIN RETURN query SELECT r.relation, r.relation_type, - jsonb_build_object( - 'id', c.id, - 'name', c.name, - 'type', c.type, - 'tags', c.tags, - 'changes', c.changes, - 'analysis', c.analysis, - 'cost_per_minute', c.cost_per_minute, - 'cost_total_1d', c.cost_total_1d, - 'cost_total_7d', c.cost_total_7d, - 'cost_total_30d', c.cost_total_30d, - 'created_at', c.created_at, - 'updated_at', c.updated_at - ) AS config + configs.id, + configs.name, + configs.type, + configs.tags, + configs.changes, + configs.analysis, + configs.cost_per_minute, + configs.cost_total_1d, + configs.cost_total_7d, + configs.cost_total_30d, + configs.created_at, + configs.updated_at, + configs.agent_id FROM related_config_ids_recursive($1, $2, $3) as r - LEFT JOIN configs AS c ON r.id = c.id; + LEFT JOIN configs ON r.id = configs.id; END; $$ LANGUAGE plpgsql;