Skip to content

Commit

Permalink
feat: expose more instance metadata categories (#44)
Browse files Browse the repository at this point in the history
  • Loading branch information
purpleclay authored Jul 17, 2022
1 parent 7d085e2 commit 4a0847a
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 35 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,13 @@ on:
branches:
- main
paths:
- "**/*.go"
- "*.go"
- "go.mod"
- "go.sum"
pull_request:
paths:
- "**/*.go"
- "*.go"
- "go.mod"
- "go.sum"
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,11 @@ on:
branches:
- main
paths:
- "**/*.go"
- "*.go"
pull_request:
paths:
- "**/*.go"
- "*.go"
schedule:
- cron: "36 4 * * 6"
Expand Down
12 changes: 12 additions & 0 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@
name: docs
on:
pull_request:
paths:
- ".github/workflows/docs.yml"
- "docs/**"
- "mkdocs.yml"
push:
tags:
- "v*.*.*"
Expand All @@ -36,45 +40,53 @@ jobs:
uses: actions/checkout@v3
with:
fetch-depth: 0

- name: Set up Python runtime
uses: actions/setup-python@v4
with:
python-version: 3.x

- name: Set up build cache
uses: actions/cache@v3
id: cache
with:
key: ${{ runner.os }}-${{ hashFiles('.cache/**') }}
path: .cache

- name: Install Python dependencies
run: |
pip install \
"mkdocs-git-committers-plugin-2>=0.4.3" \
"mkdocs-git-revision-date-localized-plugin>=1.0" \
"mkdocs-minify-plugin>=0.3" \
"mkdocs-redirects>=1.0"
- name: Install MkDocs Insiders
if: github.event.repository.fork == false
env:
GH_TOKEN: ${{ secrets.GH_MKDOCS }}
run: |
pip install git+https://${GH_TOKEN}@github.com/squidfunk/mkdocs-material-insiders.git
- name: Build
run: mkdocs build
env:
GH_TOKEN: ${{ secrets.GH_MKDOCS }}

- name: HTML Test
uses: wjdp/htmltest-action@master
with:
path: site
config: htmltest.yml

- name: Deploy documentation
if: startsWith(github.ref, 'refs/tags/v')
env:
GH_TOKEN: ${{ secrets.GH_MKDOCS }}
run: |
mkdocs gh-deploy --force
mkdocs --version
- name: Set Custom Domain
if: startsWith(github.ref, 'refs/tags/v')
uses: octokit/[email protected]
Expand Down
68 changes: 33 additions & 35 deletions pkg/imds/metadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ const (
pathIPv4 = "local-ipv4"
pathMacAddress = "mac"
pathPlacementRegion = "placement/region"
pathPlacementAZ = "placement/availability-zone"
pathInstanceID = "instance-id"
pathHostname = "hostname"
)

// MetadataClientAPI defines the API for interacting with the Amazon
Expand All @@ -60,6 +63,15 @@ type Metadata struct {

// VPC ID of where the EC2 instance was launched
VPC string

// AZ is the availability zone where the instance was launched
AZ string

// InstanceID is the unique ID of this instance
InstanceID string

// Hostname is the private IPv4 hostname of the launched instance
Hostname string
}

// NewFromAPI returns a new client from the provided IMDS API implementation
Expand All @@ -70,44 +82,39 @@ func NewFromAPI(api MetadataClientAPI) *Client {
// InstanceMetadata attempts to retrieve useful metadata associated with
// the current EC2 instance by querying IMDS
func (c *Client) InstanceMetadata(ctx context.Context) (Metadata, error) {
region, err := region(ctx, c.api)
if err != nil {
md := Metadata{}

var err error
if md.Region, err = get(ctx, c.api, pathPlacementRegion); err != nil {
return Metadata{}, err
}

ipv4, err := ipv4(ctx, c.api)
if err != nil {
if md.IPv4, err = get(ctx, c.api, pathIPv4); err != nil {
return Metadata{}, err
}

vpcID, err := vpc(ctx, c.api)
if err != nil {
if md.VPC, err = vpc(ctx, c.api); err != nil {
return Metadata{}, err
}

return Metadata{
Region: region,
IPv4: ipv4,
VPC: vpcID,
}, nil
}
if md.AZ, err = get(ctx, c.api, pathPlacementAZ); err != nil {
return Metadata{}, err
}

func region(ctx context.Context, api MetadataClientAPI) (string, error) {
out, err := api.GetMetadata(ctx, &awsimds.GetMetadataInput{
Path: pathPlacementRegion,
})
if err != nil {
return "", err
if md.InstanceID, err = get(ctx, c.api, pathInstanceID); err != nil {
return Metadata{}, err
}
defer out.Content.Close()

data, _ := ioutil.ReadAll(out.Content)
return string(data), nil
if md.Hostname, err = get(ctx, c.api, pathHostname); err != nil {
return Metadata{}, err
}

return md, nil
}

func ipv4(ctx context.Context, api MetadataClientAPI) (string, error) {
func get(ctx context.Context, api MetadataClientAPI, path string) (string, error) {
out, err := api.GetMetadata(ctx, &awsimds.GetMetadataInput{
Path: pathIPv4,
Path: path,
})
if err != nil {
return "", err
Expand All @@ -119,24 +126,15 @@ func ipv4(ctx context.Context, api MetadataClientAPI) (string, error) {
}

func vpc(ctx context.Context, api MetadataClientAPI) (string, error) {
mac, err := api.GetMetadata(ctx, &awsimds.GetMetadataInput{
Path: pathMacAddress,
})
mac, err := get(ctx, api, pathMacAddress)
if err != nil {
return "", err
}
defer mac.Content.Close()
md, _ := ioutil.ReadAll(mac.Content)

// Use the MAC address to retrieve the VPC associated with the EC2 instance
out, err := api.GetMetadata(ctx, &awsimds.GetMetadataInput{
Path: fmt.Sprintf("network/interfaces/macs/%s/vpc-id", string(md)),
})
vpc, err := get(ctx, api, fmt.Sprintf("network/interfaces/macs/%s/vpc-id", mac))
if err != nil {
return "", err
}
defer mac.Content.Close()
data, _ := ioutil.ReadAll(out.Content)

return string(data), nil
return vpc, nil
}
3 changes: 3 additions & 0 deletions pkg/imds/metadata_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,7 @@ func TestIntegration_InstanceMetadata(t *testing.T) {
assert.Equal(t, aemm.ValueLocalIPv4, metadata.IPv4)
assert.Equal(t, aemm.ValuePlacementRegion, metadata.Region)
assert.Equal(t, aemm.ValueNetworkInterfaces0VPCID, metadata.VPC)
assert.Equal(t, aemm.ValuePlacementAvailabilityZone, metadata.AZ)
assert.Equal(t, aemm.ValueInstanceID, metadata.InstanceID)
assert.Equal(t, aemm.ValueHostname, metadata.Hostname)
}

0 comments on commit 4a0847a

Please sign in to comment.