go.mondoo.com/cnquery@v0.0.0-20231005093811-59568235f6ea/_motor/discovery/local/local.go (about)

     1  // Copyright (c) Mondoo, Inc.
     2  // SPDX-License-Identifier: BUSL-1.1
     3  
     4  package local
     5  
     6  import (
     7  	"context"
     8  
     9  	"go.mondoo.com/cnquery/motor/asset"
    10  	"go.mondoo.com/cnquery/motor/discovery/common"
    11  	"go.mondoo.com/cnquery/motor/discovery/docker_engine"
    12  	"go.mondoo.com/cnquery/motor/motorid"
    13  	"go.mondoo.com/cnquery/motor/motorid/hostname"
    14  	"go.mondoo.com/cnquery/motor/platform"
    15  	"go.mondoo.com/cnquery/motor/providers"
    16  	"go.mondoo.com/cnquery/motor/providers/os"
    17  	"go.mondoo.com/cnquery/motor/providers/resolver"
    18  	"go.mondoo.com/cnquery/motor/vault"
    19  )
    20  
    21  type Resolver struct{}
    22  
    23  func (r *Resolver) Name() string {
    24  	return "Local Resolver"
    25  }
    26  
    27  func (r *Resolver) AvailableDiscoveryTargets() []string {
    28  	return []string{
    29  		common.DiscoveryAuto,
    30  		common.DiscoveryAll,
    31  		docker_engine.DiscoveryContainerRunning,
    32  		docker_engine.DiscoveryContainerImages,
    33  	}
    34  }
    35  
    36  func (r *Resolver) Resolve(ctx context.Context, root *asset.Asset, tc *providers.Config, credsResolver vault.Resolver, sfn common.QuerySecretFn, userIdDetectors ...providers.PlatformIdDetector) ([]*asset.Asset, error) {
    37  	assetObj := &asset.Asset{
    38  		Name:        root.Name,
    39  		State:       asset.State_STATE_ONLINE,
    40  		Connections: []*providers.Config{tc},
    41  	}
    42  
    43  	// use hostname as name if asset name was not explicitly provided
    44  	if assetObj.Name == "" {
    45  		assetObj.Name = tc.Host
    46  	}
    47  
    48  	m, err := resolver.NewMotorConnection(ctx, tc, credsResolver)
    49  	if err != nil {
    50  		return nil, err
    51  	}
    52  	defer m.Close()
    53  
    54  	// determine platform information
    55  	p, err := m.Platform()
    56  	if err == nil {
    57  		assetObj.Platform = p
    58  	} else {
    59  		assetObj.Platform = &platform.Platform{}
    60  	}
    61  	assetObj.Platform.Kind = providers.Kind_KIND_BARE_METAL
    62  
    63  	fingerprint, err := motorid.IdentifyPlatform(m.Provider, p, userIdDetectors)
    64  	if err != nil {
    65  		return nil, err
    66  	}
    67  
    68  	assetObj.PlatformIds = fingerprint.PlatformIDs
    69  	if fingerprint.Name != "" && assetObj.Name == "" {
    70  		assetObj.Name = fingerprint.Name
    71  	}
    72  
    73  	if fingerprint.Runtime != "" {
    74  		p.Runtime = fingerprint.Runtime
    75  	}
    76  
    77  	if fingerprint.Kind != providers.Kind_KIND_UNKNOWN {
    78  		p.Kind = fingerprint.Kind
    79  	}
    80  
    81  	for _, pf := range fingerprint.RelatedAssets {
    82  		assetObj.RelatedAssets = append(assetObj.RelatedAssets, &asset.Asset{
    83  			Name:        pf.Name,
    84  			PlatformIds: pf.PlatformIDs,
    85  		})
    86  	}
    87  
    88  	// use hostname as asset name
    89  	if p != nil && assetObj.Name == "" {
    90  		osProvider, isOSProvider := m.Provider.(os.OperatingSystemProvider)
    91  		if isOSProvider {
    92  			// retrieve hostname
    93  			hostname, err := hostname.Hostname(osProvider, p)
    94  			if err == nil && len(hostname) > 0 {
    95  				assetObj.Name = hostname
    96  			}
    97  		}
    98  	}
    99  	assetList := []*asset.Asset{assetObj}
   100  
   101  	// search for container assets on local machine
   102  	if tc.IncludesOneOfDiscoveryTarget(common.DiscoveryAll, docker_engine.DiscoveryContainerRunning, docker_engine.DiscoveryContainerImages) {
   103  		engineAssets, err := docker_engine.DiscoverDockerEngineAssets(tc)
   104  		if err != nil {
   105  			return nil, err
   106  		}
   107  		for _, a := range engineAssets {
   108  			a.RelatedAssets = append(a.RelatedAssets, assetObj)
   109  		}
   110  		assetList = append(assetList, engineAssets...)
   111  	}
   112  
   113  	return assetList, nil
   114  }