Skip to content
Snippets Groups Projects
Commit 3703f882 authored by d0m0reg00dthing's avatar d0m0reg00dthing Committed by Matt Layher
Browse files

Add Device (#20)

* Implement DCIM Device

* Adding self to AUTHORS

* fix typo & add test

* Add parent

* add more test

* Modify DeviceBay and ParentDevice type
parent 8bc2717e
No related branches found
No related tags found
No related merge requests found
...@@ -11,3 +11,4 @@ Contributors ...@@ -11,3 +11,4 @@ Contributors
------------ ------------
Allan Liu <aliu@digitalocean.com> Allan Liu <aliu@digitalocean.com>
Dave Cameron <dcameron@digitalocean.com> Dave Cameron <dcameron@digitalocean.com>
Quan D. Hoang <hdquan2014@gmail.com>
...@@ -18,6 +18,7 @@ package netbox ...@@ -18,6 +18,7 @@ package netbox
type DCIMService struct { type DCIMService struct {
c *Client c *Client
InventoryItems *InventoryItemsService InventoryItems *InventoryItemsService
Devices *DevicesService
} }
// NewDCIMService returns a DCIMService initialized with all sub-services. // NewDCIMService returns a DCIMService initialized with all sub-services.
...@@ -27,6 +28,9 @@ func NewDCIMService(client *Client) *DCIMService { ...@@ -27,6 +28,9 @@ func NewDCIMService(client *Client) *DCIMService {
InventoryItems: &InventoryItemsService{ InventoryItems: &InventoryItemsService{
c: client, c: client,
}, },
Devices: &DevicesService{
c: client,
},
} }
} }
......
// Copyright 2017 The go-netbox Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Code generated by generate_functions.go. DO NOT EDIT.
package netbox
import (
"encoding/json"
"fmt"
"net/http"
)
// DevicesService is used in a Client to access NetBox's dcim/devices API methods.
type DevicesService struct {
c *Client
}
// Get retrieves an Device object from NetBox by its ID.
func (s *DevicesService) Get(id int) (*Device, error) {
req, err := s.c.NewRequest(
http.MethodGet,
fmt.Sprintf("api/dcim/devices/%d/", id),
nil,
)
if err != nil {
return nil, err
}
t := new(Device)
err = s.c.Do(req, t)
if err != nil {
return nil, err
}
return t, nil
}
// List returns a Page associated with an NetBox API Endpoint.
func (s *DevicesService) List(options *ListDeviceOptions) *Page {
return NewPage(s.c, "api/dcim/devices/", options)
}
// Extract retrives a list of Device objects from page.
func (s *DevicesService) Extract(page *Page) ([]*Device, error) {
if err := page.Err(); err != nil {
return nil, err
}
var groups []*Device
if err := json.Unmarshal(page.data.Results, &groups); err != nil {
return nil, err
}
return groups, nil
}
// Create creates a new Device object in NetBox and returns the ID of the new object.
func (s *DevicesService) Create(data *Device) (int, error) {
req, err := s.c.NewJSONRequest(http.MethodPost, "api/dcim/devices/", nil, data)
if err != nil {
return 0, err
}
g := new(writableDevice)
err = s.c.Do(req, g)
if err != nil {
return 0, err
}
return g.ID, nil
}
// Update changes an existing Device object in NetBox, and returns the ID of the new object.
func (s *DevicesService) Update(data *Device) (int, error) {
req, err := s.c.NewJSONRequest(
http.MethodPatch,
fmt.Sprintf("api/dcim/devices/%d/", data.ID),
nil,
data,
)
if err != nil {
return 0, err
}
// g is just used to verify correct api result.
// data is not changed, because the g is not the full representation that one would
// get with Get. But if the response was unmarshaled into writableDevice correctly,
// everything went fine, and we do not need to update data.
g := new(writableDevice)
err = s.c.Do(req, g)
if err != nil {
return 0, err
}
return g.ID, nil
}
// Delete deletes an existing Device object from NetBox.
func (s *DevicesService) Delete(data *Device) error {
req, err := s.c.NewRequest(
http.MethodDelete,
fmt.Sprintf("api/dcim/devices/%d/", data.ID),
nil,
)
if err != nil {
return err
}
return s.c.Do(req, nil)
}
// Copyright 2017 The go-netbox Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Code generated by generate_basic_tests.go. DO NOT EDIT.
package netbox
import (
"encoding/json"
"errors"
"fmt"
"net/http"
"reflect"
"testing"
)
// Using this to override MarshalJSON
// In all cases when posting data to netbox-API, the Device.MarshalJSON is what you want,
// but not here as a return in testHandler
type serverDataDevice Device
func convertToServerDataDevice(data []*Device) []*serverDataDevice {
dataWant := make([]*serverDataDevice, len(data))
for i := range data {
tmp := serverDataDevice(*data[i])
dataWant[i] = &tmp
}
return dataWant
}
func TestBasicDeviceGet(t *testing.T) {
var tests = []struct {
desc string
want *Device
}{
{
desc: "Simple Device",
want: testDevice(1),
},
}
for i, tt := range tests {
t.Run(fmt.Sprintf("[%d] %s", i, tt.desc), func(t *testing.T) {
serverData := serverDataDevice(*tt.want)
c, done := testClient(t, testHandler(t, http.MethodGet, "/api/dcim/devices/1/", &serverData))
defer done()
res, err := c.DCIM.Devices.Get(1)
if err != nil {
t.Fatalf("unexpected error from Client.DCIM.Devices.Get: %v", err)
}
if want, got := tt.want, res; !reflect.DeepEqual(want, got) {
t.Fatalf("unexpected Device:\n- want: %v\n- got: %v", want, got)
}
})
}
}
func TestBasicDeviceGet404(t *testing.T) {
c, done := testClient(t, testStatusHandler(t, http.MethodGet, "/api/dcim/devices/1/", &struct {
Detail string `json:"detail"`
}{
Detail: "Not found.",
},
http.StatusNotFound))
defer done()
res, err := c.DCIM.Devices.Get(1)
errstr := "404 - Not found."
if want, got := errors.New(errstr), err; !reflect.DeepEqual(want, got) {
t.Fatalf("unexpected error from Client.DCIM.Devices.Get:\n- want: %v\n- got: %v", want, got)
}
if res != nil {
t.Fatalf("unexpected result:\n- want: %v\n- got: %v", nil, res)
}
}
func TestBasicListExtractDevice(t *testing.T) {
want := []*Device{
testDevice(1),
testDevice(2),
}
serverWant := convertToServerDataDevice(want)
serverData, _ := json.Marshal(serverWant)
c, done := testClient(t, testHandler(t, http.MethodGet, "/api/dcim/devices/", &pageData{
Count: 2,
NextURL: "",
PreviousURL: "",
Results: serverData,
}))
defer done()
page := c.DCIM.Devices.List(nil)
if page == nil {
t.Fatalf("unexpexted result from c.DCIM.Devices.List.")
}
got := []*Device{}
counter := 0
for page.Next() {
var err error
got, err = c.DCIM.Devices.Extract(page)
if err != nil {
t.Fatalf("unexpected error from c.DCIM.Devices.Extract: %v", err)
}
counter = counter + 1
if counter > 2 { // Safe guard
break
}
}
if counter != 1 {
t.Fatalf("unexpected page count:\n- want: 1\n- got: %d", counter)
}
if !reflect.DeepEqual(want, got) {
t.Fatalf("unexpected result:\n- want: %v\n- got: %v", want, got)
}
if page.Err() != nil {
t.Fatalf("unexpected error from page:\n- want: %v\n- got: %v", want, got)
}
}
func TestBasicCreateDevice(t *testing.T) {
var tests = []struct {
desc string
data *Device
want int
serverData interface{}
status int
errstr string
}{
{
desc: "Create with ID 0",
data: testDeviceCreate(1),
want: 1,
status: 0,
errstr: "",
serverData: testDevice(1),
},
{
desc: "Create duplicate",
data: testDeviceCreate(1),
want: 0,
status: http.StatusBadRequest,
errstr: "400 - {\"name\":[\"DevicesService with this name already exists.\"]}\n",
serverData: &struct {
Name []string `json:"name"`
}{
Name: []string{"DevicesService with this name already exists."},
},
},
}
for i, tt := range tests {
t.Run(fmt.Sprintf("[%d] %s", i, tt.desc), func(t *testing.T) {
c, done := testClient(t, testStatusHandler(t, http.MethodPost, "/api/dcim/devices/", tt.serverData, tt.status))
defer done()
var terr error
if tt.errstr != "" {
terr = errors.New(tt.errstr) // Using errstr and initialize real err here, to satisfy golint
}
res, err := c.DCIM.Devices.Create(tt.data)
if want, got := terr, err; !reflect.DeepEqual(want, got) {
t.Fatalf("unexpected error:\n- want: %v\n- got: %v", want, got)
}
if want, got := tt.want, res; !reflect.DeepEqual(want, got) {
t.Fatalf("unexpected Device:\n- want: %v\n- got: %v", want, got)
}
})
}
}
func TestBasicUpdateDevice(t *testing.T) {
var tests = []struct {
desc string
data *Device
want int
serverData interface{}
status int
errstr string
}{
{
desc: "Update with ID 1",
data: testDevice(1),
want: 1,
serverData: testDevice(1),
status: 0,
errstr: "",
},
{
desc: "Update not found",
data: testDevice(1),
want: 0,
serverData: &struct {
Detail string
}{
Detail: "Not found.",
},
status: http.StatusNotFound,
errstr: "404 - Not found.",
},
{
desc: "Update to duplicate",
data: testDevice(1),
want: 0,
serverData: &struct {
Name []string `json:"name"`
}{
Name: []string{"DevicesService with this name already exists."},
},
status: http.StatusBadRequest,
errstr: "400 - {\"name\":[\"DevicesService with this name already exists.\"]}\n",
},
}
for i, tt := range tests {
t.Run(fmt.Sprintf("[%d] %s", i, tt.desc), func(t *testing.T) {
c, done := testClient(t, testStatusHandler(t, http.MethodPatch, "/api/dcim/devices/1/", tt.serverData, tt.status))
defer done()
var terr error
if tt.errstr != "" {
terr = errors.New(tt.errstr) // Using errstr and initialize real err here, to satisfy golint
}
res, err := c.DCIM.Devices.Update(tt.data)
if want, got := terr, err; !reflect.DeepEqual(want, got) {
t.Fatalf("unexpected error:\n- want: %v\n- got: %v", want, got)
}
if want, got := tt.want, res; !reflect.DeepEqual(want, got) {
t.Fatalf("unexpected Device:\n- want: %v\n- got: %v", want, got)
}
})
}
}
func TestBasicDeleteDevice(t *testing.T) {
var tests = []struct {
desc string
data *Device
serverData interface{}
status int
errstr string
}{
{
desc: "Delete ID 1",
data: testDevice(1),
serverData: testDevice(1),
status: 0,
errstr: "",
},
{
desc: "Delete not Found",
data: testDevice(1),
serverData: &struct {
Detail string `json:"detail"`
}{
Detail: "Not found.",
},
status: http.StatusNotFound,
errstr: "404 - Not found.",
},
}
for i, tt := range tests {
t.Run(fmt.Sprintf("[%d] %s", i, tt.desc), func(t *testing.T) {
c, done := testClient(t, testStatusHandler(t, http.MethodDelete, "/api/dcim/devices/1/", tt.serverData, tt.status))
defer done()
var terr error
if tt.errstr != "" {
terr = errors.New(tt.errstr) // Using errstr and initialize real err here, to satisfy golint
}
err := c.DCIM.Devices.Delete(tt.data)
if want, got := terr, err; !reflect.DeepEqual(want, got) {
t.Fatalf("unexpected error:\n- want: %v\n- got: %v", want, got)
}
})
}
}
// Copyright 2017 The go-netbox Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package netbox
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
_ "net/url"
"reflect"
"testing"
)
func TestDeviceGet(t *testing.T) {
var tests = []struct {
desc string
want *Device
}{
{
desc: "Device with Platform",
want: testDevice(1),
},
}
for idx, tt := range tests {
t.Run(fmt.Sprintf("[%d] %s", idx, tt.desc), func(t *testing.T) {
serverData := serverDataDevice(*tt.want)
c, done := testClient(t, testHandler(t, http.MethodGet, "/api/dcim/devices/1/", &serverData))
defer done()
res, err := c.DCIM.Devices.Get(1)
if err != nil {
t.Fatalf("unexpected error from c.DCIM.Devices.Get: %v", err)
}
if want, got := tt.want, res; !reflect.DeepEqual(want, got) {
t.Fatalf("unexpected Device\n- want: %v\n- got: %v", want, got)
}
})
}
}
func TestDeviceUnmarshalJSON(t *testing.T) {
var tests = []struct {
desc string
data []byte
want *Device
}{
{
desc: "Minimum device",
data: []byte(`{"id": 1, "name": "Device 1", "display_name": "Device 1", "device_type": { "id": 11, "url": "http://localhost/api/dcim/device-types/11/", "manufacturer": { "id": 21, "url": "http://localhost/api/dcim/manufacturers/21/", "name": "Manufacturer Name", "slug": "mfg-name"}, "model": "Device Type Model", "slug": "device-type-model"}, "device_role": { "id": 31, "url": "http://localhost/api/dcim/device-roles/31/", "name": "Device Role Name", "slug": "device-role-name"}, "site": { "id": 61, "url": "http://localhost/api/dcim/sites/61/", "name": "Site Name", "slug": "site-name" }, "status": { "value": 1, "label": "Active" } }`),
want: &Device{
ID: 1,
Name: "Device 1",
DisplayName: "Device 1",
DeviceType: &NestedDeviceType{ID: 11,
URL: "http://localhost/api/dcim/device-types/11/",
Manufacturer: &NestedManufacturer{
ID: 21, URL: "http://localhost/api/dcim/manufacturers/21/",
Name: "Manufacturer Name",
Slug: "mfg-name",
},
Model: "Device Type Model",
Slug: "device-type-model",
},
DeviceRole: &NestedDeviceRole{
ID: 31,
URL: "http://localhost/api/dcim/device-roles/31/",
Name: "Device Role Name",
Slug: "device-role-name",
},
Site: &NestedSite{
ID: 61,
URL: "http://localhost/api/dcim/sites/61/",
Name: "Site Name",
Slug: "site-name",
},
Status: &StatusType{
Value: 1,
Label: "Active",
},
},
},
{
desc: "Maximum device",
data: []byte(`{"id": 1, "name": "Device 1", "display_name": "Device 1", "device_type": { "id": 11, "url": "http://localhost/api/dcim/device-types/11/", "manufacturer": { "id": 21, "url": "http://localhost/api/dcim/manufacturers/21/", "name": "Manufacturer Name", "slug": "mfg-name"}, "model": "Device Type Model", "slug": "device-type-model"}, "device_role": { "id": 31, "url": "http://localhost/api/dcim/device-roles/31/", "name": "Device Role Name", "slug": "device-role-name"}, "tenant": { "id": 41, "url": "http://localhost/api/tenancy/tenants/41/", "name": "Tenant Name", "slug": "tenant-name" }, "platform": { "id": 51, "url": "http://localhost/api/dcim/platforms/51", "name": "Platform Name", "slug": "platform-name" }, "serial": "Serial", "asset_tag": "Tag", "site": { "id": 61, "url": "http://localhost/api/dcim/sites/61/", "name": "Site Name", "slug": "site-name" }, "rack": { "id": 71, "url": "http://localhost/api/dcim/racks/71/", "name": "Rack Name", "display_name": "Rack Name" }, "position": 81, "face": { "value": 0, "label": "Front" }, "status": { "value": 1, "label": "Active" } }`),
want: &Device{
ID: 1,
Name: "Device 1",
DisplayName: "Device 1",
DeviceType: &NestedDeviceType{
ID: 11,
URL: "http://localhost/api/dcim/device-types/11/",
Manufacturer: &NestedManufacturer{
ID: 21,
URL: "http://localhost/api/dcim/manufacturers/21/",
Name: "Manufacturer Name",
Slug: "mfg-name",
},
Model: "Device Type Model",
Slug: "device-type-model",
},
DeviceRole: &NestedDeviceRole{
ID: 31,
URL: "http://localhost/api/dcim/device-roles/31/",
Name: "Device Role Name",
Slug: "device-role-name",
},
Tenant: &NestedTenant{
ID: 41,
URL: "http://localhost/api/tenancy/tenants/41/",
Name: "Tenant Name",
Slug: "tenant-name",
},
Platform: &NestedPlatform{
ID: 51,
URL: "http://localhost/api/dcim/platforms/51",
Name: "Platform Name",
Slug: "platform-name",
},
Serial: "Serial",
AssetTag: "Tag",
Site: &NestedSite{
ID: 61,
URL: "http://localhost/api/dcim/sites/61/",
Name: "Site Name",
Slug: "site-name",
},
Rack: &NestedRack{
ID: 71,
URL: "http://localhost/api/dcim/racks/71/",
Name: "Rack Name",
DisplayName: "Rack Name",
},
Position: 81,
Face: &FaceType{
Value: 0,
Label: "Front",
},
Status: &StatusType{
Value: 1,
Label: "Active",
},
},
},
}
for idx, tt := range tests {
t.Run(fmt.Sprintf("[%d] %s", idx, tt.desc), func(t *testing.T) {
result := new(Device)
err := json.Unmarshal(tt.data, result)
if err != nil {
t.Fatalf("unexpected error from Device.UnmarshalJSON: %v", err)
}
if want, got := tt.want, result; !reflect.DeepEqual(want, got) {
t.Fatalf("unexpected Device:\n- want: %v\n- got: %v", want, got)
}
})
}
}
func TestDeviceMarshalJSON(t *testing.T) {
var tests = []struct {
desc string
data *Device
want []byte
}{
{
desc: "Sample Device",
data: testDevice(1),
want: []byte(`{"id":1,"name":"Device 1","display_name":"Device 1","device_type":2001,"device_role":1001,"tenant":3001,"platform":4001,"site":5001,"rack":6001}`),
},
}
for idx, tt := range tests {
t.Run(fmt.Sprintf("[%d] %s", idx, tt.desc), func(t *testing.T) {
result, err := json.Marshal(tt.data)
if err != nil {
t.Fatalf("unexpected error from writableDevice.MarshalJSON: %v", err)
}
if want, got := tt.want, result; bytes.Compare(want, got) != 0 {
t.Fatalf("unexpected JSON:\n- want: %v\n- got: %v", string(want), string(got))
}
})
}
}
func testNestedDeviceRole(id int) *NestedDeviceRole {
return &NestedDeviceRole{
ID: id,
URL: fmt.Sprintf("http://localhost/api/dcim/device-roles/%d/", id),
Name: fmt.Sprintf("Device Role %d", id),
Slug: fmt.Sprintf("device-role-%d", id),
}
}
func testNestedPlatform(id int) *NestedPlatform {
return &NestedPlatform{
ID: id,
URL: fmt.Sprintf("http://localhost/api/dcim/platforms/%d/", id),
Name: fmt.Sprintf("Platform %d", id),
Slug: fmt.Sprintf("platform-%d", id),
}
}
func testNestedTenant(id int) *NestedTenant {
return &NestedTenant{
ID: id,
URL: fmt.Sprintf("http://localhost/api/tenancy/tenants/%d/", id),
Name: fmt.Sprintf("Tenant %d", id),
Slug: fmt.Sprintf("tenant-%d", id),
}
}
func testNestedSite(id int) *NestedSite {
return &NestedSite{
ID: id,
URL: fmt.Sprintf("http://localhost/api/dcim/sites/%d/", id),
Name: fmt.Sprintf("Site %d", id),
Slug: fmt.Sprintf("site-%d", id),
}
}
func testNestedRack(id int) *NestedRack {
return &NestedRack{
ID: id,
URL: fmt.Sprintf("http://localhost/api/dcim/racks/%d/", id),
Name: fmt.Sprintf("Rack %d", id),
DisplayName: fmt.Sprintf("Rack %d", id),
}
}
func testNestedDeviceType(id int) *NestedDeviceType {
manufacturerID := id + 1000
return &NestedDeviceType{
ID: id,
URL: fmt.Sprintf("http://localhost/api/dcim/device-types/%d/", id),
Manufacturer: testNestedManufacturer(manufacturerID),
Model: fmt.Sprintf("Device Type Model of %d", id),
Slug: fmt.Sprintf("test-device-type-model-%d", id),
}
}
func testDevice(id int) *Device {
roleID := id + 1000
typeID := id + 2000
tenantID := id + 3000
platformID := id + 4000
siteID := id + 5000
rackID := id + 6000
return testDeviceHelper(id, false, testNestedDeviceType(typeID), testNestedDeviceRole(roleID), testNestedTenant(tenantID), testNestedPlatform(platformID), testNestedSite(siteID), testNestedRack(rackID))
}
func testDeviceCreate(id int) *Device {
roleID := id + 1000
typeID := id + 2000
tenantID := id + 3000
platformID := id + 4000
siteID := id + 5000
rackID := id + 6000
return testDeviceHelper(id, true, testNestedDeviceType(typeID), testNestedDeviceRole(roleID), testNestedTenant(tenantID), testNestedPlatform(platformID), testNestedSite(siteID), testNestedRack(rackID))
}
func testDeviceHelper(id int, create bool, devicetype *NestedDeviceType, role *NestedDeviceRole, tenant *NestedTenant, platform *NestedPlatform, site *NestedSite, rack *NestedRack) *Device {
deviceID := id
if create {
deviceID = 0
}
return &Device{
ID: deviceID,
Name: fmt.Sprintf("Device %d", id),
DisplayName: fmt.Sprintf("Device %d", id),
DeviceType: devicetype,
DeviceRole: role,
Tenant: tenant,
Platform: platform,
Site: site,
Rack: rack,
}
}
// Copyright 2017 The go-netbox Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package netbox
import (
"encoding/json"
"net/url"
"strconv"
)
type nestedBase struct {
ID int `json:"id"`
URL string `json:"url"`
Name string `json:"name"`
Slug string `json:"slug"`
}
type simpleValueLabel struct {
Value int `json:"value"`
Label string `json:"label"`
}
// ShortDeviceBay represent the short form of a Device Bay
// when a Device Bay appears in a parent device of
// another object.
type ShortDeviceBay struct {
ID int `json:"id"`
Name string `json:"name"`
}
// ShortDevice corresponds to the simple form of
// a Device, when a Device appears as a
// parent device of another object
type ShortDevice struct {
DeviceBay *ShortDeviceBay `json:"device_bay"`
ID int `json:"id"`
Name string `json:"name"`
}
// FaceType represent the face of a Device in a Rack (Front/Rear)
type FaceType simpleValueLabel
// StatusType represent status of a Device in Netbox API.
type StatusType simpleValueLabel
// A NestedDeviceRole corresponds to the Netbox API's
// nested serializer, when a DeviceRole appears as a
// parent of another object
type NestedDeviceRole nestedBase
// A NestedPlatform corresponds to the Netbox API's
// nested serializer, when a Platform appears as a
// parent of another object
type NestedPlatform nestedBase
// A NestedTenant corresponds to the Netbox API's
// nested serializer, when a Tenant appears as a
// parent of another object
type NestedTenant nestedBase
// A NestedSite corresponds to the Netbox API's
// nested serializer, when a Site appears as a
// parent of another object
type NestedSite nestedBase
// A NestedDeviceType corresponds to the Netbox API's
// nested serializer, when a DeviceType appears as a
// parent of another object
type NestedDeviceType struct {
ID int `json:"id"`
URL string `json:"url"`
Manufacturer *NestedManufacturer `json:"manufacturer"`
Model string `json:"model"`
Slug string `json:"slug"`
}
// A NestedRack correspondes to the Netbox API's
// nested serializer, when a Rack appears as a
// parent of another object
type NestedRack struct {
ID int `json:"id"`
URL string `json:"url"`
Name string `json:"name"`
DisplayName string `json:"display_name"`
}
// A NestedIP will be used as nested serializer for
// IPv4, IPv6 ip address
type NestedIP struct {
ID int `json:"id"`
URL string `json:"url"`
Family int `json:"family"`
Address string `json:"address"`
}
// A Device corresponds to the Netbox API's
// base serializer for Device
type Device struct {
ID int `json:"id,omitempty"`
Name string `json:"name"`
DisplayName string `json:"display_name"`
DeviceType *NestedDeviceType `json:"device_type"`
DeviceRole *NestedDeviceRole `json:"device_role"`
Tenant *NestedTenant `json:"tenant,omitempty"`
Platform *NestedPlatform `json:"platform,omitempty"`
Serial string `json:"serial,omitempty"`
AssetTag string `json:"asset_tag,omitempty"`
Site *NestedSite `json:"site"`
Rack *NestedRack `json:"rack,omitempty"`
Position int `json:"position,omitempty"`
Face *FaceType `json:"face,omitempty"`
Parent *ShortDevice `json:"parent_device,omitempty"`
Status *StatusType `json:"status"`
PrimaryIP *NestedIP `json:"primary_ip,omitempty"`
PrimaryIPv4 *NestedIP `json:"primary_ip4,omitempty"`
PrimaryIPv6 *NestedIP `json:"primary_ip6,omitempty"`
Comments string `json:"comments,omitempty"`
}
// A writableDevice corresponds to the Netbox API's
// writable serializer for a Device. It is used transparently
// when Devices are serialize into JSON.
type writableDevice struct {
ID int `json:"id,omitempty"`
Name string `json:"name"`
DisplayName string `json:"display_name"`
DeviceType int `json:"device_type"`
DeviceRole int `json:"device_role"`
Tenant int `json:"tenant,omitempty"`
Platform int `json:"platform,omitempty"`
Serial string `json:"serial,omitempty"`
AssetTag string `json:"asset_tag,omitempty"`
Site int `json:"site"`
Rack int `json:"rack,omitempty"`
Position int `json:"position,omitempty"`
Face string `json:"face,omitempty"`
Parent int `json:"parent_device,omitempty"`
Status string `json:"status,omitempty"`
PrimaryIP int `json:"primary_ip,omitempty"`
PrimaryIPv4 int `json:"primary_ip4,omitempty"`
PrimaryIPv6 int `json:"primary_ip6,omitempty"`
Comments string `json:"comments,omitempty"`
}
// MarshalJSON marshals a Device into JSON bytes,
// and is used by the standard json package.
func (d *Device) MarshalJSON() ([]byte, error) {
var typeID, roleID, tenantID, platformID, siteID, rackID, parentID, primaryIPID, primaryIPv4ID, primaryIPv6ID int
var status, face string
if d.DeviceType != nil {
typeID = d.DeviceType.ID
}
if d.DeviceRole != nil {
roleID = d.DeviceRole.ID
}
if d.Tenant != nil {
tenantID = d.Tenant.ID
}
if d.Platform != nil {
platformID = d.Platform.ID
}
if d.Site != nil {
siteID = d.Site.ID
}
if d.Rack != nil {
rackID = d.Rack.ID
}
if d.PrimaryIP != nil {
primaryIPID = d.PrimaryIP.ID
}
if d.PrimaryIPv4 != nil {
primaryIPv4ID = d.PrimaryIPv4.ID
}
if d.PrimaryIPv6 != nil {
primaryIPv6ID = d.PrimaryIPv6.ID
}
if d.Face != nil {
face = d.Face.Label
}
if d.Parent != nil {
parentID = d.Parent.ID
}
if d.Status != nil {
status = d.Status.Label
}
return json.Marshal(writableDevice{
ID: d.ID,
Name: d.Name,
DisplayName: d.DisplayName,
DeviceType: typeID,
DeviceRole: roleID,
Tenant: tenantID,
Platform: platformID,
Serial: d.Serial,
AssetTag: d.AssetTag,
Site: siteID,
Rack: rackID,
Position: d.Position,
Face: face,
Parent: parentID,
Status: status,
PrimaryIP: primaryIPID,
PrimaryIPv4: primaryIPv4ID,
PrimaryIPv6: primaryIPv6ID,
Comments: d.Comments,
})
}
// ListDeviceOptions is used as an argument for Client.DCIM.Devices.List.
// Integer fileds with an *ID suffix are preferred over their string
// counterparts, and if both are set, only the *ID filed will be used.
type ListDeviceOptions struct {
Name string
Serial string
AssetTag string
MacAddress string
IDIn int
SiteID int
Site string
RackGroupID int
RackID int
RoleID int
Role string
TenantID int
Tenant string
DeviceTypeID int
ManufacturerID int
Manufacturer string
DeviceModel string
PlatformID int
Platform string
Status string
IsConsoleServer *bool
IsPDU *bool
IsNetworkDevice *bool
HasPrimaryIP *bool
Query string
}
// Values generates a url.Values map from the data in ListDeviceOptions.
func (o *ListDeviceOptions) Values() (url.Values, error) {
if o == nil {
return nil, nil
}
v := url.Values{}
status := map[string]int{
"Offline": 0,
"Active": 1,
"Planned": 2,
"Staged": 3,
"Failed": 4,
"Inventory": 5,
}
switch {
case o.SiteID != 0:
v.Set("site_id", strconv.Itoa(o.SiteID))
case o.Site != "":
v.Set("site", o.Site)
}
switch {
case o.TenantID != 0:
v.Set("tenant_id", strconv.Itoa(o.TenantID))
case o.Tenant != "":
v.Set("tenant", o.Tenant)
}
switch {
case o.ManufacturerID != 0:
v.Set("manufacturer_id", strconv.Itoa(o.ManufacturerID))
case o.Manufacturer != "":
v.Set("manufacturer", o.Manufacturer)
}
switch {
case o.PlatformID != 0:
v.Set("platform_id", strconv.Itoa(o.PlatformID))
case o.Platform != "":
v.Set("platform", o.Platform)
}
switch {
case o.RoleID != 0:
v.Set("role_id", strconv.Itoa(o.RoleID))
case o.Role != "":
v.Set("role", o.Role)
}
if o.Name != "" {
v.Set("name", o.Name)
}
if o.Serial != "" {
v.Set("serial", o.Serial)
}
if o.AssetTag != "" {
v.Set("asset_tag", o.AssetTag)
}
if o.MacAddress != "" {
v.Set("mac_address", o.MacAddress)
}
if o.IDIn != 0 {
v.Set("id__in", strconv.Itoa(o.IDIn))
}
if o.RackGroupID != 0 {
v.Set("rack_group_id", strconv.Itoa(o.RackGroupID))
}
if o.RackID != 0 {
v.Set("rack_id", strconv.Itoa(o.RackID))
}
if o.DeviceTypeID != 0 {
v.Set("device_type_id", strconv.Itoa(o.DeviceTypeID))
}
if o.DeviceModel != "" {
v.Set("model", o.DeviceModel)
}
if o.Status != "" {
v.Set("status", strconv.Itoa(status[o.Status]))
}
if o.IsConsoleServer != nil {
v.Set("is_console_server", strconv.FormatBool(*o.IsConsoleServer))
}
if o.IsPDU != nil {
v.Set("is_pdu", strconv.FormatBool(*o.IsPDU))
}
if o.IsNetworkDevice != nil {
v.Set("is_network_device", strconv.FormatBool(*o.IsNetworkDevice))
}
if o.HasPrimaryIP != nil {
v.Set("has_primary_ip", strconv.FormatBool(*o.HasPrimaryIP))
}
if o.Query != "" {
v.Set("q", o.Query)
}
return v, nil
}
//go:generate go run generate_functions.go -endpoint dcim -service devices -service-name DevicesService -type-name Device -update-type-name writableDevice
//go:generate go run generate_basic_tests.go -client-endpoint DCIM -client-service Devices -endpoint dcim -service devices -service-name DevicesService -type-name Device
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment