go.mondoo.com/cnquery@v0.0.0-20231005093811-59568235f6ea/providers/os/id/azcompute/azcompute.go (about) 1 // Copyright (c) Mondoo, Inc. 2 // SPDX-License-Identifier: BUSL-1.1 3 4 package azcompute 5 6 import ( 7 "encoding/json" 8 "errors" 9 "io" 10 "strings" 11 12 "go.mondoo.com/cnquery/providers-sdk/v1/inventory" 13 "go.mondoo.com/cnquery/providers-sdk/v1/plugin" 14 "go.mondoo.com/cnquery/providers/os/connection/shared" 15 "go.mondoo.com/cnquery/providers/os/resources/powershell" 16 "go.mondoo.com/cnquery/utils/multierr" 17 ) 18 19 const ( 20 identityUrl = "http://169.254.169.254/metadata/instance?api-version=2021-02-01" 21 metadataIdentityScriptWindows = `Invoke-RestMethod -TimeoutSec 1 -Headers @{"Metadata"="true"} -Method GET -URI http://169.254.169.254/metadata/instance?api-version=2021-02-01 -UseBasicParsing | ConvertTo-Json` 22 ) 23 24 type instanceMetadata struct { 25 Compute struct { 26 ResourceID string `json:"resourceID"` 27 SubscriptionID string `json:"subscriptionId"` 28 Tags string `json:"tags"` 29 } `json:"compute"` 30 } 31 32 type Identity struct { 33 InstanceID string 34 AccountID string 35 } 36 37 type InstanceIdentifier interface { 38 Identify() (Identity, error) 39 } 40 41 func Resolve(conn shared.Connection, pf *inventory.Platform) (InstanceIdentifier, error) { 42 if pf.IsFamily(inventory.FAMILY_UNIX) || pf.IsFamily(inventory.FAMILY_WINDOWS) { 43 return &commandInstanceMetadata{conn, pf}, nil 44 } 45 return nil, errors.New("azure compute id detector is not supported for your asset: " + pf.Name + " " + pf.Version) 46 } 47 48 type commandInstanceMetadata struct { 49 conn shared.Connection 50 platform *inventory.Platform 51 } 52 53 func (m *commandInstanceMetadata) Identify() (Identity, error) { 54 var instanceDocument string 55 switch { 56 case m.platform.IsFamily(inventory.FAMILY_UNIX): 57 cmd, err := m.conn.RunCommand("curl --noproxy '*' -H Metadata:true " + identityUrl) 58 if err != nil { 59 return Identity{}, err 60 } 61 data, err := io.ReadAll(cmd.Stdout) 62 if err != nil { 63 return Identity{}, err 64 } 65 66 instanceDocument = strings.TrimSpace(string(data)) 67 case m.platform.IsFamily(inventory.FAMILY_WINDOWS): 68 cmd, err := m.conn.RunCommand(powershell.Encode(metadataIdentityScriptWindows)) 69 if err != nil { 70 return Identity{}, err 71 } 72 data, err := io.ReadAll(cmd.Stdout) 73 if err != nil { 74 return Identity{}, err 75 } 76 77 instanceDocument = strings.TrimSpace(string(data)) 78 default: 79 return Identity{}, errors.New("your platform is not supported by azure metadata identifier resource") 80 } 81 82 // parse into struct 83 md := instanceMetadata{} 84 if err := json.NewDecoder(strings.NewReader(instanceDocument)).Decode(&md); err != nil { 85 return Identity{}, multierr.Wrap(err, "failed to decode Azure Instance Metadata") 86 } 87 88 return Identity{ 89 InstanceID: plugin.MondooAzureInstanceID(md.Compute.ResourceID), 90 AccountID: "//platformid.api.mondoo.app/runtime/azure/subscriptions/" + md.Compute.SubscriptionID, 91 }, nil 92 }