Skip to content

Commit b8546ec

Browse files
jaredledvinaHadrienPatte
authored andcommitted
azure: derive AzureInterface VMSS/VM/RG values from the interface ID
The resource group, VMSS name and VM ID were cached in unexported json:"-" fields, so an interface built from the Azure API never matched the copy read back from the apiserver and the operator rewrote /status on every sync. Derive them from ID on demand instead. SetID() then only assigns ID, so remove it. Signed-off-by: Jared Ledvina <jared.ledvina@datadoghq.com>
1 parent e4abdef commit b8546ec

13 files changed

Lines changed: 107 additions & 70 deletions

File tree

pkg/azure/api/api.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,7 @@ func parseInterface(logger *slog.Logger, iface *armnetwork.Interface, subnets ip
325325
}
326326

327327
if iface.ID != nil {
328-
i.SetID(*iface.ID)
328+
i.ID = *iface.ID
329329
}
330330

331331
if iface.Name != nil {

pkg/azure/api/api_test.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@ import (
1212
"github.com/cilium/hive/hivetest"
1313
"github.com/stretchr/testify/require"
1414

15-
// Required so SetID() resolves the Azure resource-ID parser.
16-
_ "github.com/cilium/cilium/pkg/azure/types/azureid"
1715
iputil "github.com/cilium/cilium/pkg/ip"
1816
ipamTypes "github.com/cilium/cilium/pkg/ipam/types"
1917
)
@@ -156,6 +154,7 @@ func TestParseInterface(t *testing.T) {
156154
t.Run(tt.name, func(t *testing.T) {
157155
_, got := parseInterface(hivetest.Logger(t), tt.iface, tt.subnets, tt.usePrimary)
158156
require.NotNil(t, got)
157+
require.Equal(t, ifaceID, got.ID)
159158
require.Equal(t, tt.expectedIP, got.IP)
160159
require.Equal(t, tt.expectedSubnetID, got.Subnet.ID)
161160
require.Equal(t, tt.expectedCIDR, got.Subnet.CIDR)

pkg/azure/api/mock/mock_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ import (
1111
"github.com/stretchr/testify/require"
1212

1313
"github.com/cilium/cilium/pkg/azure/types"
14-
// Register the Azure resource-ID parser so AzureInterface.SetID() can
15-
// populate VMSS/VM/RG fields used by AssignPrivateIpAddressesVMSS lookup.
14+
// Register the Azure resource-ID parser so AzureInterface.GetVMID()
15+
// resolves, which the AssignPrivateIpAddressesVMSS lookup compares against.
1616
_ "github.com/cilium/cilium/pkg/azure/types/azureid"
1717
ipamTypes "github.com/cilium/cilium/pkg/ipam/types"
1818
)
@@ -36,7 +36,7 @@ func TestMock(t *testing.T) {
3636
ifaceID := "/subscriptions/xxx/resourceGroups/g1/providers/Microsoft.Compute/virtualMachineScaleSets/vmss11/virtualMachines/vm1/networkInterfaces/vmss11"
3737
instances = ipamTypes.NewInstanceMap()
3838
resource := &types.AzureInterface{Name: "eth0"}
39-
resource.SetID(ifaceID)
39+
resource.ID = ifaceID
4040
instances.Update("vm1", resource.DeepCopy())
4141
api.UpdateInstances(instances)
4242
nics, err = api.ListAllNetworkInterfaces(t.Context())
@@ -68,7 +68,7 @@ func TestMock(t *testing.T) {
6868
vmIfaceID := "/subscriptions/xxx/resourceGroups/g1/providers/Microsoft.Network/networkInterfaces/vm22-if"
6969
vmInstances := ipamTypes.NewInstanceMap()
7070
resource = &types.AzureInterface{Name: "eth0"}
71-
resource.SetID(vmIfaceID)
71+
resource.ID = vmIfaceID
7272
vmInstances.Update("vm2", resource.DeepCopy())
7373
require.NoError(t, err)
7474
require.Equal(t, 1, vmInstances.NumInstances())

pkg/azure/ipam/instances.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,8 @@ import (
1616
"github.com/cilium/cilium/operator/pkg/ipam/nodemanager"
1717
"github.com/cilium/cilium/pkg/azure/types"
1818

19-
// Register the Azure resource-ID parser. This is the canonical place
20-
// for Azure-IPAM-enabled binaries to wire in pkg/azure/types' parser
21-
// so AzureInterface.SetID() can populate the VMSS/VM/RG fields.
19+
// Registers the Azure resource-ID parser used by AzureInterface's VMSS/VM
20+
// getters.
2221
_ "github.com/cilium/cilium/pkg/azure/types/azureid"
2322
ipamTypes "github.com/cilium/cilium/pkg/ipam/types"
2423
v2 "github.com/cilium/cilium/pkg/k8s/apis/cilium.io/v2"

pkg/azure/ipam/instances_test.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ func iteration1(t *testing.T, api *apimock.API, mngr *InstancesManager) {
7979
},
8080
State: types.StateSucceeded,
8181
}
82-
resource.SetID("intf-1")
82+
resource.ID = "intf-1"
8383
instances.Update("i-1", resource.DeepCopy())
8484

8585
resource = &types.AzureInterface{
@@ -93,7 +93,7 @@ func iteration1(t *testing.T, api *apimock.API, mngr *InstancesManager) {
9393
},
9494
State: types.StateSucceeded,
9595
}
96-
resource.SetID("intf-3")
96+
resource.ID = "intf-3"
9797
instances.Update("i-2", resource.DeepCopy())
9898

9999
api.UpdateInstances(instances)
@@ -117,7 +117,7 @@ func iteration2(t *testing.T, api *apimock.API, mngr *InstancesManager) {
117117
},
118118
State: types.StateSucceeded,
119119
}
120-
resource.SetID("intf-1")
120+
resource.ID = "intf-1"
121121
instances.Update("i-1", resource.DeepCopy())
122122

123123
resource = &types.AzureInterface{
@@ -131,7 +131,7 @@ func iteration2(t *testing.T, api *apimock.API, mngr *InstancesManager) {
131131
},
132132
State: types.StateSucceeded,
133133
}
134-
resource.SetID("intf-2")
134+
resource.ID = "intf-2"
135135
instances.Update("i-1", resource.DeepCopy())
136136

137137
resource = &types.AzureInterface{
@@ -145,7 +145,7 @@ func iteration2(t *testing.T, api *apimock.API, mngr *InstancesManager) {
145145
},
146146
State: types.StateSucceeded,
147147
}
148-
resource.SetID("intf-3")
148+
resource.ID = "intf-3"
149149
instances.Update("i-2", resource.DeepCopy())
150150

151151
api.UpdateInstances(instances)
@@ -211,7 +211,7 @@ func TestResyncInstancePreservesOtherNodesSubnets(t *testing.T) {
211211
},
212212
State: types.StateSucceeded,
213213
}
214-
iface1.SetID("intf-vm-1")
214+
iface1.ID = "intf-vm-1"
215215
instances.Update("vm-1", iface1.DeepCopy())
216216

217217
iface2 := &types.AzureInterface{
@@ -225,7 +225,7 @@ func TestResyncInstancePreservesOtherNodesSubnets(t *testing.T) {
225225
},
226226
State: types.StateSucceeded,
227227
}
228-
iface2.SetID("intf-vm-2")
228+
iface2.ID = "intf-vm-2"
229229
instances.Update("vm-2", iface2.DeepCopy())
230230

231231
api.UpdateInstances(instances)
@@ -278,7 +278,7 @@ func TestExtractSubnetIDs(t *testing.T) {
278278
},
279279
},
280280
}
281-
resource.SetID(interfaceID)
281+
resource.ID = interfaceID
282282

283283
instances.Update(instanceID, resource.DeepCopy())
284284
}

pkg/azure/ipam/ipam_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ func TestIpamPreAllocate8(t *testing.T) {
161161
},
162162
State: types.StateSucceeded,
163163
}
164-
resource.SetID("/subscriptions/xxx/resourceGroups/g1/providers/Microsoft.Compute/virtualMachineScaleSets/vmss11/virtualMachines/vm1/networkInterfaces/vmss11")
164+
resource.ID = "/subscriptions/xxx/resourceGroups/g1/providers/Microsoft.Compute/virtualMachineScaleSets/vmss11/virtualMachines/vm1/networkInterfaces/vmss11"
165165
vm1ID := "/subscriptions/xxx/resourceGroups/g1/providers/Microsoft.Compute/virtualMachineScaleSets/vmss11/virtualMachines/vm1"
166166
m.Update(vm1ID, resource.DeepCopy())
167167
api.UpdateInstances(m)
@@ -223,7 +223,7 @@ func TestIpamMinAllocate10(t *testing.T) {
223223
},
224224
State: types.StateSucceeded,
225225
}
226-
resource.SetID("/subscriptions/xxx/resourceGroups/g1/providers/Microsoft.Compute/virtualMachineScaleSets/vmss11/virtualMachines/vm1/networkInterfaces/vmss11")
226+
resource.ID = "/subscriptions/xxx/resourceGroups/g1/providers/Microsoft.Compute/virtualMachineScaleSets/vmss11/virtualMachines/vm1/networkInterfaces/vmss11"
227227
vm1ID := "/subscriptions/xxx/resourceGroups/g1/providers/Microsoft.Compute/virtualMachineScaleSets/vmss11/virtualMachines/vm1"
228228
m.Update(vm1ID, resource.DeepCopy())
229229
api.UpdateInstances(m)
@@ -315,7 +315,7 @@ func TestIpamManyNodes(t *testing.T) {
315315
},
316316
State: types.StateSucceeded,
317317
}
318-
resource.SetID(fmt.Sprintf("/subscriptions/xxx/resourceGroups/g1/providers/Microsoft.Compute/virtualMachineScaleSets/vmss11/virtualMachines/vm%d/networkInterfaces/vmss11", i))
318+
resource.ID = fmt.Sprintf("/subscriptions/xxx/resourceGroups/g1/providers/Microsoft.Compute/virtualMachineScaleSets/vmss11/virtualMachines/vm%d/networkInterfaces/vmss11", i)
319319
allInstances.Update(fmt.Sprintf("/subscriptions/xxx/resourceGroups/g1/providers/Microsoft.Compute/virtualMachineScaleSets/vmss11/virtualMachines/vm%d", i), resource.DeepCopy())
320320
}
321321

@@ -386,7 +386,7 @@ func benchmarkAllocWorker(b *testing.B, workers int64, delay time.Duration, rate
386386
Addresses: []types.AzureAddress{},
387387
State: types.StateSucceeded,
388388
}
389-
resource.SetID(fmt.Sprintf("/subscriptions/xxx/resourceGroups/g1/providers/Microsoft.Compute/virtualMachineScaleSets/vmss11/virtualMachines/vm%d/networkInterfaces/vmss11", i))
389+
resource.ID = fmt.Sprintf("/subscriptions/xxx/resourceGroups/g1/providers/Microsoft.Compute/virtualMachineScaleSets/vmss11/virtualMachines/vm%d/networkInterfaces/vmss11", i)
390390
allInstances.Update(fmt.Sprintf("/subscriptions/xxx/resourceGroups/g1/providers/Microsoft.Compute/virtualMachineScaleSets/vmss11/virtualMachines/vm%d", i), resource.DeepCopy())
391391
}
392392

pkg/azure/ipam/node.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,10 +156,11 @@ func (n *Node) AllocateIPs(ctx context.Context, a *nodemanager.AllocationAction)
156156
return fmt.Errorf("invalid interface object")
157157
}
158158

159-
if iface.GetVMScaleSetName() == "" {
159+
vmss := iface.GetVMScaleSetName()
160+
if vmss == "" {
160161
return n.manager.api.AssignPrivateIpAddressesVM(ctx, string(a.PoolID), iface.Name, a.IPv4.AvailableForAllocation)
161162
} else {
162-
return n.manager.api.AssignPrivateIpAddressesVMSS(ctx, iface.GetVMID(), iface.GetVMScaleSetName(), string(a.PoolID), iface.Name, a.IPv4.AvailableForAllocation)
163+
return n.manager.api.AssignPrivateIpAddressesVMSS(ctx, iface.GetVMID(), vmss, string(a.PoolID), iface.Name, a.IPv4.AvailableForAllocation)
163164
}
164165
}
165166

pkg/azure/ipam/node_stats_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ func newCapacityTestInterface(name, id, primaryIP string, secondaryIPs ...string
5454
Addresses: addrs,
5555
State: types.StateSucceeded,
5656
}
57-
iface.SetID(id)
57+
iface.ID = id
5858
return iface
5959
}
6060

pkg/azure/types/azureid/azureid.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
// pkg/azure/types via CiliumNode's AzureSpec).
1010
//
1111
// On import, this package registers Parse with pkg/azure/types so that
12-
// AzureInterface.SetID() can extract the resource group, VMSS name, and VM ID
13-
// from a network interface resource ID.
12+
// AzureInterface's GetResourceGroup(), GetVMScaleSetName(), and GetVMID() can
13+
// derive their values from the network interface resource ID.
1414
package azureid
1515

1616
import (

pkg/azure/types/extract_ids.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ package types
88
// from pkg/azure/types/azureid (which uses the Azure SDK) so that pkg/azure/types
99
// itself does not transitively pull the Azure SDK into every consumer of
1010
// CiliumNode (which embeds AzureSpec). Non-Azure binaries leave this stub in
11-
// place; they never call extractIDs() on real Azure resource IDs.
11+
// place.
1212
var resourceIDParser = func(_ string) (resourceGroup, vmssName, vmID string) {
1313
return "", "", ""
1414
}

0 commit comments

Comments
 (0)