func (imds TypedIMDS) GetIPv6Prefixes(ctx context.Context, mac string) ([]net.IPNet, error) {
	key := fmt.Sprintf("network/interfaces/macs/%s/ipv6-prefix", mac)
	prefixes, err := imds.getCIDRs(ctx, key)
	if err != nil {
		if imdsErr, ok := err.(*imdsRequestError); ok {
			if IsNotFound(imdsErr.err) {
				return nil, nil
			}
			log.Warnf("%v", err)
			return nil, imdsErr.err
		}
		return nil, err
	}
	return prefixes, err
}
GetIPv6Prefixes returns the IPv6 prefixes delegated to this interface
package awsutils
import (
	"context"
	"fmt"
	"net"
	"net/http"
	"strconv"
	"strings"
	"github.com/aws/aws-sdk-go/aws/awserr"
	"github.com/pkg/errors"
)
type EC2MetadataIface interface {
	GetMetadataWithContext(ctx context.Context, p string) (string, error)
}
type TypedIMDS struct {
	EC2MetadataIface
}
type imdsRequestError struct {
	requestKey string
	err        error
}
var _ error = &imdsRequestError{}
func newIMDSRequestError(requestKey string, err error) *imdsRequestError {
	return &imdsRequestError{
		requestKey: requestKey,
		err:        err,
	}
}
func (e *imdsRequestError) Error() string {
	return fmt.Sprintf("failed to retrieve %s from instance metadata %v", e.requestKey, e.err)
}
func (imds TypedIMDS) getList(ctx context.Context, key string) ([]string, error) {
	data, err := imds.GetMetadataWithContext(ctx, key)
	if err != nil {
		return nil, err
	}
	return strings.Fields(data), err
}
func (imds TypedIMDS) GetAZ(ctx context.Context) (string, error) {
	az, err := imds.GetMetadataWithContext(ctx, "placement/availability-zone")
	if err != nil {
		if imdsErr, ok := err.(*imdsRequestError); ok {
			log.Warnf("%v", err)
			return az, imdsErr.err
		}
		return "", err
	}
	return az, err
}
func (imds TypedIMDS) GetInstanceType(ctx context.Context) (string, error) {
	instanceType, err := imds.GetMetadataWithContext(ctx, "instance-type")
	if err != nil {
		if imdsErr, ok := err.(*imdsRequestError); ok {
			log.Warnf("%v", err)
			return instanceType, imdsErr.err
		}
		return "", err
	}
	return instanceType, err
}
func (imds TypedIMDS) GetLocalIPv4(ctx context.Context) (net.IP, error) {
	return imds.getIP(ctx, "local-ipv4")
}
func (imds TypedIMDS) GetInstanceID(ctx context.Context) (string, error) {
	instanceID, err := imds.GetMetadataWithContext(ctx, "instance-id")
	if err != nil {
		if imdsErr, ok := err.(*imdsRequestError); ok {
			log.Warnf("%v", err)
			return instanceID, imdsErr.err
		}
		return "", err
	}
	return instanceID, err
}
func (imds TypedIMDS) GetMAC(ctx context.Context) (string, error) {
	mac, err := imds.GetMetadataWithContext(ctx, "mac")
	if err != nil {
		if imdsErr, ok := err.(*imdsRequestError); ok {
			log.Warnf("%v", err)
			return mac, imdsErr.err
		}
		return "", err
	}
	return mac, err
}
func (imds TypedIMDS) GetMACs(ctx context.Context) ([]string, error) {
	list, err := imds.getList(ctx, "network/interfaces/macs")
	if err != nil {
		if imdsErr, ok := err.(*imdsRequestError); ok {
			log.Warnf("%v", err)
			return nil, imdsErr.err
		}
		return nil, err
	}
	for i, item := range list {
		list[i] = strings.TrimSuffix(item, "/")
	}
	return list, err
}
func (imds TypedIMDS) GetInterfaceID(ctx context.Context, mac string) (string, error) {
	key := fmt.Sprintf("network/interfaces/macs/%s/interface-id", mac)
	interfaceID, err := imds.GetMetadataWithContext(ctx, key)
	if err != nil {
		if imdsErr, ok := err.(*imdsRequestError); ok {
			log.Warnf("%v", err)
			return interfaceID, imdsErr.err
		}
		return "", err
	}
	return interfaceID, err
}
func (imds TypedIMDS) getInt(ctx context.Context, key string) (int, error) {
	data, err := imds.GetMetadataWithContext(ctx, key)
	if err != nil {
		if imdsErr, ok := err.(*imdsRequestError); ok {
			log.Warnf("%v", err)
			return 0, imdsErr.err
		}
		return 0, err
	}
	dataInt, err := strconv.Atoi(data)
	if err != nil {
		return 0, err
	}
	return dataInt, err
}
func (imds TypedIMDS) GetDeviceNumber(ctx context.Context, mac string) (int, error) {
	key := fmt.Sprintf("network/interfaces/macs/%s/device-number", mac)
	return imds.getInt(ctx, key)
}
func (imds TypedIMDS) GetSubnetID(ctx context.Context, mac string) (string, error) {
	key := fmt.Sprintf("network/interfaces/macs/%s/subnet-id", mac)
	subnetID, err := imds.GetMetadataWithContext(ctx, key)
	if err != nil {
		if imdsErr, ok := err.(*imdsRequestError); ok {
			log.Warnf("%v", err)
			return subnetID, imdsErr.err
		}
		return "", err
	}
	return subnetID, err
}
func (imds TypedIMDS) GetSecurityGroupIDs(ctx context.Context, mac string) ([]string, error) {
	key := fmt.Sprintf("network/interfaces/macs/%s/security-group-ids", mac)
	sgs, err := imds.getList(ctx, key)
	if err != nil {
		if imdsErr, ok := err.(*imdsRequestError); ok {
			log.Warnf("%v", err)
			return sgs, imdsErr.err
		}
		return nil, err
	}
	return sgs, err
}
func (imds TypedIMDS) getIP(ctx context.Context, key string) (net.IP, error) {
	data, err := imds.GetMetadataWithContext(ctx, key)
	if err != nil {
		if imdsErr, ok := err.(*imdsRequestError); ok {
			log.Warnf("%v", err)
			return nil, imdsErr.err
		}
		return nil, err
	}
	ip := net.ParseIP(data)
	if ip == nil {
		err = &net.ParseError{Type: "IP address", Text: data}
		return nil, err
	}
	return ip, err
}
func (imds TypedIMDS) getIPs(ctx context.Context, key string) ([]net.IP, error) {
	list, err := imds.getList(ctx, key)
	if err != nil {
		return nil, err
	}
	ips := make([]net.IP, len(list))
	for i, item := range list {
		ip := net.ParseIP(item)
		if ip == nil {
			err = &net.ParseError{Type: "IP address", Text: item}
			return nil, err
		}
		ips[i] = ip
	}
	return ips, err
}
func (imds TypedIMDS) getCIDR(ctx context.Context, key string) (net.IPNet, error) {
	data, err := imds.GetMetadataWithContext(ctx, key)
	if err != nil {
		if imdsErr, ok := err.(*imdsRequestError); ok {
			log.Warnf("%v", err)
			return net.IPNet{}, imdsErr.err
		}
		return net.IPNet{}, err
	}
	ip, network, err := net.ParseCIDR(data)
	if err != nil {
		return net.IPNet{}, err
	}
	cidr := net.IPNet{IP: ip, Mask: network.Mask}
	return cidr, err
}
func (imds TypedIMDS) getCIDRs(ctx context.Context, key string) ([]net.IPNet, error) {
	list, err := imds.getList(ctx, key)
	if err != nil {
		return nil, err
	}
	cidrs := make([]net.IPNet, len(list))
	for i, item := range list {
		ip, network, err := net.ParseCIDR(item)
		if err != nil {
			return nil, err
		}
		cidrs[i] = net.IPNet{IP: ip, Mask: network.Mask}
	}
	return cidrs, nil
}
func (imds TypedIMDS) GetLocalIPv4s(ctx context.Context, mac string) ([]net.IP, error) {
	key := fmt.Sprintf("network/interfaces/macs/%s/local-ipv4s", mac)
	ips, err := imds.getIPs(ctx, key)
	if err != nil {
		if imdsErr, ok := err.(*imdsRequestError); ok {
			log.Warnf("%v", err)
			return nil, imdsErr.err
		}
		return nil, err
	}
	return ips, err
}
func (imds TypedIMDS) GetIPv4Prefixes(ctx context.Context, mac string) ([]net.IPNet, error) {
	key := fmt.Sprintf("network/interfaces/macs/%s/ipv4-prefix", mac)
	prefixes, err := imds.getCIDRs(ctx, key)
	if err != nil {
		if imdsErr, ok := err.(*imdsRequestError); ok {
			if IsNotFound(imdsErr.err) {
				return nil, nil
			}
			log.Warnf("%v", err)
			return nil, imdsErr.err
		}
		return nil, err
	}
	return prefixes, err
}