@@ -1545,6 +1545,289 @@ func TestGetVPCInterfaceConfig(t *testing.T) {
15451545 }
15461546}
15471547
1548+ func TestGetVPCLinodeInterfaceConfig (t * testing.T ) {
1549+ t .Parallel ()
1550+
1551+ // Setup test cases
1552+ testCases := []struct {
1553+ name string
1554+ vpcRef * corev1.ObjectReference
1555+ linodeInterfaces []linodego.LinodeInterfaceCreateOptions
1556+ subnetName string
1557+ mockSetup func (mockK8sClient * mock.MockK8sClient )
1558+ expectErr bool
1559+ expectErrMsg string
1560+ expectLinodeInterface bool
1561+ expectSubnetID int
1562+ }{
1563+ {
1564+ name : "Success - Finding VPC with default namespace" ,
1565+ vpcRef : & corev1.ObjectReference {
1566+ Name : "test-vpc" ,
1567+ },
1568+ linodeInterfaces : []linodego.LinodeInterfaceCreateOptions {},
1569+ mockSetup : func (mockK8sClient * mock.MockK8sClient ) {
1570+ mockK8sClient .EXPECT ().Get (gomock .Any (), client.ObjectKey {
1571+ Name : "test-vpc" ,
1572+ Namespace : "default" , // Default namespace
1573+ }, gomock .Any ()).DoAndReturn (func (_ context.Context , _ client.ObjectKey , vpc * infrav1alpha2.LinodeVPC , _ ... client.GetOption ) error {
1574+ vpc .Status .Ready = true
1575+ vpc .Spec .VPCID = ptr .To (123 )
1576+ vpc .Spec .Subnets = []infrav1alpha2.VPCSubnetCreateOptions {
1577+ {
1578+ SubnetID : 456 ,
1579+ Label : "subnet-1" ,
1580+ IPv6 : []linodego.VPCIPv6Range {
1581+ {
1582+ Range : "2001:0db8::/56" ,
1583+ },
1584+ },
1585+ },
1586+ }
1587+ return nil
1588+ })
1589+ },
1590+ expectErr : false ,
1591+ expectLinodeInterface : true ,
1592+ expectSubnetID : 456 , // First subnet ID
1593+ },
1594+ {
1595+ name : "Success - Finding VPC with specific namespace" ,
1596+ vpcRef : & corev1.ObjectReference {
1597+ Name : "test-vpc" ,
1598+ Namespace : "custom-namespace" ,
1599+ },
1600+ linodeInterfaces : []linodego.LinodeInterfaceCreateOptions {},
1601+ mockSetup : func (mockK8sClient * mock.MockK8sClient ) {
1602+ mockK8sClient .EXPECT ().Get (gomock .Any (), client.ObjectKey {
1603+ Name : "test-vpc" ,
1604+ Namespace : "custom-namespace" ,
1605+ }, gomock .Any ()).DoAndReturn (func (_ context.Context , _ client.ObjectKey , vpc * infrav1alpha2.LinodeVPC , _ ... client.GetOption ) error {
1606+ vpc .Status .Ready = true
1607+ vpc .Spec .VPCID = ptr .To (123 )
1608+ vpc .Spec .Subnets = []infrav1alpha2.VPCSubnetCreateOptions {
1609+ {
1610+ SubnetID : 456 ,
1611+ Label : "subnet-1" ,
1612+ },
1613+ }
1614+ return nil
1615+ })
1616+ },
1617+ expectErr : false ,
1618+ expectLinodeInterface : true ,
1619+ expectSubnetID : 456 ,
1620+ },
1621+ {
1622+ name : "Success - With subnet name specified and found" ,
1623+ vpcRef : & corev1.ObjectReference {
1624+ Name : "test-vpc" ,
1625+ },
1626+ subnetName : "subnet-2" ,
1627+ linodeInterfaces : []linodego.LinodeInterfaceCreateOptions {},
1628+ mockSetup : func (mockK8sClient * mock.MockK8sClient ) {
1629+ mockK8sClient .EXPECT ().Get (gomock .Any (), client.ObjectKey {
1630+ Name : "test-vpc" ,
1631+ Namespace : "default" ,
1632+ }, gomock .Any ()).DoAndReturn (func (_ context.Context , _ client.ObjectKey , vpc * infrav1alpha2.LinodeVPC , _ ... client.GetOption ) error {
1633+ vpc .Status .Ready = true
1634+ vpc .Spec .VPCID = ptr .To (123 )
1635+ vpc .Spec .Subnets = []infrav1alpha2.VPCSubnetCreateOptions {
1636+ {
1637+ SubnetID : 456 ,
1638+ Label : "subnet-1" ,
1639+ },
1640+ {
1641+ SubnetID : 789 ,
1642+ Label : "subnet-2" ,
1643+ },
1644+ }
1645+ return nil
1646+ })
1647+ },
1648+ expectErr : false ,
1649+ expectLinodeInterface : true ,
1650+ expectSubnetID : 789 ,
1651+ },
1652+ {
1653+ name : "Success - VPC interface already exists" ,
1654+ vpcRef : & corev1.ObjectReference {
1655+ Name : "test-vpc" ,
1656+ },
1657+ linodeInterfaces : []linodego.LinodeInterfaceCreateOptions {
1658+ {
1659+ VPC : & linodego.VPCInterfaceCreateOptions {},
1660+ },
1661+ },
1662+ mockSetup : func (mockK8sClient * mock.MockK8sClient ) {
1663+ mockK8sClient .EXPECT ().Get (gomock .Any (), client.ObjectKey {
1664+ Name : "test-vpc" ,
1665+ Namespace : "default" ,
1666+ }, gomock .Any ()).DoAndReturn (func (_ context.Context , _ client.ObjectKey , vpc * infrav1alpha2.LinodeVPC , _ ... client.GetOption ) error {
1667+ vpc .Status .Ready = true
1668+ vpc .Spec .VPCID = ptr .To (123 )
1669+ vpc .Spec .Subnets = []infrav1alpha2.VPCSubnetCreateOptions {
1670+ {
1671+ SubnetID : 456 ,
1672+ Label : "subnet-1" ,
1673+ IPv6 : []linodego.VPCIPv6Range {
1674+ {
1675+ Range : "2001:0db8::/56" ,
1676+ },
1677+ },
1678+ },
1679+ }
1680+ return nil
1681+ })
1682+ },
1683+ expectErr : false ,
1684+ expectLinodeInterface : false ,
1685+ expectSubnetID : 456 ,
1686+ },
1687+ {
1688+ name : "Error - Failed to fetch LinodeVPC" ,
1689+ vpcRef : & corev1.ObjectReference {
1690+ Name : "nonexistent-vpc" ,
1691+ },
1692+ linodeInterfaces : []linodego.LinodeInterfaceCreateOptions {},
1693+ mockSetup : func (mockK8sClient * mock.MockK8sClient ) {
1694+ mockK8sClient .EXPECT ().Get (gomock .Any (), client.ObjectKey {
1695+ Name : "nonexistent-vpc" ,
1696+ Namespace : "default" ,
1697+ }, gomock .Any ()).Return (fmt .Errorf ("vpc not found" ))
1698+ },
1699+ expectErr : true ,
1700+ expectErrMsg : "vpc not found" ,
1701+ expectLinodeInterface : false ,
1702+ },
1703+ {
1704+ name : "Error - VPC is not ready" ,
1705+ vpcRef : & corev1.ObjectReference {
1706+ Name : "test-vpc" ,
1707+ },
1708+ linodeInterfaces : []linodego.LinodeInterfaceCreateOptions {},
1709+ mockSetup : func (mockK8sClient * mock.MockK8sClient ) {
1710+ mockK8sClient .EXPECT ().Get (gomock .Any (), client.ObjectKey {
1711+ Name : "test-vpc" ,
1712+ Namespace : "default" ,
1713+ }, gomock .Any ()).DoAndReturn (func (_ context.Context , _ client.ObjectKey , vpc * infrav1alpha2.LinodeVPC , _ ... client.GetOption ) error {
1714+ vpc .Status .Ready = false
1715+ vpc .Spec .VPCID = ptr .To (123 )
1716+ return nil
1717+ })
1718+ },
1719+ expectErr : true ,
1720+ expectErrMsg : "vpc is not available" ,
1721+ expectLinodeInterface : false ,
1722+ },
1723+ {
1724+ name : "Error - VPC has no subnets" ,
1725+ vpcRef : & corev1.ObjectReference {
1726+ Name : "test-vpc" ,
1727+ },
1728+ linodeInterfaces : []linodego.LinodeInterfaceCreateOptions {},
1729+ mockSetup : func (mockK8sClient * mock.MockK8sClient ) {
1730+ mockK8sClient .EXPECT ().Get (gomock .Any (), client.ObjectKey {
1731+ Name : "test-vpc" ,
1732+ Namespace : "default" ,
1733+ }, gomock .Any ()).DoAndReturn (func (_ context.Context , _ client.ObjectKey , vpc * infrav1alpha2.LinodeVPC , _ ... client.GetOption ) error {
1734+ vpc .Status .Ready = true
1735+ vpc .Spec .VPCID = ptr .To (123 )
1736+ vpc .Spec .Subnets = []infrav1alpha2.VPCSubnetCreateOptions {}
1737+ return nil
1738+ })
1739+ },
1740+ expectErr : true ,
1741+ expectErrMsg : "failed to find subnet" ,
1742+ expectLinodeInterface : false ,
1743+ },
1744+ {
1745+ name : "Error - Subnet name not found" ,
1746+ vpcRef : & corev1.ObjectReference {
1747+ Name : "test-vpc" ,
1748+ },
1749+ subnetName : "nonexistent-subnet" ,
1750+ linodeInterfaces : []linodego.LinodeInterfaceCreateOptions {},
1751+ mockSetup : func (mockK8sClient * mock.MockK8sClient ) {
1752+ mockK8sClient .EXPECT ().Get (gomock .Any (), client.ObjectKey {
1753+ Name : "test-vpc" ,
1754+ Namespace : "default" ,
1755+ }, gomock .Any ()).DoAndReturn (func (_ context.Context , _ client.ObjectKey , vpc * infrav1alpha2.LinodeVPC , _ ... client.GetOption ) error {
1756+ vpc .Status .Ready = true
1757+ vpc .Spec .VPCID = ptr .To (123 )
1758+ vpc .Spec .Subnets = []infrav1alpha2.VPCSubnetCreateOptions {
1759+ {
1760+ SubnetID : 456 ,
1761+ Label : "subnet-1" ,
1762+ },
1763+ }
1764+ return nil
1765+ })
1766+ },
1767+ expectErr : true ,
1768+ expectErrMsg : "failed to find subnet as subnet id set is 0" ,
1769+ expectLinodeInterface : false ,
1770+ },
1771+ }
1772+
1773+ for _ , tc := range testCases {
1774+ tc := tc
1775+ t .Run (tc .name , func (t * testing.T ) {
1776+ t .Parallel ()
1777+
1778+ // Setup mock controller and client
1779+ ctrl := gomock .NewController (t )
1780+ defer ctrl .Finish ()
1781+
1782+ mockK8sClient := mock .NewMockK8sClient (ctrl )
1783+ mockLinodeClient := mock .NewMockLinodeClient (ctrl )
1784+
1785+ tc .mockSetup (mockK8sClient )
1786+
1787+ // Create test context
1788+ ctx := t .Context ()
1789+ logger := testr .New (t )
1790+
1791+ // Create machine scope
1792+ machineScope := & scope.MachineScope {
1793+ LinodeClient : mockLinodeClient ,
1794+ Client : mockK8sClient ,
1795+ LinodeMachine : & infrav1alpha2.LinodeMachine {
1796+ ObjectMeta : metav1.ObjectMeta {
1797+ Namespace : "default" ,
1798+ },
1799+ Spec : infrav1alpha2.LinodeMachineSpec {
1800+ IPv6Options : & infrav1alpha2.IPv6CreateOptions {
1801+ EnableSLAAC : ptr .To (true ),
1802+ IsPublicIPv6 : ptr .To (true ),
1803+ },
1804+ },
1805+ },
1806+ LinodeCluster : & infrav1alpha2.LinodeCluster {
1807+ Spec : infrav1alpha2.LinodeClusterSpec {
1808+ Network : infrav1alpha2.NetworkSpec {
1809+ SubnetName : tc .subnetName ,
1810+ UseNewNetworkInterfaces : true ,
1811+ },
1812+ },
1813+ },
1814+ }
1815+
1816+ // Call the function being tested
1817+ linodeIface , err := getVPCLinodeInterfaceConfig (ctx , machineScope , tc .linodeInterfaces , logger , tc .vpcRef )
1818+
1819+ // Check expectations
1820+ validateInterfaceExpectations (t , err , nil , linodeIface , tc .expectErr , tc .expectErrMsg , false , tc .expectLinodeInterface , tc .expectSubnetID )
1821+
1822+ // Additional check for interface updates
1823+ if ! tc .expectErr && ! tc .expectLinodeInterface && len (tc .linodeInterfaces ) > 0 && tc .linodeInterfaces [0 ].VPC != nil {
1824+ require .NotNil (t , tc .linodeInterfaces [0 ].VPC .SubnetID )
1825+ require .Equal (t , tc .expectSubnetID , tc .linodeInterfaces [0 ].VPC .SubnetID )
1826+ }
1827+ })
1828+ }
1829+ }
1830+
15481831func TestGetTags (t * testing.T ) {
15491832 t .Parallel ()
15501833
0 commit comments