Skip to content

Commit c4c46a9

Browse files
authored
Fetch internal IP from dhcp server (#748)
* Fetch internal IP from dhcp server * Localised inialising the dhcp cache store * Localise caching to power vs controller
1 parent 595c787 commit c4c46a9

File tree

8 files changed

+518
-6
lines changed

8 files changed

+518
-6
lines changed

cloud/scope/powervs_machine.go

Lines changed: 98 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import (
3333
powerVSUtils "github.com/ppc64le-cloud/powervs-utils"
3434
corev1 "k8s.io/api/core/v1"
3535
"k8s.io/apimachinery/pkg/types"
36+
"k8s.io/client-go/tools/cache"
3637
"k8s.io/klog/v2/klogr"
3738
"k8s.io/utils/pointer"
3839
capiv1beta1 "sigs.k8s.io/cluster-api/api/v1beta1"
@@ -60,6 +61,7 @@ type PowerVSMachineScopeParams struct {
6061
IBMPowerVSMachine *infrav1beta1.IBMPowerVSMachine
6162
IBMPowerVSImage *infrav1beta1.IBMPowerVSImage
6263
ServiceEndpoint []endpoints.ServiceEndpoint
64+
DHCPIPCacheStore cache.Store
6365
}
6466

6567
// PowerVSMachineScope defines a scope defined around a Power VS Machine.
@@ -75,6 +77,7 @@ type PowerVSMachineScope struct {
7577
IBMPowerVSMachine *infrav1beta1.IBMPowerVSMachine
7678
IBMPowerVSImage *infrav1beta1.IBMPowerVSImage
7779
ServiceEndpoint []endpoints.ServiceEndpoint
80+
DHCPIPCacheStore cache.Store
7881
}
7982

8083
// NewPowerVSMachineScope creates a new PowerVSMachineScope from the supplied parameters.
@@ -163,7 +166,7 @@ func NewPowerVSMachineScope(params PowerVSMachineScopeParams) (scope *PowerVSMac
163166
scope.SetRegion(region)
164167
scope.SetZone(*res.RegionID)
165168

166-
options := powervs.ServiceOptions{
169+
serviceOptions := powervs.ServiceOptions{
167170
IBMPIOptions: &ibmpisession.IBMPIOptions{
168171
Debug: params.Logger.V(DEBUGLEVEL).Enabled(),
169172
UserAccount: account,
@@ -175,17 +178,17 @@ func NewPowerVSMachineScope(params PowerVSMachineScopeParams) (scope *PowerVSMac
175178

176179
// Fetch the service endpoint.
177180
if svcEndpoint := endpoints.FetchPVSEndpoint(region, params.ServiceEndpoint); svcEndpoint != "" {
178-
options.IBMPIOptions.URL = svcEndpoint
181+
serviceOptions.IBMPIOptions.URL = svcEndpoint
179182
scope.Logger.V(3).Info("overriding the default powervs service endpoint")
180183
}
181184

182-
c, err := powervs.NewService(options)
185+
c, err := powervs.NewService(serviceOptions)
183186
if err != nil {
184187
err = fmt.Errorf("failed to create PowerVS service")
185188
return
186189
}
187190
scope.IBMPowerVSClient = c
188-
191+
scope.DHCPIPCacheStore = params.DHCPIPCacheStore
189192
return scope, nil
190193
}
191194

@@ -435,6 +438,97 @@ func (m *PowerVSMachineScope) SetAddresses(instance *models.PVMInstance) {
435438
}
436439
}
437440
m.IBMPowerVSMachine.Status.Addresses = addresses
441+
if len(addresses) > 2 {
442+
// If the address length is more than 2 means either NodeInternalIP or NodeExternalIP is updated so return
443+
return
444+
}
445+
// In this case there is no IP found under instance.Networks, So try to fetch the IP from cache or DHCP server
446+
// Look for DHCP IP from the cache
447+
obj, exists, err := m.DHCPIPCacheStore.GetByKey(*instance.ServerName)
448+
if err != nil {
449+
m.Error(err, "failed to fetch the DHCP IP address from cache store", "VM", *instance.ServerName)
450+
}
451+
if exists {
452+
m.Info("found IP for VM from DHCP cache", "IP", obj.(powervs.VMip).IP, "VM", *instance.ServerName)
453+
addresses = append(addresses, corev1.NodeAddress{
454+
Type: corev1.NodeInternalIP,
455+
Address: obj.(powervs.VMip).IP,
456+
})
457+
m.IBMPowerVSMachine.Status.Addresses = addresses
458+
return
459+
}
460+
// Fetch the VM network ID
461+
networkID, err := getNetworkID(m.IBMPowerVSMachine.Spec.Network, m)
462+
if err != nil {
463+
m.Error(err, "failed to fetch network id from network resource", "VM", *instance.ServerName)
464+
return
465+
}
466+
// Fetch the details of the network attached to the VM
467+
var pvmNetwork *models.PVMInstanceNetwork
468+
for _, network := range instance.Networks {
469+
if network.NetworkID == *networkID {
470+
pvmNetwork = network
471+
m.Info("found network attached to VM", "Network ID", network.NetworkID, "VM", *instance.ServerName)
472+
}
473+
}
474+
if pvmNetwork == nil {
475+
m.Info("failed to get network attached to VM", "VM", *instance.ServerName, "Network ID", *networkID)
476+
return
477+
}
478+
// Get all the DHCP servers
479+
dhcpServer, err := m.IBMPowerVSClient.GetAllDHCPServers()
480+
if err != nil {
481+
m.Error(err, "failed to get DHCP server")
482+
return
483+
}
484+
// Get the Details of DHCP server associated with the network
485+
var dhcpServerDetails *models.DHCPServerDetail
486+
for _, server := range dhcpServer {
487+
if *server.Network.ID == *networkID {
488+
m.Info("found DHCP server for network", "DHCP server ID", *server.ID, "network ID", *networkID)
489+
dhcpServerDetails, err = m.IBMPowerVSClient.GetDHCPServer(*server.ID)
490+
if err != nil {
491+
m.Error(err, "failed to get DHCP server details", "DHCP server ID", *server.ID)
492+
return
493+
}
494+
break
495+
}
496+
}
497+
if dhcpServerDetails == nil {
498+
errStr := fmt.Errorf("DHCP server details is nil")
499+
m.Error(errStr, "DHCP server associated with network is nil", "Network ID", *networkID)
500+
return
501+
}
502+
503+
// Fetch the VM IP using VM's mac from DHCP server lease
504+
var internalIP *string
505+
for _, lease := range dhcpServerDetails.Leases {
506+
if *lease.InstanceMacAddress == pvmNetwork.MacAddress {
507+
m.Info("found internal ip for VM from DHCP lease", "IP", *lease.InstanceIP, "VM", *instance.ServerName)
508+
internalIP = lease.InstanceIP
509+
break
510+
}
511+
}
512+
if internalIP == nil {
513+
errStr := fmt.Errorf("internal IP is nil")
514+
m.Error(errStr, "failed to get internal IP, DHCP lease not found for VM with MAC in DHCP network", "VM", *instance.ServerName,
515+
"MAC", pvmNetwork.MacAddress, "DHCP server ID", *dhcpServerDetails.ID)
516+
return
517+
}
518+
m.Info("found internal IP for VM from DHCP lease", "IP", *internalIP, "VM", *instance.ServerName)
519+
addresses = append(addresses, corev1.NodeAddress{
520+
Type: corev1.NodeInternalIP,
521+
Address: *internalIP,
522+
})
523+
// Update the cache with the ip and VM name
524+
err = m.DHCPIPCacheStore.Add(powervs.VMip{
525+
Name: *instance.ServerName,
526+
IP: *internalIP,
527+
})
528+
if err != nil {
529+
m.Error(err, "failed to update the DHCP cache store with the IP", "VM", *instance.ServerName, "IP", *internalIP)
530+
}
531+
m.IBMPowerVSMachine.Status.Addresses = addresses
438532
}
439533

440534
// SetInstanceState will set the state for the machine.

0 commit comments

Comments
 (0)