go.mondoo.com/cnquery@v0.0.0-20231005093811-59568235f6ea/providers-sdk/v1/inventory/manager/credentials_query.go (about) 1 // Copyright (c) Mondoo, Inc. 2 // SPDX-License-Identifier: BUSL-1.1 3 4 package manager 5 6 import ( 7 "strings" 8 9 "github.com/cockroachdb/errors" 10 "github.com/mitchellh/mapstructure" 11 "github.com/rs/zerolog/log" 12 "go.mondoo.com/cnquery" 13 "go.mondoo.com/cnquery/llx" 14 "go.mondoo.com/cnquery/mql" 15 "go.mondoo.com/cnquery/providers-sdk/v1/inventory" 16 "go.mondoo.com/cnquery/providers-sdk/v1/vault" 17 "go.mondoo.com/cnquery/types" 18 ) 19 20 type CredentialQueryResponse struct { 21 // maps to credentials 22 Type string `json:"type,omitempty"` 23 User string `json:"user,omitempty"` // user associated with the secret 24 SecretId string `json:"secret_id,omitempty"` // id to use to fetch the secret from the source vault 25 } 26 27 func NewCredentialQueryRunner(credentialQuery string, runtime llx.Runtime) (*CredentialQueryRunner, error) { 28 mqlExecutor := mql.New(runtime, cnquery.DefaultFeatures) 29 30 // just empty props to ensure we can compile 31 props := map[string]*llx.Primitive{ 32 "mrn": llx.StringPrimitive(""), 33 "name": llx.StringPrimitive(""), 34 "labels": llx.MapData(map[string]interface{}{}, types.String).Result().Data, 35 "platform": llx.MapData(map[string]interface{}{}, types.String).Result().Data, 36 } 37 38 // test query to see if it compiles well 39 _, err := mql.Exec(credentialQuery, runtime, nil, props) 40 if err != nil { 41 return nil, errors.Wrap(err, "could not compile the secret metadata function") 42 } 43 return &CredentialQueryRunner{ 44 mqlExecutor: mqlExecutor, 45 secretMetadataQuery: credentialQuery, 46 }, nil 47 } 48 49 type CredentialQueryRunner struct { 50 mqlExecutor *mql.Executor 51 secretMetadataQuery string 52 } 53 54 func (sq *CredentialQueryRunner) Run(a *inventory.Asset) (*vault.Credential, error) { 55 // map labels to props 56 labelProps := map[string]interface{}{} 57 labels := a.GetLabels() 58 for k, v := range labels { 59 labelProps[k] = v 60 } 61 62 // map platform to props 63 var platformProps map[string]interface{} 64 if a.Platform != nil { 65 platformProps = map[string]interface{}{ 66 "name": a.Platform.Name, 67 "release": a.Platform.Version, 68 "arch": a.Platform.Arch, 69 } 70 } else { 71 platformProps = map[string]interface{}{} 72 } 73 74 props := map[string]*llx.Primitive{ 75 "mrn": llx.StringPrimitive(a.Mrn), 76 "name": llx.StringPrimitive(a.Name), 77 "labels": llx.MapData(labelProps, types.String).Result().Data, 78 "platform": llx.MapData(platformProps, types.String).Result().Data, 79 } 80 81 value, err := sq.mqlExecutor.Exec(sq.secretMetadataQuery, props) 82 if err != nil { 83 return nil, err 84 } 85 86 sMeta := &CredentialQueryResponse{} 87 decoder, _ := mapstructure.NewDecoder(&mapstructure.DecoderConfig{ 88 Metadata: nil, 89 Result: sMeta, 90 TagName: "json", 91 }) 92 err = decoder.Decode(value.Value) 93 94 code, ok := vault.CredentialType_value[strings.TrimSpace(sMeta.Type)] 95 if !ok { 96 log.Warn().Str("credential_type", sMeta.Type).Msg("unknown credential type used in credential query") 97 } 98 99 creds := &vault.Credential{ 100 Type: vault.CredentialType(code), 101 User: sMeta.User, 102 SecretId: sMeta.SecretId, 103 } 104 105 return creds, err 106 }