go.mondoo.com/cnquery@v0.0.0-20231005093811-59568235f6ea/providers/os/id/gce/gce.go (about) 1 // Copyright (c) Mondoo, Inc. 2 // SPDX-License-Identifier: BUSL-1.1 3 4 package gce 5 6 import ( 7 "encoding/json" 8 "errors" 9 "io" 10 "strconv" 11 "strings" 12 13 "go.mondoo.com/cnquery/providers-sdk/v1/inventory" 14 "go.mondoo.com/cnquery/providers/os/connection/shared" 15 "go.mondoo.com/cnquery/providers/os/resources/powershell" 16 ) 17 18 // deprecated: use MondooGcpInstancePlatformMrn 19 func MondooGcpInstanceID(project string, zone string, instanceID uint64) string { 20 return "//platformid.api.mondoo.app/runtime/gcp/compute/v1/projects/" + project + "/zones/" + zone + "/instances/" + strconv.FormatUint(uint64(instanceID), 10) 21 } 22 23 func MondooGcpInstancePlatformMrn(project string, zone string, instanceName string) string { 24 return "//platformid.api.mondoo.app/runtime/gcp/compute/v1/projects/" + project + "/zones/" + zone + "/instances/" + instanceName 25 } 26 27 type Identity struct { 28 ProjectID string 29 // deprecated: use PlatformMrn 30 InstanceID string 31 PlatformMrn string 32 } 33 type InstanceIdentifier interface { 34 Identify() (Identity, error) 35 } 36 37 func Resolve(conn shared.Connection, pf *inventory.Platform) (InstanceIdentifier, error) { 38 if pf.IsFamily(inventory.FAMILY_UNIX) || pf.IsFamily(inventory.FAMILY_WINDOWS) { 39 return NewCommandInstanceMetadata(conn, pf), nil 40 } 41 return nil, errors.New("gce id detector is not supported for your asset: " + pf.Name + " " + pf.Version) 42 } 43 44 const ( 45 metadataSvcURL = "http://metadata.google.internal/computeMetadata/v1/" 46 metadataIdentityScriptWindows = ` 47 $projectID = Invoke-RestMethod -Headers @{"Metadata-Flavor"="Google"} -Method GET -URI http://metadata.google.internal/computeMetadata/v1/project/project-id?alt=json -UseBasicParsing 48 $instanceID = Invoke-RestMethod -Headers @{"Metadata-Flavor"="Google"} -Method GET -URI http://metadata.google.internal/computeMetadata/v1/instance/id?alt=json -UseBasicParsing 49 $instanceName = Invoke-RestMethod -Headers @{"Metadata-Flavor"="Google"} -Method GET -URI http://metadata.google.internal/computeMetadata/v1/instance/name?alt=json -UseBasicParsing 50 $zone = Invoke-RestMethod -Headers @{"Metadata-Flavor"="Google"} -Method GET -URI http://metadata.google.internal/computeMetadata/v1/instance/zone?alt=json -UseBasicParsing 51 52 $doc = New-Object -TypeName PSObject 53 $doc | Add-Member -MemberType NoteProperty -Value $projectID -Name ProjectID 54 $doc | Add-Member -MemberType NoteProperty -Value $instanceID -Name InstanceID 55 $doc | Add-Member -MemberType NoteProperty -Value $instanceName -Name InstanceName 56 $doc | Add-Member -MemberType NoteProperty -Value $zone -Name ZoneInfo 57 58 $doc | ConvertTo-Json 59 ` 60 ) 61 62 func NewCommandInstanceMetadata(conn shared.Connection, platform *inventory.Platform) *CommandInstanceMetadata { 63 return &CommandInstanceMetadata{ 64 connection: conn, 65 platform: platform, 66 } 67 } 68 69 type CommandInstanceMetadata struct { 70 connection shared.Connection 71 platform *inventory.Platform 72 } 73 74 func (m *CommandInstanceMetadata) curl(key string, v interface{}) error { 75 cmd, err := m.connection.RunCommand("curl --noproxy '*' -H Metadata-Flavor:Google " + metadataSvcURL + key + "?alt=json") 76 if err != nil { 77 return err 78 } 79 80 return json.NewDecoder(cmd.Stdout).Decode(v) 81 } 82 83 func (m *CommandInstanceMetadata) Identify() (Identity, error) { 84 switch { 85 case m.platform.IsFamily(inventory.FAMILY_UNIX): 86 var projectID string 87 var instanceID uint64 88 var instanceName string 89 var zoneInfo string 90 91 if err := m.curl("project/project-id", &projectID); err != nil { 92 return Identity{}, err 93 } 94 95 if err := m.curl("instance/id", &instanceID); err != nil { 96 return Identity{}, err 97 } 98 99 if err := m.curl("instance/name", &instanceName); err != nil { 100 return Identity{}, err 101 } 102 103 if err := m.curl("instance/zone", &zoneInfo); err != nil { 104 return Identity{}, err 105 } 106 107 zone := zoneInfo[strings.LastIndex(zoneInfo, "/")+1:] 108 return Identity{ 109 ProjectID: "//platformid.api.mondoo.app/runtime/gcp/projects/" + projectID, 110 InstanceID: MondooGcpInstanceID(projectID, zone, instanceID), 111 PlatformMrn: MondooGcpInstancePlatformMrn(projectID, zone, instanceName), 112 }, nil 113 case m.platform.IsFamily(inventory.FAMILY_WINDOWS): 114 cmd, err := m.connection.RunCommand(powershell.Encode(metadataIdentityScriptWindows)) 115 if err != nil { 116 return Identity{}, err 117 } 118 data, err := io.ReadAll(cmd.Stdout) 119 if err != nil { 120 return Identity{}, err 121 } 122 123 instanceDocument := strings.TrimSpace(string(data)) 124 doc := struct { 125 ProjectID string `json:"ProjectID"` 126 InstanceID uint64 `json:"InstanceID"` 127 InstanceName string `json:"InstanceName"` 128 ZoneInfo string `json:"ZoneInfo"` 129 }{} 130 json.Unmarshal([]byte(instanceDocument), &doc) 131 zone := doc.ZoneInfo[strings.LastIndex(doc.ZoneInfo, "/")+1:] 132 133 return Identity{ 134 ProjectID: "//platformid.api.mondoo.app/runtime/gcp/projects/" + doc.ProjectID, 135 InstanceID: MondooGcpInstanceID(doc.ProjectID, zone, doc.InstanceID), 136 PlatformMrn: MondooGcpInstancePlatformMrn(doc.ProjectID, zone, doc.InstanceName), 137 }, nil 138 default: 139 return Identity{}, errors.New("your platform is not supported by azure metadata identifier resource") 140 } 141 }