Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
arlimus committed Sep 17, 2023
1 parent 7907256 commit 95c25a2
Show file tree
Hide file tree
Showing 7 changed files with 147 additions and 24 deletions.
7 changes: 5 additions & 2 deletions cli/providers/providers.go
Original file line number Diff line number Diff line change
Expand Up @@ -307,15 +307,18 @@ func setConnector(provider *plugin.Provider, connector *plugin.Connector, run fu
if recordingPath == "" {
recordingPath = useRecording
}
doRecord := record != ""

runtime.Recording, err = providers.NewRecording(recordingPath, providers.RecordingOptions{
DoRecord: record != "",
recording, err := providers.NewRecording(recordingPath, providers.RecordingOptions{
DoRecord: doRecord,
PrettyPrintJSON: pretty,
})
if err != nil {
log.Fatal().Msg(err.Error())
}

runtime.SetRecording(recording, provider.ID)

cliRes, err := runtime.Provider.Instance.Plugin.ParseCLI(&plugin.ParseCLIReq{
Connector: connector.Name,
Args: args,
Expand Down
7 changes: 4 additions & 3 deletions providers-sdk/v1/testutils/testutils.go
Original file line number Diff line number Diff line change
Expand Up @@ -219,16 +219,17 @@ func mockRuntimeAbs(testdata string) llx.Runtime {
if err != nil {
panic("failed to load recording: " + err.Error())
}
roRecording := recording.ReadOnly()

err = runtime.SetRecording(recording, runtime.Provider.Instance.ID, true, true)
err = runtime.SetMockRecording(roRecording, runtime.Provider.Instance.ID, true)
if err != nil {
panic("failed to set recording: " + err.Error())
}
err = runtime.SetRecording(recording, networkconf.Config.ID, true, true)
err = runtime.SetMockRecording(roRecording, networkconf.Config.ID, true)
if err != nil {
panic("failed to set recording: " + err.Error())
}
err = runtime.SetRecording(recording, mockprovider.Config.ID, true, true)
err = runtime.SetMockRecording(roRecording, mockprovider.Config.ID, true)
if err != nil {
panic("failed to set recording: " + err.Error())
}
Expand Down
11 changes: 11 additions & 0 deletions providers/builtin.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ package providers
import (
_ "embed"

"go.mondoo.com/cnquery/providers-sdk/v1/resources"
coreconf "go.mondoo.com/cnquery/providers/core/config"
core "go.mondoo.com/cnquery/providers/core/provider"
// osconf "go.mondoo.com/cnquery/providers/os/config"
Expand All @@ -36,6 +37,16 @@ var builtinProviders = map[string]*builtinProvider{
},
Config: &coreconf.Config,
},
mockProvider.ID: {
Runtime: &RunningProvider{
Name: mockProvider.Name,
ID: mockProvider.ID,
Plugin: initMockProvider(),
Schema: &resources.Schema{},
isClosed: false,
},
Config: mockProvider.Provider,
},
// osconf.Config.ID: {
// Runtime: &RunningProvider{
// Name: osconf.Config.Name,
Expand Down
1 change: 0 additions & 1 deletion providers/os.resources.json

This file was deleted.

43 changes: 43 additions & 0 deletions providers/providers.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,44 @@ func ListAll() ([]*Provider, error) {
return all, nil
}

var mockProvider = Provider{
Provider: &plugin.Provider{
Name: "mock",
ID: "go.mondoo.com/cnquery/providers/mock",
Connectors: []plugin.Connector{{
Name: "mock",
Use: "mock",
Short: "use a recording without an active connection",
}},
},
}

type mockProviderService struct{}

func (s *mockProviderService) ParseCLI(req *plugin.ParseCLIReq) (*plugin.ParseCLIRes, error) {
return nil, errors.New("mock doesn't parse CLI")
}

func (s *mockProviderService) Connect(req *plugin.ConnectReq, callback plugin.ProviderCallback) (*plugin.ConnectRes, error) {
panic("NO")
}

func (s *mockProviderService) Shutdown(req *plugin.ShutdownReq) (*plugin.ShutdownRes, error) {
panic("NO")
}

func (s *mockProviderService) GetData(req *plugin.DataReq) (*plugin.DataRes, error) {
panic("NO")
}

func (s *mockProviderService) StoreData(req *plugin.StoreReq) (*plugin.StoreRes, error) {
panic("NO")
}

func initMockProvider() *mockProviderService {
return nil
}

// EnsureProvider find the provider for a given connector either from the list
// of existing proviers or by downloading and installing it.
func EnsureProvider(existing Providers, connectorName string, connectorType string, autoUpdate bool) (*Provider, error) {
Expand All @@ -155,6 +193,11 @@ func EnsureProvider(existing Providers, connectorName string, connectorType stri
return provider, nil
}

if connectorName == "mock" || connectorType == "mock" {
existing.Add(&mockProvider)
return &mockProvider, nil
}

upstream := DefaultProviders.ForConnection(connectorName, connectorType)
if upstream == nil {
// we can't find any provider for this connector in our default set
Expand Down
25 changes: 15 additions & 10 deletions providers/recording.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ type recording struct {
prettyPrintJSON bool `json:"-"`
}

// ReadOnly converts the recording into a read-only recording
func (r *recording) ReadOnly() *readOnlyRecording {
return &readOnlyRecording{r}
}

type assetRecording struct {
Asset assetInfo `json:"asset"`
Connections []connectionRecording `json:"connections"`
Expand All @@ -56,11 +61,11 @@ type assetInfo struct {
}

type connectionRecording struct {
Url string `json:"url"`
Provider string `json:"provider"`
Connector string `json:"connector"`
Version string `json:"version"`
id uint32 `json:"-"`
Url string `json:"url"`
ProviderID string `json:"provider"`
Connector string `json:"connector"`
Version string `json:"version"`
id uint32 `json:"-"`
}

type resourceRecording struct {
Expand Down Expand Up @@ -374,7 +379,7 @@ func (r *recording) findAssetConnID(asset *inventory.Asset, conf *inventory.Conf
return found, id
}

func (r *recording) EnsureAsset(asset *inventory.Asset, provider string, connectionID uint32, conf *inventory.Config) {
func (r *recording) EnsureAsset(asset *inventory.Asset, providerID string, connectionID uint32, conf *inventory.Config) {
found, _ := r.findAssetConnID(asset, conf)

if found == -1 {
Expand Down Expand Up @@ -409,10 +414,10 @@ func (r *recording) EnsureAsset(asset *inventory.Asset, provider string, connect

url := conf.ToUrl()
assetObj.connections[url] = &connectionRecording{
Url: url,
Provider: provider,
Connector: conf.Type,
id: conf.Id,
Url: url,
ProviderID: providerID,
Connector: conf.Type,
id: conf.Id,
}
r.assets[connectionID] = assetObj
}
Expand Down
77 changes: 69 additions & 8 deletions providers/runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ func (r *Runtime) Connect(req *plugin.ConnectReq) error {
if err != nil {
return err
}
r.Recording.EnsureAsset(r.Provider.Connection.Asset, r.Provider.Instance.Name, r.Provider.Connection.Id, asset.Connections[0])
r.Recording.EnsureAsset(r.Provider.Connection.Asset, r.Provider.Instance.ID, r.Provider.Connection.Id, asset.Connections[0])
return nil
}

Expand Down Expand Up @@ -401,19 +401,80 @@ func (p *providerCallbacks) Collect(req *plugin.DataRes) error {
return nil
}

func (r *Runtime) SetRecording(recording *recording, providerID string, readOnly bool, mockConnection bool) error {
if readOnly {
r.Recording = &readOnlyRecording{recording}
} else {
r.Recording = recording
func baseRecording(anyRecording Recording) *recording {
var baseRecording *recording
switch x := anyRecording.(type) {
case *recording:
baseRecording = x
case *readOnlyRecording:
baseRecording = x.recording
}
return baseRecording
}

func (r *Runtime) SetRecording(anyRecording Recording, providerID string) error {
r.Recording = anyRecording
if providerID != mockProvider.ID {
// This is a sanity check, to make sure we didn't set a pseudo-mock connection
// without the mock provider.
if r.Provider == nil || r.Provider.Instance == nil || r.Provider.Instance.ID == "" {
return errors.New("running provider must be set")
}
return nil
}

// At this point it's all about mock recordings. We now have 2 goals:
// 1. make one asset the primary asset for this runtime
// 2. load all schemas for all other connections
base := baseRecording(anyRecording)
if base == nil {
return errors.New("cannot get recording for mock connection, it is required")
}

if len(base.Assets) == 0 {
return errors.New("no asset found in recording")
}
asset := base.Assets[0]

if len(asset.Connections) == 0 {
return errors.New("asset '" + asset.Asset.ID + "' in recording (which is used by default) has no connections")
}

for i := range asset.Connections {
conn := asset.Connections[i]
provider, err := r.addProvider(conn.ProviderID)
if err != nil {
return errors.New("failed to get provider '" + conn.ProviderID + "' which is used for asset '" + asset.Asset.ID + "' in this recording")
}

if i == 0 {
r.Provider = provider
}
r.AddConnectedProvider(provider)

err = r.SetMockRecording(anyRecording, provider.Instance.ID, true)
if err != nil {
panic("failed to set recording: " + err.Error())
}
}

return nil
}

func (r *Runtime) SetMockRecording(anyRecording Recording, providerID string, mockConnection bool) error {
r.Recording = anyRecording

baseRecording := baseRecording(anyRecording)
if baseRecording == nil {
return nil
}

provider, ok := r.providers[providerID]
if !ok {
return errors.New("cannot set recording, provider '" + providerID + "' not found")
}

assetRecording := &recording.Assets[0]
assetRecording := &baseRecording.Assets[0]
asset := assetRecording.Asset.ToInventory()

if mockConnection {
Expand Down Expand Up @@ -442,7 +503,7 @@ func (r *Runtime) SetRecording(recording *recording, providerID string, readOnly
// Dom: we may need to cancel the entire setup here, may need to be reconsidered...
log.Warn().Msg("recording cannot determine asset, no connection was set up!")
} else {
recording.assets[provider.Connection.Id] = assetRecording
baseRecording.assets[provider.Connection.Id] = assetRecording
}

return nil
Expand Down

0 comments on commit 95c25a2

Please sign in to comment.