Skip to content

Commit

Permalink
✨ merge asset.Labels and asset.Platform.Labels
Browse files Browse the repository at this point in the history
We will merge `asset.Labels` and `asset.Platform.Labels` for backwards
compatibility.

Should be removed in v12 when we remove `asset.Platform.Labels`.

Signed-off-by: Salim Afiune Maya <afiune@mondoo.com>
  • Loading branch information
afiune committed Feb 21, 2025
1 parent 2138e1d commit 1ac237d
Show file tree
Hide file tree
Showing 3 changed files with 144 additions and 1 deletion.
7 changes: 6 additions & 1 deletion providers/core/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"go.mondoo.com/cnquery/v11/providers-sdk/v1/upstream"
"go.mondoo.com/cnquery/v11/providers/core/resources"
"go.mondoo.com/cnquery/v11/types"
"go.mondoo.com/cnquery/v11/utils/mapx"
)

const defaultConnection uint32 = 1
Expand Down Expand Up @@ -62,6 +63,10 @@ func (s *Service) Connect(req *plugin.ConnectReq, callback plugin.ProviderCallba
}

asset := req.Asset
// FIXME: remove in v12 (or later) vv
// we merge `asset.Labels` and `asset.Platform.Labels` for backwards compatibility
assetLabelsMergedV11 := mapx.Merge(asset.Labels, asset.Platform.Labels)
// ^^
_, err = resources.CreateResource(runtime, "asset", map[string]*llx.RawData{
"ids": llx.ArrayData(llx.TArr2Raw(asset.PlatformIds), types.String),
"platform": llx.StringData(asset.Platform.Name),
Expand All @@ -73,7 +78,7 @@ func (s *Service) Connect(req *plugin.ConnectReq, callback plugin.ProviderCallba
"title": llx.StringData(asset.Platform.PrettyTitle()),
"family": llx.ArrayData(llx.TArr2Raw(asset.Platform.Family), types.String),
"build": llx.StringData(asset.Platform.Build),
"labels": llx.MapData(llx.TMap2Raw(asset.Labels), types.String),
"labels": llx.MapData(llx.TMap2Raw(assetLabelsMergedV11), types.String),
"platformMetadata": llx.MapData(llx.TMap2Raw(asset.Platform.Labels), types.String),
"annotations": llx.MapData(llx.TMap2Raw(asset.Annotations), types.String),
"fqdn": llx.StringData(asset.Fqdn),
Expand Down
21 changes: 21 additions & 0 deletions utils/mapx/merge.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright (c) Mondoo, Inc.
// SPDX-License-Identifier: BUSL-1.1

package mapx

// Merge merges two maps of type `map[K]T` giving preference to the first map.
func Merge[K comparable, V any](m1, m2 map[K]V) map[K]V {
merged := make(map[K]V)

// store all key:value's from the second map
for key, value := range m2 {
merged[key] = value
}

// iterate over the first map to give it preference
for key, value := range m1 {
merged[key] = value
}

return merged
}
117 changes: 117 additions & 0 deletions utils/mapx/merge_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
// Copyright (c) Mondoo, Inc.
// SPDX-License-Identifier: BUSL-1.1

package mapx_test

import (
"testing"

subject "go.mondoo.com/cnquery/v11/utils/mapx"

"github.com/stretchr/testify/assert"
)

func TestMerge(t *testing.T) {
t.Run("map[string]int", func(t *testing.T) {
tests := []struct {
name string
m1, m2 map[string]int
expected map[string]int
}{
{
name: "Merge with nil maps",
m1: map[string]int{"a": 1},
m2: nil,
expected: map[string]int{"a": 1},
},
{
name: "Merge with no conflicts",
m1: map[string]int{"a": 1, "b": 2},
m2: map[string]int{"c": 3, "d": 4},
expected: map[string]int{"a": 1, "b": 2, "c": 3, "d": 4},
},
{
name: "Merge with conflicts, prefer first map",
m1: map[string]int{"a": 10, "b": 20},
m2: map[string]int{"a": 1, "b": 2, "c": 3},
expected: map[string]int{"a": 10, "b": 20, "c": 3},
},
{
name: "First map empty",
m1: map[string]int{},
m2: map[string]int{"x": 100, "y": 200},
expected: map[string]int{"x": 100, "y": 200},
},
{
name: "Second map empty",
m1: map[string]int{"x": 100, "y": 200},
m2: map[string]int{},
expected: map[string]int{"x": 100, "y": 200},
},
{
name: "Both maps empty",
m1: map[string]int{},
m2: map[string]int{},
expected: map[string]int{},
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := subject.Merge(tt.m1, tt.m2)
assert.Equal(t, tt.expected, result)
})
}
})

t.Run("map[string]string", func(t *testing.T) {
tests := []struct {
name string
m1, m2 map[string]string
expected map[string]string
}{
{
name: "Merge with nil maps",
m1: nil,
m2: map[string]string{"a": "coco"},
expected: map[string]string{"a": "coco"},
},
{
name: "Merge two non-empty maps with string keys",
m1: map[string]string{"a": "apple", "b": "banana"},
m2: map[string]string{"b": "BLUEBERRY", "c": "cherry"},
expected: map[string]string{"a": "apple", "b": "banana", "c": "cherry"},
},
{
name: "Merge with an empty first map",
m1: map[string]string{},
m2: map[string]string{"a": "apple", "b": "banana"},
expected: map[string]string{"a": "apple", "b": "banana"},
},
{
name: "Merge with an empty second map",
m1: map[string]string{"a": "apple", "b": "banana"},
m2: map[string]string{},
expected: map[string]string{"a": "apple", "b": "banana"},
},
{
name: "Merge two empty maps",
m1: map[string]string{},
m2: map[string]string{},
expected: map[string]string{},
},
{
name: "Merge two nil maps",
m1: nil,
m2: nil,
expected: map[string]string{},
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert.Equal(t, tt.expected, subject.Merge(tt.m1, tt.m2))
})
}
})
}

0 comments on commit 1ac237d

Please sign in to comment.