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