mondoohq / cnquery

open source, cloud-native, graph-based asset inventory
https://cnquery.io
Other
312 stars 21 forks source link

Cross provider communication #2632

Open chris-rock opened 11 months ago

chris-rock commented 11 months ago

Is your feature request related to a problem? Please describe.

Currently we limited the cross provider communication to a very specific set of providers. We would need to loosen the restriction for https://github.com/mondoohq/cnquery/blob/main/providers/runtime.go#L579-L582.

This would unblock us on https://github.com/mondoohq/cnquery/pull/2201.

Describe the solution you'd like

Ability to call resources from another provider. There will be the challenge for the providers to understand each others connection. We need to see how we handle that properly.

arlimus commented 11 months ago

Heya, adding a description here for an approach to make this work.

Analysis

Cross-provider calls come in 2 shapes: connection-extenders and child-connectors.

Connection-extenders

This is useful when you have an existing connection and want to add another (one) provider to this (one) connection. This means, that a connection with an asset may have additional connections to other providers added to it.

For example: When you connect to a local system, you have an established os+local connection. It is useful to extend this connection with the network provider, to natively answer queries within the scope of this asset.

This approach works as long as we only have:

Child-connectors

This is useful when targeting multiple other assets from within one connection. These child assets can be of the same provider type as the caller or of an entirely different provider type.

Example 1: When we list docker containers, each container is its own asset. Thus, we can create a new connection per child container, which provides the container contents. The query can span multiple assets and later cache these calls. Container scanning is done via the os provider too, thus showing that this is an example using the os provider and multiple connections within it.

Approach

Within these approaches, I recommend we implement Connection-extenders first and save child-connectors for later. The referenced ticket that raised this originally ( https://github.com/mondoohq/cnquery/pull/2201 ) looks like it would work with a shared connection.

Connection-extenders

We want to keep track of connections that are getting extended in the runtime, so things can be properly shut down again. Providers need to explicitly request a connection extension via proto:

message CrossConnectReq {
  Asset asset = 1;
}

service ProviderCallback {
  ...
  rpc CrossConnect(CrossConnectReq) returns (ConnectRes);
}


Since these calls are made via the plugin runtime, we turn them into proper connect calls by adding all required fields (recordings, callback server, upstream, features etc).

Additionally, the providers keep track of connections they have established, as well as failures they encoutered in establishing connections. If a CrossConnect call fails it doesn't need to be retried in this iteration. We do however need to make sure errors are properly reported. Failures in the cross-connect do not abort the entire execution, but they turn into resource errors.

**Initial CrossConnectors**

- os to cross-connect into network
- azure to cross-connect into ms365

**Exception**

The one notable exception to all this is the core provider. Users do not explicitly need to establish it, since the plugin runtime will always establish it for every provider. The idea for the cross-provider connection is to mix/combine providers other than the core provider.

## Final thoughts

This write-up is not meant to be final - any feedback and other ideas are warmly appreciated!