feat(02-01): install go-openai and add CreateDevice to NetBox client
- go get github.com/sashabaranov/go-openai v1.41.2 - Add CreateDevice(ctx, name, assetTag, deviceTypeID, roleID, siteID) → (int64, error) - Add DeleteDevice(ctx, id) for test cleanup - Use Int32As* oneOf helpers for go-netbox v4 FK fields - TestCreateDeviceValidation PASS; TestCreateDeviceLive SKIP (no live token)
This commit is contained in:
parent
7bebe2ed93
commit
6040ecc3cc
4 changed files with 94 additions and 0 deletions
1
go.mod
1
go.mod
|
|
@ -18,6 +18,7 @@ require (
|
|||
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
|
||||
github.com/redis/go-redis/v9 v9.18.0 // indirect
|
||||
github.com/sagikazarmark/locafero v0.11.0 // indirect
|
||||
github.com/sashabaranov/go-openai v1.41.2 // indirect
|
||||
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect
|
||||
github.com/spf13/afero v1.15.0 // indirect
|
||||
github.com/spf13/cast v1.10.0 // indirect
|
||||
|
|
|
|||
2
go.sum
2
go.sum
|
|
@ -37,6 +37,8 @@ github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZV
|
|||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||
github.com/sagikazarmark/locafero v0.11.0 h1:1iurJgmM9G3PA/I+wWYIOw/5SyBtxapeHDcg+AAIFXc=
|
||||
github.com/sagikazarmark/locafero v0.11.0/go.mod h1:nVIGvgyzw595SUSUE6tvCp3YYTeHs15MvlmU87WwIik=
|
||||
github.com/sashabaranov/go-openai v1.41.2 h1:vfPRBZNMpnqu8ELsclWcAvF19lDNgh1t6TVfFFOPiSM=
|
||||
github.com/sashabaranov/go-openai v1.41.2/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adOgerWeFyZLUhAKRg=
|
||||
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 h1:+jumHNA0Wrelhe64i8F6HNlS8pkoyMv5sreGx2Ry5Rw=
|
||||
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8/go.mod h1:3n1Cwaq1E1/1lhQhtRK2ts/ZwZEhjcQeJQ1RuC6Q/8U=
|
||||
github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I=
|
||||
|
|
|
|||
|
|
@ -72,6 +72,41 @@ func (c *Client) GetDevice(ctx context.Context, id int) (*Device, error) {
|
|||
return &dev, nil
|
||||
}
|
||||
|
||||
// CreateDevice creates a new device in NetBox with the given name and asset tag.
|
||||
// deviceTypeID, roleID, and siteID must be valid NetBox IDs (pre-existing objects).
|
||||
// Returns the new device's NetBox ID or error.
|
||||
func (c *Client) CreateDevice(ctx context.Context, name, assetTag string, deviceTypeID, roleID, siteID int32) (int64, error) {
|
||||
if name == "" {
|
||||
return 0, fmt.Errorf("device name must not be empty")
|
||||
}
|
||||
// go-netbox v4 uses oneOf wrapper types for FK fields — use the Int32As* helpers.
|
||||
dtID := nb.Int32AsDeviceBayTemplateRequestDeviceType(&deviceTypeID)
|
||||
role := nb.Int32AsDeviceWithConfigContextRequestRole(&roleID)
|
||||
site := nb.Int32AsDeviceWithConfigContextRequestSite(&siteID)
|
||||
|
||||
req := nb.NewWritableDeviceWithConfigContextRequest(dtID, role, site)
|
||||
req.SetName(name)
|
||||
if assetTag != "" {
|
||||
req.SetAssetTag(assetTag)
|
||||
}
|
||||
result, _, err := c.api.DcimAPI.DcimDevicesCreate(ctx).
|
||||
WritableDeviceWithConfigContextRequest(*req).Execute()
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("CreateDevice %q: %w", name, err)
|
||||
}
|
||||
return int64(result.GetId()), nil
|
||||
}
|
||||
|
||||
// DeleteDevice removes a device from NetBox by its internal ID.
|
||||
// Used primarily for test cleanup after CreateDevice integration tests.
|
||||
func (c *Client) DeleteDevice(ctx context.Context, id int64) error {
|
||||
_, err := c.api.DcimAPI.DcimDevicesDestroy(ctx, int32(id)).Execute()
|
||||
if err != nil {
|
||||
return fmt.Errorf("DeleteDevice %d: %w", id, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// deviceFromNetBox maps a go-netbox DeviceWithConfigContext to our Device type.
|
||||
// Custom fields are mapped separately via ParseCustomFields.
|
||||
func deviceFromNetBox(d nb.DeviceWithConfigContext) Device {
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package netbox_test
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
|
|
@ -60,3 +61,58 @@ func TestListDevicesLive(t *testing.T) {
|
|||
t.Logf("found %d devices in NetBox", len(devices))
|
||||
// Not asserting count — NetBox may be empty; just assert no error
|
||||
}
|
||||
|
||||
// TestCreateDeviceValidation verifies that CreateDevice rejects an empty name
|
||||
// without making any NetBox API call.
|
||||
func TestCreateDeviceValidation(t *testing.T) {
|
||||
c, err := netbox.NewClient("http://10.5.0.130:8000/api", "sometoken")
|
||||
if err != nil {
|
||||
t.Fatalf("NewClient: %v", err)
|
||||
}
|
||||
_, err = c.CreateDevice(context.Background(), "", "HW-00001", 1, 1, 1)
|
||||
if err == nil {
|
||||
t.Error("expected error for empty device name")
|
||||
}
|
||||
}
|
||||
|
||||
// TestCreateDeviceLive creates a real device in NetBox and deletes it as cleanup.
|
||||
// Requires HWLAB_NETBOX_TOKEN (40 chars) and HWLAB_TEST_SITE_ID to be set.
|
||||
func TestCreateDeviceLive(t *testing.T) {
|
||||
token := integrationToken(t)
|
||||
siteIDStr := os.Getenv("HWLAB_TEST_SITE_ID")
|
||||
if siteIDStr == "" {
|
||||
t.Skip("HWLAB_TEST_SITE_ID not set — skipping live CreateDevice test")
|
||||
}
|
||||
|
||||
// Parse site ID
|
||||
var siteID int32
|
||||
if _, err := fmt.Sscanf(siteIDStr, "%d", &siteID); err != nil {
|
||||
t.Fatalf("HWLAB_TEST_SITE_ID is not a valid int: %v", err)
|
||||
}
|
||||
|
||||
// These must exist in the NetBox instance used for integration testing.
|
||||
// Device type 1 and role 1 are typically pre-provisioned.
|
||||
const (
|
||||
testDeviceTypeID int32 = 1
|
||||
testRoleID int32 = 1
|
||||
)
|
||||
|
||||
c, err := netbox.NewClient("http://10.5.0.130:8000/api", token)
|
||||
if err != nil {
|
||||
t.Fatalf("NewClient: %v", err)
|
||||
}
|
||||
|
||||
id, err := c.CreateDevice(context.Background(), "hwlab-test-device", "HW-TEST-01", testDeviceTypeID, testRoleID, siteID)
|
||||
if err != nil {
|
||||
t.Fatalf("CreateDevice: %v", err)
|
||||
}
|
||||
if id <= 0 {
|
||||
t.Errorf("expected positive device ID, got %d", id)
|
||||
}
|
||||
t.Logf("created device id=%d — will clean up", id)
|
||||
|
||||
// Cleanup: delete the test device
|
||||
if err := c.DeleteDevice(context.Background(), id); err != nil {
|
||||
t.Logf("cleanup warning: DeleteDevice(%d): %v", id, err)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue