func()

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
}