diff --git a/internal/source/fmc/fmc_client.go b/internal/source/fmc/fmc_client.go index d5b4221b..8e430b7c 100644 --- a/internal/source/fmc/fmc_client.go +++ b/internal/source/fmc/fmc_client.go @@ -157,6 +157,11 @@ func (fmcc *fmcClient) MakeRequest(ctx context.Context, method, path string, bod ) for attempt := 0; attempt < maxRetries; attempt++ { + // Check if context is already canceled or expired + if ctx.Err() != nil { + return nil, ctx.Err() + } + resp, err = fmcc.makeRequestOnce(ctx, method, path, body) if err == nil { return resp, nil @@ -188,6 +193,7 @@ func (fmcc *fmcClient) GetDomains() ([]Domain, error) { limit := 25 domains := []Domain{} ctx := context.Background() + defer ctx.Done() for { apiResponse, err := fmcc.MakeRequest(ctx, http.MethodGet, fmt.Sprintf("fmc_platform/v1/info/domain?offset=%d&limit=%d", offset, limit), nil) if err != nil { @@ -225,6 +231,7 @@ func (fmcc *fmcClient) GetDevices(domainUUID string) ([]Device, error) { limit := 25 devices := []Device{} ctx := context.Background() + defer ctx.Done() devicesURL := fmt.Sprintf("fmc_config/v1/domain/%s/devices/devicerecords?offset=%d&limit=%d", domainUUID, offset, limit) for { apiResponse, err := fmcc.MakeRequest(ctx, http.MethodGet, devicesURL, nil) @@ -269,6 +276,7 @@ func (fmcc *fmcClient) GetDevicePhysicalInterfaces(domainUUID string, deviceID s limit := 25 pIfaces := []PhysicalInterface{} ctx := context.Background() + defer ctx.Done() pInterfacesURL := fmt.Sprintf("fmc_config/v1/domain/%s/devices/devicerecords/%s/physicalinterfaces?offset=%d&limit=%d", domainUUID, deviceID, offset, limit) for { apiResponse, err := fmcc.MakeRequest(ctx, http.MethodGet, pInterfacesURL, nil) @@ -374,6 +382,7 @@ type PhysicalInterfaceInfo struct { func (fmcc *fmcClient) GetPhysicalInterfaceInfo(domainUUID string, deviceID string, interfaceID string) (*PhysicalInterfaceInfo, error) { var pInterfaceInfo PhysicalInterfaceInfo ctx := context.Background() + defer ctx.Done() devicesURL := fmt.Sprintf("fmc_config/v1/domain/%s/devices/devicerecords/%s/physicalinterfaces/%s", domainUUID, deviceID, interfaceID) apiResponse, err := fmcc.MakeRequest(ctx, http.MethodGet, devicesURL, nil) if err != nil { @@ -398,6 +407,7 @@ func (fmcc *fmcClient) GetPhysicalInterfaceInfo(domainUUID string, deviceID stri func (fmcc *fmcClient) GetVLANInterfaceInfo(domainUUID string, deviceID string, interfaceID string) (*VLANInterfaceInfo, error) { var vlanInterfaceInfo VLANInterfaceInfo ctx := context.Background() + defer ctx.Done() devicesURL := fmt.Sprintf("fmc_config/v1/domain/%s/devices/devicerecords/%s/vlaninterfaces/%s", domainUUID, deviceID, interfaceID) apiResponse, err := fmcc.MakeRequest(ctx, http.MethodGet, devicesURL, nil) if err != nil { diff --git a/internal/source/vmware/vmware_sync.go b/internal/source/vmware/vmware_sync.go index e6d22eb3..ef7e92a4 100644 --- a/internal/source/vmware/vmware_sync.go +++ b/internal/source/vmware/vmware_sync.go @@ -136,7 +136,6 @@ func (vc *VmwareSource) syncHosts(nbi *inventory.NetboxInventory) error { for hostID, host := range vc.Hosts { var err error hostName := host.Name - hostCluster := nbi.ClustersIndexByName[vc.Clusters[vc.Host2Cluster[hostID]].Name] hostSite, err := common.MatchHostToSite(vc.Ctx, nbi, hostName, vc.HostSiteRelations) if err != nil { @@ -147,6 +146,15 @@ func (vc *VmwareSource) syncHosts(nbi *inventory.NetboxInventory) error { return fmt.Errorf("hostTenant: %s", err) } + hostCluster := nbi.ClustersIndexByName[vc.Clusters[vc.Host2Cluster[hostID]].Name] + if hostCluster == nil { + // Create a hypothetical cluster https://github.com/bl4ko/netbox-ssot/issues/141 + hostCluster, err = vc.createHypotheticalCluster(nbi, hostName, hostSite, hostTenant) + if err != nil { + return fmt.Errorf("add hypothetical cluster: %s", err) + } + } + // Extract host hardware info var hostUUID, hostModel, hostManufacturerName string if host.Summary.Hardware != nil { @@ -733,14 +741,6 @@ func (vc *VmwareSource) syncVM(nbi *inventory.NetboxInventory, vmKey string, vm // Cluster of the vm is same as the host vmCluster := vmHost.Cluster - // Create a hypothetical cluster if needed - if vmCluster == nil { - vmCluster, err = vc.createHypotheticalCluster(nbi, vmHost) - if err != nil { - return fmt.Errorf("add hypothetical cluster: %s", err) - } - } - // VM status vmStatus := &objects.VMStatusOffline if vm.Runtime.PowerState == types.VirtualMachinePowerStatePoweredOn { @@ -1249,7 +1249,7 @@ func (vc *VmwareSource) createVmwareClusterType(nbi *inventory.NetboxInventory) // createHypotheticalCluster creates a cluster with name clusterName. This function is needed // for all hosts that are not assigned to cluster so we can assign them to hypotheticalCluster. // for more see: https://github.com/bl4ko/netbox-ssot/issues/141 -func (vc *VmwareSource) createHypotheticalCluster(nbi *inventory.NetboxInventory, vmHost *objects.Device) (*objects.Cluster, error) { +func (vc *VmwareSource) createHypotheticalCluster(nbi *inventory.NetboxInventory, hostName string, hostSite *objects.Site, hostTenant *objects.Tenant) (*objects.Cluster, error) { clusterType, err := vc.createVmwareClusterType(nbi) if err != nil { return nil, fmt.Errorf("failed to add vmware ClusterType: %v", err) @@ -1261,20 +1261,15 @@ func (vc *VmwareSource) createHypotheticalCluster(nbi *inventory.NetboxInventory constants.CustomFieldSourceName: vc.SourceConfig.Name, }, }, - Name: vmHost.Name, + Name: hostName, Type: clusterType, Status: objects.ClusterStatusActive, - Site: vmHost.Site, - Tenant: vmHost.Tenant, + Site: hostSite, + Tenant: hostTenant, }) if err != nil { - return nil, fmt.Errorf("failed to add vmware cluster %s as Netbox cluster: %v", vmHost.Name, err) - } - vmHostCopy := *vmHost - vmHostCopy.Cluster = nbCluster - _, err = nbi.AddDevice(vc.Ctx, &vmHostCopy) - if err != nil { - return nil, fmt.Errorf("failed updating existing host with hypothetical cluster: %s", err) + return nil, fmt.Errorf("failed to add vmware hypothetical cluster %s as Netbox cluster: %v", hostName, err) } + return nbCluster, nil }