Skip to content

Commit

Permalink
Fix network re-creation in machinebroker (#886)
Browse files Browse the repository at this point in the history
Remove the network provider ID from the waiters map once an emit
successuflly finished. This solves the problem that in case the network
has been removed (e.g. via network GC controller), it is never
recreated. This causes a problem when brokering machine and NIC
resources as the OwnerRef can not be set on a non existing network
resource.
  • Loading branch information
afritzler authored Oct 16, 2023
1 parent 0f99319 commit 2ea678d
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 0 deletions.
3 changes: 3 additions & 0 deletions broker/machinebroker/networks/networks.go
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,9 @@ func (e *Manager) emit(providerID string, network *networkingv1alpha1.Network, e
w.network = network
w.error = err
close(w.done)
// Remove providerID from waiters map once the emit call finishes. Otherwise, we won't be able to recreate
// the network if it has been deleted (e.g. via GC when the network has been released due to the lack of consumers).
delete(e.waitersByProviderID, providerID)
}

func (e *Manager) GetNetwork(ctx context.Context, providerID string) (*networkingv1alpha1.Network, error) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,4 +94,97 @@ var _ = Describe("AttachNetworkInterface", func() {
State: networkingv1alpha1.NetworkStateAvailable,
}))
})

It("should correctly re-create a network in case it has been removed", func(ctx SpecContext) {
By("creating a machine")
createMachineRes, err := srv.CreateMachine(ctx, &ori.CreateMachineRequest{
Machine: &ori.Machine{
Spec: &ori.MachineSpec{
Power: ori.Power_POWER_ON,
Image: &ori.ImageSpec{
Image: "example.org/foo:latest",
},
Class: machineClass.Name,
},
},
})
Expect(err).NotTo(HaveOccurred())
machineID := createMachineRes.Machine.Metadata.Id

By("attaching a network interface")
Expect(srv.AttachNetworkInterface(ctx, &ori.AttachNetworkInterfaceRequest{
MachineId: machineID,
NetworkInterface: &ori.NetworkInterface{
Name: "my-nic",
NetworkId: "network-id",
Ips: []string{"10.0.0.1"},
},
})).Error().NotTo(HaveOccurred())

By("getting the onmetal machine")
onmetalMachine := &computev1alpha1.Machine{}
onmetalMachineKey := client.ObjectKey{Namespace: ns.Name, Name: machineID}
Expect(k8sClient.Get(ctx, onmetalMachineKey, onmetalMachine)).To(Succeed())

By("inspecting the onmetal machine's network interfaces")
Expect(onmetalMachine.Spec.NetworkInterfaces).To(ConsistOf(MatchAllFields(Fields{
"Name": Equal("my-nic"),
"NetworkInterfaceSource": MatchFields(IgnoreExtras, Fields{
"NetworkInterfaceRef": PointTo(MatchAllFields(Fields{
"Name": Not(BeEmpty()),
})),
}),
})))

By("getting the corresponding onmetal network interface")
nic := &networkingv1alpha1.NetworkInterface{}
nicName := onmetalMachine.Spec.NetworkInterfaces[0].NetworkInterfaceRef.Name
nicKey := client.ObjectKey{Namespace: ns.Name, Name: nicName}
Expect(k8sClient.Get(ctx, nicKey, nic)).To(Succeed())

By("inspecting the onmetal network interface")
Expect(nic.Spec.IPs).To(Equal([]networkingv1alpha1.IPSource{
{Value: commonv1alpha1.MustParseNewIP("10.0.0.1")},
}))

By("getting the referenced onmetal network")
network := &networkingv1alpha1.Network{}
networkKey := client.ObjectKey{Namespace: ns.Name, Name: nic.Spec.NetworkRef.Name}
Expect(k8sClient.Get(ctx, networkKey, network)).To(Succeed())

By("inspecting the onmetal network")
Expect(network.Spec).To(Equal(networkingv1alpha1.NetworkSpec{
ProviderID: "network-id",
}))
Expect(network.Status).To(Equal(networkingv1alpha1.NetworkStatus{
State: networkingv1alpha1.NetworkStateAvailable,
}))

By("detaching the network interface")
Expect(srv.DetachNetworkInterface(ctx, &ori.DetachNetworkInterfaceRequest{
MachineId: machineID,
Name: "my-nic",
})).Error().NotTo(HaveOccurred())

By("deleting the network")
Expect(k8sClient.Delete(ctx, network)).To(Succeed())

By("re-attaching a network interface")
Expect(srv.AttachNetworkInterface(ctx, &ori.AttachNetworkInterfaceRequest{
MachineId: machineID,
NetworkInterface: &ori.NetworkInterface{
Name: "my-nic",
NetworkId: "network-id",
Ips: []string{"10.0.0.1"},
},
})).Error().NotTo(HaveOccurred())

By("inspecting the onmetal network again")
Expect(network.Spec).To(Equal(networkingv1alpha1.NetworkSpec{
ProviderID: "network-id",
}))
Expect(network.Status).To(Equal(networkingv1alpha1.NetworkStatus{
State: networkingv1alpha1.NetworkStateAvailable,
}))
})
})

0 comments on commit 2ea678d

Please sign in to comment.