package queue import ( "context" "encoding/json" "fmt" ) // Op type string constants for WAQ operations. const ( OpNetBoxCreateDevice = "netbox.create_device" OpNetBoxPatchCustomFields = "netbox.patch_custom_fields" ) // CreateDevicePayload is the JSON payload for OpNetBoxCreateDevice ops. type CreateDevicePayload struct { Name string `json:"name"` AssetTag string `json:"asset_tag"` DeviceTypeID int32 `json:"device_type_id"` RoleID int32 `json:"role_id"` SiteID int32 `json:"site_id"` } // PatchCustomFieldsPayload is the JSON payload for OpNetBoxPatchCustomFields ops. type PatchCustomFieldsPayload struct { DeviceID int64 `json:"device_id"` Patch map[string]interface{} `json:"patch"` } // NetBoxOpsClient is the subset of netbox.Client that the WAQ handler needs. // Using an interface here allows tests to inject a mock without importing netbox. type NetBoxOpsClient interface { CreateDevice(ctx context.Context, name, assetTag string, deviceTypeID, roleID, siteID int32) (int64, error) PatchCustomFields(ctx context.Context, deviceID int64, patch map[string]interface{}) error } // NewNetBoxOpHandler returns an OpHandler that processes netbox WAQ operations. // Pass a *netbox.Client as the client argument (it satisfies NetBoxOpsClient). // // Routing: // - OpNetBoxCreateDevice → client.CreateDevice // - OpNetBoxPatchCustomFields → client.PatchCustomFields // - Unknown op type → error (op will be re-queued, not silently dropped) func NewNetBoxOpHandler(client NetBoxOpsClient) OpHandler { return func(ctx context.Context, op PendingOp) error { switch op.Type { case OpNetBoxCreateDevice: var p CreateDevicePayload if err := json.Unmarshal(op.Payload, &p); err != nil { return fmt.Errorf("decode create_device payload: %w", err) } _, err := client.CreateDevice(ctx, p.Name, p.AssetTag, p.DeviceTypeID, p.RoleID, p.SiteID) return err case OpNetBoxPatchCustomFields: var p PatchCustomFieldsPayload if err := json.Unmarshal(op.Payload, &p); err != nil { return fmt.Errorf("decode patch_custom_fields payload: %w", err) } return client.PatchCustomFields(ctx, p.DeviceID, p.Patch) default: return fmt.Errorf("unknown op type: %q", op.Type) } } }