go.mondoo.com/cnquery@v0.0.0-20231005093811-59568235f6ea/providers/os/provider/detector.go (about)

     1  // Copyright (c) Mondoo, Inc.
     2  // SPDX-License-Identifier: BUSL-1.1
     3  
     4  package provider
     5  
     6  import (
     7  	"errors"
     8  
     9  	"github.com/rs/zerolog/log"
    10  	"go.mondoo.com/cnquery/providers-sdk/v1/inventory"
    11  	"go.mondoo.com/cnquery/providers/os/connection/shared"
    12  	"go.mondoo.com/cnquery/providers/os/detector"
    13  	"go.mondoo.com/cnquery/providers/os/id/aws"
    14  	"go.mondoo.com/cnquery/providers/os/id/azure"
    15  	"go.mondoo.com/cnquery/providers/os/id/gcp"
    16  	"go.mondoo.com/cnquery/providers/os/id/hostname"
    17  	"go.mondoo.com/cnquery/providers/os/id/ids"
    18  	"go.mondoo.com/cnquery/providers/os/id/machineid"
    19  	"go.mondoo.com/cnquery/providers/os/id/sshhostkey"
    20  )
    21  
    22  // default id detectors
    23  var IdDetectors = []string{
    24  	ids.IdDetector_Hostname,
    25  	ids.IdDetector_CloudDetect,
    26  	ids.IdDetector_SshHostkey,
    27  }
    28  
    29  func hasDetector(detectors map[string]struct{}, any ...string) bool {
    30  	for i := range any {
    31  		if _, ok := detectors[any[i]]; ok {
    32  			return true
    33  		}
    34  	}
    35  	return false
    36  }
    37  
    38  func mapDetectors(raw []string) map[string]struct{} {
    39  	if len(raw) == 0 {
    40  		raw = IdDetectors
    41  	}
    42  	res := make(map[string]struct{}, len(raw))
    43  	for _, v := range raw {
    44  		res[v] = struct{}{}
    45  	}
    46  	return res
    47  }
    48  
    49  func (s *Service) detect(asset *inventory.Asset, conn shared.Connection) error {
    50  	var ok bool
    51  	asset.Platform, ok = detector.DetectOS(conn)
    52  	if !ok {
    53  		return errors.New("failed to detect OS")
    54  	}
    55  	if asset.Platform.Kind == "" {
    56  		asset.Platform.Kind = "baremetal"
    57  	}
    58  	if asset.Connections[0].Runtime == "vagrant" {
    59  		// detect overrides this
    60  		asset.Platform.Kind = "virtualmachine"
    61  	}
    62  
    63  	var detectors map[string]struct{}
    64  	if asset.Platform.Kind != "container-image" {
    65  		detectors = mapDetectors(asset.IdDetector)
    66  	}
    67  
    68  	if hasDetector(detectors, ids.IdDetector_Hostname) {
    69  		log.Debug().Msg("run hostname id detector")
    70  		if id, ok := hostname.Hostname(conn, asset.Platform); ok {
    71  			asset.PlatformIds = append(asset.PlatformIds, id)
    72  		}
    73  	}
    74  
    75  	if hasDetector(detectors, ids.IdDetector_CloudDetect) {
    76  		log.Debug().Msg("run cloud platform detector")
    77  		if id, name, related := aws.Detect(conn, asset.Platform); id != "" {
    78  			asset.PlatformIds = append(asset.PlatformIds, id)
    79  			asset.Platform.Name = name
    80  			asset.RelatedAssets = append(asset.RelatedAssets, relatedIds2assets(related)...)
    81  		}
    82  
    83  		if id, name, related := azure.Detect(conn, asset.Platform); id != "" {
    84  			asset.PlatformIds = append(asset.PlatformIds, id)
    85  			asset.Platform.Name = name
    86  			asset.RelatedAssets = append(asset.RelatedAssets, relatedIds2assets(related)...)
    87  		}
    88  
    89  		if id, name, related := gcp.Detect(conn, asset.Platform); id != "" {
    90  			asset.PlatformIds = append(asset.PlatformIds, id)
    91  			asset.Platform.Name = name
    92  			asset.RelatedAssets = append(asset.RelatedAssets, relatedIds2assets(related)...)
    93  		}
    94  	}
    95  
    96  	if hasDetector(detectors, ids.IdDetector_SshHostkey) {
    97  		log.Debug().Msg("run ssh id detector")
    98  		ids, err := sshhostkey.Detect(conn, asset.Platform)
    99  		if err != nil {
   100  			log.Warn().Err(err).Msg("failure in ssh hostkey detector")
   101  		} else {
   102  			asset.PlatformIds = append(asset.PlatformIds, ids...)
   103  		}
   104  	}
   105  
   106  	if hasDetector(detectors, ids.IdDetector_MachineID) {
   107  		log.Debug().Msg("run machineID id detector")
   108  		id, hostErr := machineid.MachineId(conn, asset.Platform)
   109  		if hostErr != nil {
   110  			log.Warn().Err(hostErr).Msg("failure in machineID detector")
   111  		} else if id != "" {
   112  			asset.PlatformIds = append(asset.PlatformIds, id)
   113  		}
   114  	}
   115  
   116  	return nil
   117  }
   118  
   119  func relatedIds2assets(ids []string) []*inventory.Asset {
   120  	res := make([]*inventory.Asset, len(ids))
   121  	for i := range ids {
   122  		res[i] = &inventory.Asset{Id: ids[i]}
   123  	}
   124  	return res
   125  }