From a52c8a27691376bce4b3210d6c31a3a737a4dd7c Mon Sep 17 00:00:00 2001 From: Thomas Munzer Date: Wed, 28 Aug 2024 17:47:39 +0200 Subject: [PATCH] improve inventory processing --- internal/provider/org_inventory_resource.go | 5 +- .../terraform_to_sdk.go | 98 +++++++++++++------ 2 files changed, 71 insertions(+), 32 deletions(-) diff --git a/internal/provider/org_inventory_resource.go b/internal/provider/org_inventory_resource.go index 159ebd0c..f37c309b 100644 --- a/internal/provider/org_inventory_resource.go +++ b/internal/provider/org_inventory_resource.go @@ -160,7 +160,6 @@ func (r *orgInventoryResource) Update(ctx context.Context, req resource.UpdateRe return } - /////////////////////// Update orgId, err := uuid.Parse(plan.OrgId.ValueString()) if err != nil { resp.Diagnostics.AddError( @@ -169,11 +168,13 @@ func (r *orgInventoryResource) Update(ctx context.Context, req resource.UpdateRe ) return } + /////////////////////// Update diags = r.updateInventory(ctx, &orgId, &plan, &state) resp.Diagnostics.Append(diags...) if resp.Diagnostics.HasError() { return } + /////////////////////// Sync, required to get missing devices info (MAC, Serial, ...) state, diags = r.refreshInventory(ctx, &orgId, &plan) resp.Diagnostics.Append(diags...) @@ -312,7 +313,7 @@ func (r *orgInventoryResource) updateInventory(ctx context.Context, orgId *uuid. assign_body := models.InventoryUpdate{} assign_body.Op = models.InventoryUpdateOperationEnum_ASSIGN - assign_body.Macs = assign[k] + assign_body.Macs = v assign_body.DisableAutoConfig = types.BoolValue(false).ValueBoolPointer() assign_body.Managed = types.BoolValue(true).ValueBoolPointer() tflog.Info(ctx, "devices "+strings.Join(assign[k], ", ")+" to "+k) diff --git a/internal/resource_org_inventory/terraform_to_sdk.go b/internal/resource_org_inventory/terraform_to_sdk.go index 823503da..713cfb22 100644 --- a/internal/resource_org_inventory/terraform_to_sdk.go +++ b/internal/resource_org_inventory/terraform_to_sdk.go @@ -2,6 +2,7 @@ package resource_org_inventory import ( "context" + "fmt" "strings" "github.com/hashicorp/terraform-plugin-framework/diag" @@ -26,21 +27,53 @@ func genDeviceMap(devices *basetypes.ListValue) map[string]DevicesValue { return deviceMap } -func processAction(planDevice *DevicesValue, stateDevice *DevicesValue, assign map[string][]string, unassign []string) (map[string][]string, []string) { +func processAction(planDevice *DevicesValue, stateDevice *DevicesValue) string { + + if stateDevice != nil && stateDevice.SiteId.Equal(planDevice.SiteId) { + return "" + } else if planDevice.SiteId.ValueStringPointer() == nil { + // Planned Site ID nil > must be unassigned + return "unassign" + //*unassign = append(*unassign, stateDevice.Mac.ValueString()) + } else { + // Planned Site ID not not nil > must be assigned or reassiogned + return "assign" + // (*assign)[planDevice.SiteId.ValueString()] = append((*assign)[planDevice.SiteId.ValueString()], stateDevice.Mac.ValueString()) + } +} - // Site ID not in state but planed > must be assigned - if !stateDevice.SiteId.Equal(planDevice.SiteId) && planDevice.SiteId.ValueString() != "" { - assign[planDevice.SiteId.ValueString()] = append(assign[planDevice.SiteId.ValueString()], stateDevice.Mac.ValueString()) - // Site ID in state but not planed > must be unassigned +func processClaimedDevice(planDevice *DevicesValue, stateMap *map[string]DevicesValue) (string, string, string) { + var op, siteId, mac string + var magic string = strings.ToUpper(planDevice.Magic.ValueString()) + + if stateDevice, ok := (*stateMap)[magic]; ok { + // for already claimed devices + op = processAction(planDevice, &stateDevice) + mac = stateDevice.Mac.ValueString() + } else if planDevice.SiteId.ValueString() != "" { + // for devices not claimed with the site_id set + op = "assign" + } + siteId = planDevice.SiteId.ValueString() - } else if !stateDevice.SiteId.Equal(planDevice.SiteId) && planDevice.SiteId.ValueString() == "" { - unassign = append(unassign, stateDevice.Mac.ValueString()) - // State Site ID != Plan Site ID > must be reassigned + return op, mac, siteId +} +func processAdoptedDevice(planDevice *DevicesValue, stateMap *map[string]DevicesValue) (string, string, string) { + var op, siteId string + var mac string = strings.ToUpper(planDevice.Mac.ValueString()) + + if stateDevice, ok := (*stateMap)[mac]; ok { + // or adopted devices that are already known + op = processAction(planDevice, &stateDevice) + } else if planDevice.SiteId.ValueString() != "" { + // for adopted devices that are unknown and have the site_id set + op = "assign" } - return assign, unassign -} + siteId = planDevice.SiteId.ValueString() + return op, planDevice.Mac.ValueString(), siteId +} func TerraformToSdk(ctx context.Context, devices_plan *basetypes.ListValue, devices_state *basetypes.ListValue) ([]string, []string, []string, map[string]string, map[string][]string, diag.Diagnostics) { var diags diag.Diagnostics var claim []string @@ -49,34 +82,39 @@ func TerraformToSdk(ctx context.Context, devices_plan *basetypes.ListValue, devi assign_claim := make(map[string]string) assign := make(map[string][]string) - stateMap := genDeviceMap(devices_state) planMap := genDeviceMap(devices_plan) + stateMap := genDeviceMap(devices_state) - for _, dev_plan_attr := range devices_plan.Elements() { + for i, dev_plan_attr := range devices_plan.Elements() { var dpi interface{} = dev_plan_attr var dev_plan = dpi.(DevicesValue) + var op, mac, siteId string - var already_claimed bool = false - var magic string = strings.ToUpper(dev_plan.Magic.ValueString()) - var mac string = strings.ToUpper(dev_plan.Mac.ValueString()) - - if dev_state, ok := stateMap[magic]; ok { - // for already claimed devices - already_claimed = true - assign, unassign = processAction(&dev_plan, &dev_state, assign, unassign) - } else if dev_state, ok = stateMap[mac]; ok { - // for already adopted devices - already_claimed = true - assign, unassign = processAction(&dev_plan, &dev_state, assign, unassign) + if dev_plan.Magic.ValueString() != "" { + op, mac, siteId = processClaimedDevice(&dev_plan, &stateMap) + } else if dev_plan.Mac.ValueString() != "" { + op, mac, siteId = processAdoptedDevice(&dev_plan, &stateMap) + } else { + diags.AddError( + "Unable to process device in \"mist_org_inventory\"", + fmt.Sprintf("Claim Code and MAC Address not found for the device mist_org_inventory.devices[%s]", string(i)), + ) } - if !already_claimed && !dev_plan.Magic.IsNull() && !dev_plan.Magic.IsUnknown() { + // if the device is not claimed (unknown MAC Address), we will need to claim it to get the MAC address + if mac == "" && dev_plan.Magic.ValueString() != "" { claim = append(claim, dev_plan.Magic.ValueString()) - if dev_plan.SiteId.ValueStringPointer() != nil && dev_plan.SiteId.ValueString() != "" { - assign_claim[dev_plan.Magic.ValueString()] = dev_plan.SiteId.ValueString() + if siteId != "" { + assign_claim[dev_plan.Magic.ValueString()] = siteId + } + } else { + switch op { + case "assign": + assign[siteId] = append(assign[siteId], mac) + case "unassign": + unassign = append(unassign, mac) } } - } for _, dev_state_attr := range devices_state.Elements() { @@ -86,8 +124,8 @@ func TerraformToSdk(ctx context.Context, devices_plan *basetypes.ListValue, devi var mac string = strings.ToUpper(dev_state.Mac.ValueString()) if _, ok := planMap[magic]; magic != "" && !ok { unclaim = append(unclaim, dev_state.Serial.ValueString()) - } else if dev_state, ok = stateMap[mac]; !ok { - unassign = append(unassign, mac) + } else if _, ok = planMap[mac]; magic == "" && !ok { + unassign = append(unassign, dev_state.Mac.ValueString()) } }