func (eni ENIMetadata) PrimaryIPv4Address() string {
	for _, addr := range eni.IPv4Addresses {
		if aws.BoolValue(addr.Primary) {
			return aws.StringValue(addr.PrivateIpAddress)
		}
	}
	return ""
}
PrimaryIPv4Address returns the primary IPv4 address of this node
package awsutils
import (
	"context"
	"encoding/json"
	"fmt"
	"math/rand"
	"net"
	"os"
	"regexp"
	"strings"
	"sync"
	"time"
	"github.com/aws/amazon-vpc-cni-k8s/pkg/awsutils/awssession"
	"github.com/aws/amazon-vpc-cni-k8s/pkg/ec2wrapper"
	"github.com/aws/amazon-vpc-cni-k8s/pkg/utils/logger"
	"github.com/aws/amazon-vpc-cni-k8s/pkg/utils/retry"
	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/awserr"
	"github.com/aws/aws-sdk-go/aws/ec2metadata"
	"github.com/aws/aws-sdk-go/service/ec2"
	"github.com/pkg/errors"
	"github.com/prometheus/client_golang/prometheus"
	"k8s.io/apimachinery/pkg/util/sets"
	"k8s.io/apimachinery/pkg/util/wait"
)
const (
	maxENIEC2APIRetries  = 12
	maxENIBackoffDelay   = time.Minute
	eniDescriptionPrefix = "aws-K8S-"
	maxENIs                 = 100
	clusterNameEnvVar       = "CLUSTER_NAME"
	eniNodeTagKey           = "node.k8s.amazonaws.com/instance_id"
	eniCreatedAtTagKey      = "node.k8s.amazonaws.com/createdAt"
	eniClusterTagKey        = "cluster.k8s.amazonaws.com/name"
	additionalEniTagsEnvVar = "ADDITIONAL_ENI_TAGS"
	reservedTagKeyPrefix    = "k8s.amazonaws.com"
	UnknownInstanceType = "vpc ip resource(eni ip limit): unknown instance type"
	eniCleanupStartupDelayMax = 300
	eniDeleteCooldownTime     = 5 * time.Minute
	describeENIPageSize = 1000
)
var (
	ErrENINotFound = errors.New("ENI is not found")
	ErrAllSecondaryIPsNotFound = errors.New("All secondary IPs not found")
	ErrNoSecondaryIPsFound = errors.New("No secondary IPs have been assigned to this ENI")
	ErrNoNetworkInterfaces = errors.New("No network interfaces found for ENI")
)
var log = logger.Get()
var (
	awsAPILatency = prometheus.NewSummaryVec(
		prometheus.SummaryOpts{
			Name: "awscni_aws_api_latency_ms",
			Help: "AWS API call latency in ms",
		},
		[]string{"api", "error", "status"},
	)
	awsAPIErr = prometheus.NewCounterVec(
		prometheus.CounterOpts{
			Name: "awscni_aws_api_error_count",
			Help: "The number of times AWS API returns an error",
		},
		[]string{"api", "error"},
	)
	awsUtilsErr = prometheus.NewCounterVec(
		prometheus.CounterOpts{
			Name: "awscni_aws_utils_error_count",
			Help: "The number of errors not handled in awsutils library",
		},
		[]string{"fn", "error"},
	)
	prometheusRegistered = false
)
type APIs interface {
	AllocENI(useCustomCfg bool, sg []*string, subnet string) (eni string, err error)
	FreeENI(eniName string) error
	TagENI(eniID string, currentTags map[string]string) error
	GetAttachedENIs() (eniList []ENIMetadata, err error)
	GetIPv4sFromEC2(eniID string) (addrList []*ec2.NetworkInterfacePrivateIpAddress, err error)
	GetIPv4PrefixesFromEC2(eniID string) (addrList []*ec2.Ipv4PrefixSpecification, err error)
	GetIPv6PrefixesFromEC2(eniID string) (addrList []*ec2.Ipv6PrefixSpecification, err error)
	DescribeAllENIs() (DescribeAllENIsResult, error)
	AllocIPAddress(eniID string) error
	AllocIPAddresses(eniID string, numIPs int) error
	DeallocIPAddresses(eniID string, ips []string) error
	DeallocPrefixAddresses(eniID string, ips []string) error
	AllocIPv6Prefixes(eniID string) ([]*string, error)
	GetVPCIPv4CIDRs() ([]string, error)
	GetLocalIPv4() net.IP
	GetVPCIPv6CIDRs() ([]string, error)
	GetPrimaryENI() string
	GetENIIPv4Limit() int
	GetENILimit() int
	GetPrimaryENImac() string
	SetUnmanagedENIs(eniIDs []string)
	IsUnmanagedENI(eniID string) bool
	WaitForENIAndIPsAttached(eni string, wantedSecondaryIPs int) (ENIMetadata, error)
	SetCNIUnmanagedENIs(eniID []string) error
	IsCNIUnmanagedENI(eniID string) bool
	IsPrimaryENI(eniID string) bool
	RefreshSGIDs(mac string) error
	GetInstanceHypervisorFamily() string
	GetInstanceType() string
	InitCachedPrefixDelegation(bool)
	GetInstanceID() string
	FetchInstanceTypeLimits() error
}
type EC2InstanceMetadataCache struct {
	securityGroups   StringSet
	subnetID         string
	localIPv4        net.IP
	v4Enabled        bool
	v6Enabled        bool
	instanceID       string
	instanceType     string
	primaryENI       string
	primaryENImac    string
	availabilityZone string
	region           string
	unmanagedENIs          StringSet
	useCustomNetworking    bool
	cniunmanagedENIs       StringSet
	enablePrefixDelegation bool
	clusterName       string
	additionalENITags map[string]string
	imds   TypedIMDS
	ec2SVC ec2wrapper.EC2
}
type ENIMetadata struct {
	ENIID string
	MAC string
	DeviceNumber int  
	SubnetIPv4CIDR string
	SubnetIPv6CIDR string
	IPv4Addresses []*ec2.NetworkInterfacePrivateIpAddress
	IPv4Prefixes []*ec2.Ipv4PrefixSpecification
	IPv6Addresses []*ec2.NetworkInterfaceIpv6Address
	IPv6Prefixes []*ec2.Ipv6PrefixSpecification
}
type InstanceTypeLimits struct {
	ENILimit       int
	IPv4Limit      int
	HypervisorType string
}