Skip to content

Commit

Permalink
⭐ add TechnologyUrl to platform + AssetUrlTrees to provider (#3540)
Browse files Browse the repository at this point in the history
* ⭐ add TechnologyUrl to platform + AssetUrlTrees to provider

1. Providers are extended to define their AssetUrlTrees. These are part
   of the config and can be loaded statically. This allows developers to
   define and extend existing AssetUrlTrees. Note that we currently
   maintain a `/technology=X` asset tree. We are in the process of
   adding all providers to this grouping strategy.
2. Extend the inventory definition of the asset `Platform` to include
   the TechnologyUrl. While assets may belong to a multitude of URLs,
   the platform definition only focuses on the technology URL.
3. Implement both for the `os` provider. Note: Initially this was
   designed to define the entire tree of URLs, including all OS names
   and versions. I noticed, however, that the structure of the tree
   doesn't change by different OS families, names, or versions, at all.
   Thus, we use `*` to allow for arbitrary terms, as these terms won't
   have any impact on the remaining URL.

Signed-off-by: Dominik Richter <[email protected]>

* 🧹 check against platform name or version being empty

Signed-off-by: Dominik Richter <[email protected]>

---------

Signed-off-by: Dominik Richter <[email protected]>
  • Loading branch information
arlimus authored Mar 13, 2024
1 parent d03b6fd commit 00f3bbb
Show file tree
Hide file tree
Showing 6 changed files with 302 additions and 192 deletions.
368 changes: 191 additions & 177 deletions providers-sdk/v1/inventory/inventory.pb.go

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions providers-sdk/v1/inventory/inventory.proto
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ message AssetUrlBranch {
uint32 depth = 20;
// internal only: parent relationships
AssetUrlBranch parent = 21;
// internal only: how this branch is connected in the parent's value field
string parent_value = 22;
}

Expand Down Expand Up @@ -294,6 +295,8 @@ message Platform {
string build = 6;
string version = 7;
string kind = 8;
// technology url for this asset, raw version of an AssetUrl
repeated string technology_url_segments = 9;

// FIXME: DEPRECATED, remove in v10 vv
DeprecatedV8_Kind deprecated_v8_kind = 20;
Expand Down
2 changes: 2 additions & 0 deletions providers-sdk/v1/plugin/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/rs/zerolog/log"
"github.com/spf13/pflag"
"go.mondoo.com/cnquery/v10/logger"
inventory "go.mondoo.com/cnquery/v10/providers-sdk/v1/inventory"
)

type Provider struct {
Expand All @@ -31,6 +32,7 @@ type Provider struct {
// call out.
CrossProviderTypes []string
Connectors []Connector
AssetUrlTrees []*inventory.AssetUrlBranch
}

type Connector struct {
Expand Down
37 changes: 37 additions & 0 deletions providers/os/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
package config

import (
"go.mondoo.com/cnquery/v10/providers-sdk/v1/inventory"
"go.mondoo.com/cnquery/v10/providers-sdk/v1/plugin"
"go.mondoo.com/cnquery/v10/providers/os/connection/shared"
"go.mondoo.com/cnquery/v10/providers/os/resources/discovery/docker_engine"
Expand Down Expand Up @@ -248,4 +249,40 @@ var Config = plugin.Provider{
},
},
},
AssetUrlTrees: []*inventory.AssetUrlBranch{
{
PathSegments: []string{"technology=os"},
Key: "family",
Title: "Family",
Values: map[string]*inventory.AssetUrlBranch{
// linux, windows, darwin, unix, ...
"*": {
Key: "platform",
Title: "Platform",
Values: map[string]*inventory.AssetUrlBranch{
// redhat, arch, ...
"*": {
Key: "version",
Title: "Version",
Values: map[string]*inventory.AssetUrlBranch{
// any valid version for the OS
"*": nil,
},
},
},
},
},
},
{
PathSegments: []string{"technology=container"},
Key: "kind",
Title: "Kind",
Values: map[string]*inventory.AssetUrlBranch{
// container-image, container, ...
"*": {
References: []string{"technology=os"},
},
},
},
},
}
58 changes: 56 additions & 2 deletions providers/os/detector/detector.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,64 @@ import (
)

func DetectOS(conn shared.Connection) (*inventory.Platform, bool) {
var res *inventory.Platform
var ok bool
if conn.Type() == shared.Type_Local && runtime.GOOS == "windows" {
return WindowsFamily.Resolve(conn)
res, ok = WindowsFamily.Resolve(conn)
} else {
res, ok = OperatingSystems.Resolve(conn)
}
return OperatingSystems.Resolve(conn)

addTechnologyUrl(res)
return res, ok
}

// returns a primary family for the platform, e.g. linux, windows, osx, etc
// platform must be non-nil
func primaryFamily(platform *inventory.Platform) string {
families := platform.Family
for len(families) != 0 {
last := families[0]
switch last {
case "windows":
return "windows"
case "linux":
return "linux"
case "darwin":
return "darwin"
case "unix":
return "unix"
}

families = families[1:]
}

return "other"
}

func addTechnologyUrl(platform *inventory.Platform) {
if platform == nil {
return
}

if platform.Kind == "container-image" {
platform.TechnologyUrlSegments = []string{
// technology, kind
"container", platform.Kind,
}
} else {
platform.TechnologyUrlSegments = []string{"os"}
}

if platform.Name == "" {
platform.Name = "unknown"
}
if platform.Version == "" {
platform.Version = "unknown"
}

platform.TechnologyUrlSegments = append(platform.TechnologyUrlSegments,
primaryFamily(platform), platform.Name, platform.Version)
}

// map that is organized by platform name, to quickly determine its families
Expand Down
26 changes: 13 additions & 13 deletions providers/os/detector/platform_resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,39 +22,39 @@ type PlatformResolver struct {

func (r *PlatformResolver) Resolve(conn shared.Connection) (*inventory.Platform, bool) {
// prepare detect info object
di := &inventory.Platform{}
di.Family = make([]string, 0)
platform := &inventory.Platform{}
platform.Family = make([]string, 0)

// start recursive platform resolution
pi, resolved := r.resolvePlatform(di, conn)
pi, resolved := r.resolvePlatform(platform, conn)

// if we have a container image use the architecture specified in the transport as it is resolved
// using the container image properties
tarConn, ok := conn.(*tar.Connection)
if resolved && ok {
pi.Arch = tarConn.PlatformArchitecture
di.Runtime = "docker-image"
di.Kind = "container-image"
platform.Runtime = "docker-image"
platform.Kind = "container-image"

// if the platform name is not set, we should fallback to the scratch operating system
if len(pi.Name) == 0 {
di.Name = "scratch"
di.Arch = tarConn.PlatformArchitecture
return di, true
platform.Name = "scratch"
platform.Arch = tarConn.PlatformArchitecture
return platform, true
}
}

containerConn, ok := conn.(*docker.ContainerConnection)
if resolved && ok {
pi.Arch = containerConn.PlatformArchitecture
di.Runtime = string(containerConn.Type())
di.Kind = "container"
platform.Runtime = string(containerConn.Type())
platform.Kind = "container"

// if the platform name is not set, we should fallback to the scratch operating system
if len(pi.Name) == 0 {
di.Name = "scratch"
di.Arch = pi.Arch
return di, true
platform.Name = "scratch"
platform.Arch = pi.Arch
return platform, true
}
}

Expand Down

0 comments on commit 00f3bbb

Please sign in to comment.