Skip to content

Commit

Permalink
🐛 fix error when cloning resources (#1923)
Browse files Browse the repository at this point in the history
Mandatory arguments were never submitted, because the new provider concept meant that we had to request all the fields individually. We were missing a good pattern to execute this.

Turns out the CreateResourceWithID was only used in one place and its primary purpose was to clone the resource. This method has now been adjusted to better reflect its purpose and its arguments can now do the heavy lifting or getting all the necessary fields for cloning the resource. This method can be further refined to grab mandatory fields automatically.

Signed-off-by: Dominik Richter <[email protected]>
  • Loading branch information
arlimus authored Sep 26, 2023
1 parent 970e46f commit a2b4ee9
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 13 deletions.
17 changes: 6 additions & 11 deletions llx/builtin_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"strconv"
"time"

"github.com/rs/zerolog/log"
"go.mondoo.com/cnquery/types"
)

Expand Down Expand Up @@ -86,21 +85,17 @@ func _resourceWhereV2(e *blockExecutor, bind *RawData, chunk *Chunk, ref uint64,

// get all mandatory args
resourceInfo := e.ctx.runtime.Schema().Lookup(resource.MqlName())
args := map[string]*Primitive{
"list": ArrayPrimitive(resList, ct),
}
copyFields := []string{}
for k, v := range resourceInfo.Fields {
if k != "list" && v.IsMandatory {
log.Error().Msg("found a mandatory argument for list, which is not supported: " + k + " for list of " + resource.MqlName())
// e.ctx.runtime.WatchAndUpdate(resource, k, blockId, func(res interface{}, err error) {
// if err == nil {
// args[k] = v
// }
// })
copyFields = append(copyFields, k)
}
}
args := map[string]*Primitive{
"list": ArrayPrimitive(resList, ct),
}

resResource, err := e.ctx.runtime.CreateResourceWithID(resource.MqlName(), blockId, args)
resResource, err := e.ctx.runtime.CloneResource(resource, blockId, copyFields, args)

var data *RawData
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion llx/runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ type Runtime interface {
AssetMRN() string
Unregister(watcherUID string) error
CreateResource(name string, args map[string]*Primitive) (Resource, error)
CreateResourceWithID(name string, id string, args map[string]*Primitive) (Resource, error)
CloneResource(src Resource, id string, fields []string, args map[string]*Primitive) (Resource, error)
WatchAndUpdate(resource Resource, field string, watcherUID string, callback func(res interface{}, err error)) error
Schema() Schema
Close()
Expand Down
19 changes: 18 additions & 1 deletion providers/runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -260,12 +260,29 @@ func (r *Runtime) CreateResource(name string, args map[string]*llx.Primitive) (l
return &llx.MockResource{Name: typ.ResourceName(), ID: string(res.Data.Value)}, nil
}

func (r *Runtime) CreateResourceWithID(name string, id string, args map[string]*llx.Primitive) (llx.Resource, error) {
func (r *Runtime) CloneResource(src llx.Resource, id string, fields []string, args map[string]*llx.Primitive) (llx.Resource, error) {
name := src.MqlName()
srcID := src.MqlID()

provider, _, err := r.lookupResourceProvider(name)
if err != nil {
return nil, err
}

for i := range fields {
field := fields[i]
data, err := provider.Instance.Plugin.GetData(&plugin.DataReq{
Connection: provider.Connection.Id,
Resource: name,
ResourceId: srcID,
Field: field,
})
if err != nil {
return nil, err
}
args[field] = data.Data
}

args["__id"] = llx.StringPrimitive(id)

_, err = provider.Instance.Plugin.StoreData(&plugin.StoreReq{
Expand Down

0 comments on commit a2b4ee9

Please sign in to comment.