in pkg/aws/ec2/api/helper.go [102:185]
func (h *ec2APIHelper) CreateNetworkInterface(description *string, subnetId *string, securityGroups []string, tags []ec2types.Tag,
ipResourceCount *config.IPResourceCount, interfaceType *string,
) (*ec2types.NetworkInterface, error) {
eniDescription := CreateENIDescriptionPrefix + *description
var ec2SecurityGroups []string
if securityGroups != nil && len(securityGroups) != 0 {
// Only add security groups if there are one or more security group provided, otherwise API call will fail instead
// of creating the interface with default security groups
ec2SecurityGroups = securityGroups
}
if tags == nil {
tags = []ec2types.Tag{}
}
// Append the default controller tag to scope down the permissions on network interfaces using IAM roles and add the
// k8s cluster name tag which will be used by the controller to clean up dangling ENIs
tags = append(tags, defaultControllerTag, clusterNameTag)
tagSpecifications := []ec2types.TagSpecification{
{
ResourceType: ec2types.ResourceTypeNetworkInterface,
Tags: tags,
},
}
createInput := &ec2.CreateNetworkInterfaceInput{
Description: aws.String(eniDescription),
Groups: ec2SecurityGroups,
SubnetId: subnetId,
TagSpecifications: tagSpecifications,
}
if ipResourceCount != nil {
secondaryPrivateIPCount := ipResourceCount.SecondaryIPv4Count
ipV4PrefixCount := ipResourceCount.IPv4PrefixCount
if secondaryPrivateIPCount != 0 && ipV4PrefixCount != 0 {
return nil, fmt.Errorf("cannot specify both secondaryPrivateIPCount %v and ipV4PrefixCount %v", secondaryPrivateIPCount, ipV4PrefixCount)
}
if secondaryPrivateIPCount != 0 {
createInput.SecondaryPrivateIpAddressCount = aws.Int32(int32(secondaryPrivateIPCount))
} else if ipV4PrefixCount != 0 {
createInput.Ipv4PrefixCount = aws.Int32(int32(ipV4PrefixCount))
}
}
if interfaceType != nil {
createInput.InterfaceType = ec2types.NetworkInterfaceCreationType(*interfaceType)
}
createOutput, err := h.ec2Wrapper.CreateNetworkInterface(createInput)
if err != nil {
return nil, err
}
if createOutput == nil ||
createOutput.NetworkInterface == nil ||
createOutput.NetworkInterface.NetworkInterfaceId == nil {
return nil, fmt.Errorf("network interface details not returned in response for requet %v", *createInput)
}
nwInterface := createOutput.NetworkInterface
// If the interface type is trunk then attach interface permissions
if interfaceType != nil && *interfaceType == "trunk" {
// Get attach permission from User's Service Linked Role. Account ID will be added by the EC2 API Wrapper
input := &ec2.CreateNetworkInterfacePermissionInput{
NetworkInterfaceId: nwInterface.NetworkInterfaceId,
Permission: ec2types.InterfacePermissionType(ec2types.InterfacePermissionTypeInstanceAttach),
}
_, err = h.ec2Wrapper.CreateNetworkInterfacePermission(input)
if err != nil {
errDelete := h.DeleteNetworkInterface(nwInterface.NetworkInterfaceId)
if errDelete != nil {
return nwInterface, fmt.Errorf("failed to attach the network interface permissions %v: failed to delete the nw interfac %v",
err, errDelete)
}
return nil, fmt.Errorf("failed to get attach network interface permissions for trunk %v", err)
}
}
return nwInterface, nil
}