Refactoring and tests
Break out tenant to its own type Rearrange structs to better align with memory
This commit is contained in:
parent
af589e9fc0
commit
92eacc150c
7 changed files with 1566 additions and 117 deletions
|
@ -23,8 +23,8 @@ func TestListDevices(t *testing.T) {
|
||||||
|
|
||||||
apiToken = os.Getenv("NETBOX_TOKEN")
|
apiToken = os.Getenv("NETBOX_TOKEN")
|
||||||
apiURL = os.Getenv("NETBOX_URL")
|
apiURL = os.Getenv("NETBOX_URL")
|
||||||
assert(t, true, apiToken)
|
notempty(t, apiToken)
|
||||||
assert(t, true, apiURL)
|
notempty(t, apiURL)
|
||||||
|
|
||||||
var nb *Client
|
var nb *Client
|
||||||
nb, err = NewClient(apiURL, nil)
|
nb, err = NewClient(apiURL, nil)
|
||||||
|
@ -40,6 +40,14 @@ func TestListDevices(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func notempty(tb testing.TB, msg string) {
|
||||||
|
if msg == "" {
|
||||||
|
_, file, line, _ := runtime.Caller(1)
|
||||||
|
fmt.Printf("\033[31m%s:%d: string empty\033[39m\n\n", filepath.Base(file), line)
|
||||||
|
tb.FailNow()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ok fails the test if an err is not nil.
|
// ok fails the test if an err is not nil.
|
||||||
func ok(tb testing.TB, err error) {
|
func ok(tb testing.TB, err error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
73
devices_test.go
Normal file
73
devices_test.go
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
package netboxgo_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"context"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
. "git.kcbark.net/kc/netboxgo"
|
||||||
|
)
|
||||||
|
|
||||||
|
type fakeClient struct {
|
||||||
|
q url.Values
|
||||||
|
h *http.Client
|
||||||
|
}
|
||||||
|
|
||||||
|
func newFakeClient() *fakeClient {
|
||||||
|
return &fakeClient{q: url.Values{}, h: &http.Client{}}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *fakeClient) prepare(path string, jsonfile string) {
|
||||||
|
u, err := url.Parse(path)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
b, err := ioutil.ReadFile(jsonfile)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("failed to read json file: %q: %+v", jsonfile, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
newFakeHTTPClient := NewTestClient(func(req *http.Request) *http.Response {
|
||||||
|
return &http.Response{
|
||||||
|
StatusCode: 200,
|
||||||
|
Body: io.NopCloser(bytes.NewBuffer(b)),
|
||||||
|
Header: make(http.Header),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
c.q = u.Query()
|
||||||
|
c.h = newFakeHTTPClient
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewTestClient(fn RoundTripFunc) *http.Client {
|
||||||
|
return &http.Client{
|
||||||
|
Transport: RoundTripFunc(fn),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type RoundTripFunc func(req *http.Request) *http.Response
|
||||||
|
|
||||||
|
func (f RoundTripFunc) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||||
|
return f(req), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDevicesList(t *testing.T) {
|
||||||
|
c := newFakeClient()
|
||||||
|
c.prepare("/dcim/devices", "./testdata/dcim_devices_list.json")
|
||||||
|
|
||||||
|
nb, err := NewClient("tokenloken", c.h)
|
||||||
|
ok(t, err)
|
||||||
|
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
devices, err := nb.Devices.List(ctx, nil)
|
||||||
|
ok(t, err)
|
||||||
|
|
||||||
|
equals(t, 10, len(devices.Results))
|
||||||
|
}
|
44
netbox_test.go
Normal file
44
netbox_test.go
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
package netboxgo_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"path/filepath"
|
||||||
|
"reflect"
|
||||||
|
"runtime"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
// func notempty(tb testing.TB, msg string) {
|
||||||
|
// if msg == "" {
|
||||||
|
// _, file, line, _ := runtime.Caller(1)
|
||||||
|
// fmt.Printf("\033[31m%s:%d: string empty\033[39m\n\n", filepath.Base(file), line)
|
||||||
|
// tb.FailNow()
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// ok fails the test if an err is not nil.
|
||||||
|
func ok(tb testing.TB, err error) {
|
||||||
|
if err != nil {
|
||||||
|
_, file, line, _ := runtime.Caller(1)
|
||||||
|
fmt.Printf("\033[31m%s:%d: unexpected error: %s\033[39m\n\n", filepath.Base(file), line, err.Error())
|
||||||
|
tb.FailNow()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// assert fails the test if the condition is false.
|
||||||
|
// func assert(tb testing.TB, condition bool, msg string, v ...interface{}) {
|
||||||
|
// if !condition {
|
||||||
|
// _, file, line, _ := runtime.Caller(1)
|
||||||
|
// fmt.Printf("\033[31m%s:%d: "+msg+"\033[39m\n\n", append([]interface{}{filepath.Base(file), line}, v...)...)
|
||||||
|
// tb.FailNow()
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// equals fails the test if exp is not equal to act.
|
||||||
|
func equals(tb testing.TB, exp, act interface{}) {
|
||||||
|
if !reflect.DeepEqual(exp, act) {
|
||||||
|
_, file, line, _ := runtime.Caller(1)
|
||||||
|
fmt.Printf("\033[31m%s:%d:\n\n\texp: %#v\n\n\tgot: %#v\033[39m\n\n", filepath.Base(file), line, exp, act)
|
||||||
|
tb.FailNow()
|
||||||
|
}
|
||||||
|
}
|
127
prefixes.go
127
prefixes.go
|
@ -16,89 +16,86 @@ type PrefixesService service
|
||||||
|
|
||||||
// NewPrefix is used for the return values from Netbox API ipam_prefixes_create
|
// NewPrefix is used for the return values from Netbox API ipam_prefixes_create
|
||||||
type NewPrefix struct {
|
type NewPrefix struct {
|
||||||
|
CustomFields interface{} `json:"custom_fields"`
|
||||||
Prefix string `json:"prefix"`
|
Prefix string `json:"prefix"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
Tags []string `json:"tags"`
|
||||||
Site int `json:"site"`
|
Site int `json:"site"`
|
||||||
|
Status int `json:"status"`
|
||||||
|
Role int `json:"role"`
|
||||||
Vrf int `json:"vrf"`
|
Vrf int `json:"vrf"`
|
||||||
Tenant int `json:"tenant"`
|
Tenant int `json:"tenant"`
|
||||||
VLAN int `json:"vlan"`
|
VLAN int `json:"vlan"`
|
||||||
Status int `json:"status"`
|
|
||||||
Role int `json:"role"`
|
|
||||||
IsPool bool `json:"is_pool"`
|
IsPool bool `json:"is_pool"`
|
||||||
Description string `json:"description"`
|
|
||||||
Tags []string `json:"tags"`
|
|
||||||
CustomFields interface{} `json:"custom_fields"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prefixes is used for the return value from NetBox API ipam_prefixes_list
|
// Prefixes is used for the return value from NetBox API ipam_prefixes_list
|
||||||
type Prefixes struct {
|
type Prefixes struct {
|
||||||
Count int `json:"count"`
|
|
||||||
Next string `json:"next"`
|
Next string `json:"next"`
|
||||||
Previous string `json:"previous"`
|
Previous string `json:"previous"`
|
||||||
Results []struct {
|
Results []struct {
|
||||||
ID int `json:"id"`
|
LastUpdated time.Time `json:"last_updated"`
|
||||||
Family struct {
|
CustomFields interface{} `json:"custom_fields"`
|
||||||
Label string `json:"label"`
|
VLAN struct {
|
||||||
Value int `json:"value"`
|
|
||||||
} `json:"family"`
|
|
||||||
Prefix string `json:"prefix"`
|
|
||||||
Site struct {
|
|
||||||
ID int `json:"id"`
|
|
||||||
URL string `json:"url"`
|
|
||||||
Name string `json:"name"`
|
|
||||||
Slug string `json:"slug"`
|
|
||||||
} `json:"site"`
|
|
||||||
Vrf struct {
|
|
||||||
ID int `json:"id"`
|
|
||||||
URL string `json:"url"`
|
URL string `json:"url"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Rd string `json:"rd"`
|
|
||||||
PrefixCount int `json:"prefix_count"`
|
|
||||||
} `json:"vrf"`
|
|
||||||
Tenant struct {
|
|
||||||
ID int `json:"id"`
|
|
||||||
URL string `json:"url"`
|
|
||||||
Name string `json:"name"`
|
|
||||||
Slug string `json:"slug"`
|
|
||||||
} `json:"tenant"`
|
|
||||||
VLAN struct {
|
|
||||||
ID int `json:"id"`
|
|
||||||
URL string `json:"url"`
|
|
||||||
Vid int `json:"vid"`
|
|
||||||
Name string `json:"name"`
|
|
||||||
DisplayName string `json:"display_name"`
|
DisplayName string `json:"display_name"`
|
||||||
|
ID int `json:"id"`
|
||||||
|
Vid int `json:"vid"`
|
||||||
} `json:"vlan"`
|
} `json:"vlan"`
|
||||||
|
Tenant struct {
|
||||||
|
URL string `json:"url"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Slug string `json:"slug"`
|
||||||
|
ID int `json:"id"`
|
||||||
|
} `json:"tenant"`
|
||||||
|
Site struct {
|
||||||
|
URL string `json:"url"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Slug string `json:"slug"`
|
||||||
|
ID int `json:"id"`
|
||||||
|
} `json:"site"`
|
||||||
Status struct {
|
Status struct {
|
||||||
Label string `json:"label"`
|
Label string `json:"label"`
|
||||||
Value string `json:"value"`
|
Value string `json:"value"`
|
||||||
} `json:"status"`
|
} `json:"status"`
|
||||||
Role struct {
|
Prefix string `json:"prefix"`
|
||||||
ID int `json:"id"`
|
Description string `json:"description"`
|
||||||
|
Created string `json:"created"`
|
||||||
|
Vrf struct {
|
||||||
URL string `json:"url"`
|
URL string `json:"url"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Slug string `json:"slug"`
|
Rd string `json:"rd"`
|
||||||
|
ID int `json:"id"`
|
||||||
PrefixCount int `json:"prefix_count"`
|
PrefixCount int `json:"prefix_count"`
|
||||||
VLANCount int `json:"vlan_count"`
|
} `json:"vrf"`
|
||||||
} `json:"role"`
|
Tags []struct {
|
||||||
IsPool bool `json:"is_pool"`
|
|
||||||
Description string `json:"description"`
|
|
||||||
Tags []struct {
|
|
||||||
ID int `json:"id"`
|
|
||||||
URL string `json:"url"`
|
URL string `json:"url"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Slug string `json:"slug"`
|
Slug string `json:"slug"`
|
||||||
Color string `json:"color"`
|
Color string `json:"color"`
|
||||||
|
ID int `json:"id"`
|
||||||
} `json:"tags"`
|
} `json:"tags"`
|
||||||
CustomFields interface{} `json:"custom_fields"`
|
Family struct {
|
||||||
Created string `json:"created"`
|
Label string `json:"label"`
|
||||||
LastUpdated time.Time `json:"last_updated"`
|
Value int `json:"value"`
|
||||||
|
} `json:"family"`
|
||||||
|
Role struct {
|
||||||
|
URL string `json:"url"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Slug string `json:"slug"`
|
||||||
|
ID int `json:"id"`
|
||||||
|
PrefixCount int `json:"prefix_count"`
|
||||||
|
VLANCount int `json:"vlan_count"`
|
||||||
|
} `json:"role"`
|
||||||
|
ID int `json:"id"`
|
||||||
|
IsPool bool `json:"is_pool"`
|
||||||
} `json:"results"`
|
} `json:"results"`
|
||||||
|
Count int `json:"count"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// PrefixFilter is used to filter out returned object from Netbox API ipam_prefixes_list
|
// PrefixFilter is used to filter out returned object from Netbox API ipam_prefixes_list
|
||||||
type PrefixFilter struct {
|
type PrefixFilter struct {
|
||||||
Offset int64 `schema:"offset,omitempty"`
|
|
||||||
Limit int64 `schema:"limit,omitempty"`
|
|
||||||
|
|
||||||
// User specific filters
|
// User specific filters
|
||||||
Family string `schema:"family,omitempty"`
|
Family string `schema:"family,omitempty"`
|
||||||
IsPool string `schema:"is_pool,omitempty"`
|
IsPool string `schema:"is_pool,omitempty"`
|
||||||
|
@ -124,6 +121,9 @@ type PrefixFilter struct {
|
||||||
VLANID string `schema:"vlan_id,omitempty"`
|
VLANID string `schema:"vlan_id,omitempty"`
|
||||||
Role string `schema:"role,omitempty"`
|
Role string `schema:"role,omitempty"`
|
||||||
Status string `schema:"status,omitempty"`
|
Status string `schema:"status,omitempty"`
|
||||||
|
|
||||||
|
Offset int `schema:"offset,omitempty"`
|
||||||
|
Limit int `schema:"limit,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
const prefixesPath = ipamPath + "/prefixes"
|
const prefixesPath = ipamPath + "/prefixes"
|
||||||
|
@ -157,6 +157,35 @@ func (s *PrefixesService) List(ctx context.Context, f *PrefixFilter) (*Prefixes,
|
||||||
return &prefixes, nil
|
return &prefixes, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ListAll prefixes. PrefixFilter is used to list all prefixes based on filters
|
||||||
|
func (s *PrefixesService) ListAll(ctx context.Context, f *PrefixFilter) (*Prefixes, error) {
|
||||||
|
var all Prefixes
|
||||||
|
var r *Prefixes
|
||||||
|
var num int
|
||||||
|
var err error
|
||||||
|
|
||||||
|
f.Limit = 1
|
||||||
|
r, err = s.List(ctx, f)
|
||||||
|
if err != nil {
|
||||||
|
return &all, fmt.Errorf("unable to count prefixes with filter %+v: %w", f, err)
|
||||||
|
}
|
||||||
|
num = r.Count
|
||||||
|
|
||||||
|
for count := 0; count < num; count += 1000 {
|
||||||
|
f.Limit = 1000
|
||||||
|
f.Offset = count
|
||||||
|
|
||||||
|
r, err = s.List(ctx, f)
|
||||||
|
if err != nil {
|
||||||
|
return &all, fmt.Errorf("unable to list prefixes with filter %+v: %w", f, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
all.Results = append(all.Results, r.Results...)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &all, nil
|
||||||
|
}
|
||||||
|
|
||||||
// Create a prefix
|
// Create a prefix
|
||||||
func (s *PrefixesService) Create(ctx context.Context, c *NewPrefix) error {
|
func (s *PrefixesService) Create(ctx context.Context, c *NewPrefix) error {
|
||||||
var err error
|
var err error
|
||||||
|
|
102
tenants.go
102
tenants.go
|
@ -14,53 +14,53 @@ type TenantsService service
|
||||||
|
|
||||||
// NewTenant is used for the return values from Netbox API tenancy_tenants_create
|
// NewTenant is used for the return values from Netbox API tenancy_tenants_create
|
||||||
type NewTenant struct {
|
type NewTenant struct {
|
||||||
Name string `json:"name"`
|
CustomFields interface{} `json:"custom_fields"`
|
||||||
Slug string `json:"slug"`
|
Slug string `json:"slug"`
|
||||||
Group int `json:"group"`
|
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
Comments string `json:"comments"`
|
Comments string `json:"comments"`
|
||||||
|
Name string `json:"name"`
|
||||||
Tags []string `json:"tags"`
|
Tags []string `json:"tags"`
|
||||||
CustomFields interface{} `json:"custom_fields"`
|
Group int `json:"group"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tenants is used for the return value from NetBox API tenancy_tenants_list
|
// Tenant represents a tenant
|
||||||
|
type Tenant struct {
|
||||||
|
LastUpdated time.Time `json:"last_updated"`
|
||||||
|
CustomFields interface{} `json:"custom_fields"`
|
||||||
|
VirtualmachineCount interface{} `json:"virtualmachine_count"`
|
||||||
|
RackCount interface{} `json:"rack_count"`
|
||||||
|
IpaddressCount interface{} `json:"ipaddress_count"`
|
||||||
|
CircuitCount interface{} `json:"circuit_count"`
|
||||||
|
VrfCount interface{} `json:"vrf_count"`
|
||||||
|
Group struct {
|
||||||
|
URL string `json:"url"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Slug string `json:"slug"`
|
||||||
|
ID int `json:"id"`
|
||||||
|
} `json:"group"`
|
||||||
|
Created string `json:"created"`
|
||||||
|
Comments string `json:"comments"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
Slug string `json:"slug"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Tags []interface{} `json:"tags"`
|
||||||
|
DeviceCount int `json:"device_count"`
|
||||||
|
PrefixCount int `json:"prefix_count"`
|
||||||
|
SiteCount int `json:"site_count"`
|
||||||
|
VlanCount int `json:"vlan_count"`
|
||||||
|
ID int `json:"id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tenants is represents a list of multiple tenants
|
||||||
type Tenants struct {
|
type Tenants struct {
|
||||||
Count int `json:"count"`
|
|
||||||
Next string `json:"next"`
|
|
||||||
Previous interface{} `json:"previous"`
|
Previous interface{} `json:"previous"`
|
||||||
Results []struct {
|
Next string `json:"next"`
|
||||||
ID int `json:"id"`
|
Results []Tenant `json:"results"`
|
||||||
Name string `json:"name"`
|
Count int `json:"count"`
|
||||||
Slug string `json:"slug"`
|
|
||||||
Group struct {
|
|
||||||
ID int `json:"id"`
|
|
||||||
URL string `json:"url"`
|
|
||||||
Name string `json:"name"`
|
|
||||||
Slug string `json:"slug"`
|
|
||||||
} `json:"group"`
|
|
||||||
Description string `json:"description"`
|
|
||||||
Comments string `json:"comments"`
|
|
||||||
Tags []interface{} `json:"tags"`
|
|
||||||
CustomFields interface{} `json:"custom_fields"`
|
|
||||||
Created string `json:"created"`
|
|
||||||
LastUpdated time.Time `json:"last_updated"`
|
|
||||||
CircuitCount interface{} `json:"circuit_count"`
|
|
||||||
DeviceCount int `json:"device_count"`
|
|
||||||
IpaddressCount interface{} `json:"ipaddress_count"`
|
|
||||||
PrefixCount int `json:"prefix_count"`
|
|
||||||
RackCount interface{} `json:"rack_count"`
|
|
||||||
SiteCount int `json:"site_count"`
|
|
||||||
VirtualmachineCount interface{} `json:"virtualmachine_count"`
|
|
||||||
VlanCount int `json:"vlan_count"`
|
|
||||||
VrfCount interface{} `json:"vrf_count"`
|
|
||||||
} `json:"results"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TenantFilter is used to filter out returned object from Netbox API tenancy_tenants_list
|
// TenantFilter is used to filter out returned object from Netbox API tenancy_tenants_list
|
||||||
type TenantFilter struct {
|
type TenantFilter struct {
|
||||||
Offset int64 `schema:"offset,omitempty"`
|
|
||||||
Limit int64 `schema:"limit,omitempty"`
|
|
||||||
|
|
||||||
// User specific filters
|
// User specific filters
|
||||||
Name string `schema:"name,omitempty"`
|
Name string `schema:"name,omitempty"`
|
||||||
Slug string `schema:"slug,omitempty"`
|
Slug string `schema:"slug,omitempty"`
|
||||||
|
@ -69,6 +69,9 @@ type TenantFilter struct {
|
||||||
IDIn string `schema:"id__in,omitempty"`
|
IDIn string `schema:"id__in,omitempty"`
|
||||||
Q string `schema:"q,omitempty"`
|
Q string `schema:"q,omitempty"`
|
||||||
Tag string `schema:"tag,omitempty"`
|
Tag string `schema:"tag,omitempty"`
|
||||||
|
|
||||||
|
Offset int `schema:"offset,omitempty"`
|
||||||
|
Limit int `schema:"limit,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
const tenantsPath = tenancyPath + "/tenants"
|
const tenantsPath = tenancyPath + "/tenants"
|
||||||
|
@ -102,6 +105,35 @@ func (s *TenantsService) List(ctx context.Context, f *TenantFilter) (*Tenants, e
|
||||||
return &tenants, nil
|
return &tenants, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ListAll tenants. TenantFilter is used to list all tenants based on filters
|
||||||
|
func (s *TenantsService) ListAll(ctx context.Context, f *TenantFilter) (*Tenants, error) {
|
||||||
|
var all Tenants
|
||||||
|
var r *Tenants
|
||||||
|
var num int
|
||||||
|
var err error
|
||||||
|
|
||||||
|
f.Limit = 1
|
||||||
|
r, err = s.List(ctx, f)
|
||||||
|
if err != nil {
|
||||||
|
return &all, fmt.Errorf("unable to count prefixes with filter %+v: %w", f, err)
|
||||||
|
}
|
||||||
|
num = r.Count
|
||||||
|
|
||||||
|
for count := 0; count < num; count += 1000 {
|
||||||
|
f.Limit = 1000
|
||||||
|
f.Offset = count
|
||||||
|
|
||||||
|
r, err = s.List(ctx, f)
|
||||||
|
if err != nil {
|
||||||
|
return &all, fmt.Errorf("unable to list prefixes with filter %+v: %w", f, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
all.Results = append(all.Results, r.Results...)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &all, nil
|
||||||
|
}
|
||||||
|
|
||||||
// Create a tenant
|
// Create a tenant
|
||||||
func (s *TenantsService) Create(ctx context.Context, c *NewTenant) error {
|
func (s *TenantsService) Create(ctx context.Context, c *NewTenant) error {
|
||||||
var err error
|
var err error
|
||||||
|
|
1234
testdata/dcim_devices_list.json
vendored
Normal file
1234
testdata/dcim_devices_list.json
vendored
Normal file
File diff suppressed because it is too large
Load diff
91
vlans.go
91
vlans.go
|
@ -14,75 +14,72 @@ type VLANsService service
|
||||||
|
|
||||||
// NewVLAN is used for the return values from Netbox API ipam_vlans_create
|
// NewVLAN is used for the return values from Netbox API ipam_vlans_create
|
||||||
type NewVLAN struct {
|
type NewVLAN struct {
|
||||||
Site int `json:"site"`
|
CustomFields interface{} `json:"custom_fields"`
|
||||||
Group int `json:"group"`
|
Description string `json:"description"`
|
||||||
Vid int `json:"vid"`
|
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
|
Tags []string `json:"tags"`
|
||||||
|
Site int `json:"site"`
|
||||||
Tenant int `json:"tenant"`
|
Tenant int `json:"tenant"`
|
||||||
Status int `json:"status"`
|
Status int `json:"status"`
|
||||||
Role int `json:"role"`
|
Role int `json:"role"`
|
||||||
Description string `json:"description"`
|
Group int `json:"group"`
|
||||||
Tags []string `json:"tags"`
|
Vid int `json:"vid"`
|
||||||
CustomFields interface{} `json:"custom_fields"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type VLAN struct {
|
type VLAN struct {
|
||||||
ID int `json:"id"`
|
LastUpdated time.Time `json:"last_updated"`
|
||||||
Site struct {
|
CustomFields interface{} `json:"custom_fields"`
|
||||||
ID int `json:"id"`
|
Site struct {
|
||||||
URL string `json:"url"`
|
URL string `json:"url"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Slug string `json:"slug"`
|
Slug string `json:"slug"`
|
||||||
|
ID int `json:"id"`
|
||||||
} `json:"site"`
|
} `json:"site"`
|
||||||
Group struct {
|
|
||||||
ID int `json:"id"`
|
|
||||||
URL string `json:"url"`
|
|
||||||
Name string `json:"name"`
|
|
||||||
Slug string `json:"slug"`
|
|
||||||
VLANCount int `json:"vlan_count"`
|
|
||||||
} `json:"group"`
|
|
||||||
Vid int `json:"vid"`
|
|
||||||
Name string `json:"name"`
|
|
||||||
Tenant struct {
|
Tenant struct {
|
||||||
ID int `json:"id"`
|
|
||||||
URL string `json:"url"`
|
URL string `json:"url"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Slug string `json:"slug"`
|
Slug string `json:"slug"`
|
||||||
|
ID int `json:"id"`
|
||||||
} `json:"tenant"`
|
} `json:"tenant"`
|
||||||
Status struct {
|
Status struct {
|
||||||
Label string `json:"label"`
|
Label string `json:"label"`
|
||||||
Value string `json:"value"`
|
Value string `json:"value"`
|
||||||
} `json:"status"`
|
} `json:"status"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Created string `json:"created"`
|
||||||
|
DisplayName string `json:"display_name"`
|
||||||
|
Group struct {
|
||||||
|
URL string `json:"url"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Slug string `json:"slug"`
|
||||||
|
ID int `json:"id"`
|
||||||
|
VLANCount int `json:"vlan_count"`
|
||||||
|
} `json:"group"`
|
||||||
|
Tags []string `json:"tags"`
|
||||||
Role struct {
|
Role struct {
|
||||||
ID int `json:"id"`
|
|
||||||
URL string `json:"url"`
|
URL string `json:"url"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Slug string `json:"slug"`
|
Slug string `json:"slug"`
|
||||||
|
ID int `json:"id"`
|
||||||
PrefixCount int `json:"prefix_count"`
|
PrefixCount int `json:"prefix_count"`
|
||||||
VLANCount int `json:"vlan_count"`
|
VLANCount int `json:"vlan_count"`
|
||||||
} `json:"role"`
|
} `json:"role"`
|
||||||
Description string `json:"description"`
|
ID int `json:"id"`
|
||||||
Tags []string `json:"tags"`
|
Vid int `json:"vid"`
|
||||||
DisplayName string `json:"display_name"`
|
PrefixCount int `json:"prefix_count"`
|
||||||
CustomFields interface{} `json:"custom_fields"`
|
|
||||||
Created string `json:"created"`
|
|
||||||
LastUpdated time.Time `json:"last_updated"`
|
|
||||||
PrefixCount int `json:"prefix_count"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// IpamVLANsList is used for the return value from NetBox API ipam_vlans_list
|
// IpamVLANsList is used for the return value from NetBox API ipam_vlans_list
|
||||||
type VLANs struct {
|
type VLANs struct {
|
||||||
Count int `json:"count"`
|
|
||||||
Next string `json:"next"`
|
Next string `json:"next"`
|
||||||
Previous string `json:"previous"`
|
Previous string `json:"previous"`
|
||||||
Results []VLAN `json:"results"`
|
Results []VLAN `json:"results"`
|
||||||
|
Count int `json:"count"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// VLANFilter is used to filter out returned object from Netbox API ipam_vlans_list
|
// VLANFilter is used to filter out returned object from Netbox API ipam_vlans_list
|
||||||
type VLANFilter struct {
|
type VLANFilter struct {
|
||||||
Offset int64 `schema:"offset,omitempty"`
|
|
||||||
Limit int64 `schema:"limit,omitempty"`
|
|
||||||
|
|
||||||
// User specific filters
|
// User specific filters
|
||||||
Vid string `schema:"vid,omitempty"`
|
Vid string `schema:"vid,omitempty"`
|
||||||
Name string `schema:"name,omitempty"`
|
Name string `schema:"name,omitempty"`
|
||||||
|
@ -100,6 +97,9 @@ type VLANFilter struct {
|
||||||
Role string `schema:"role,omitempty"`
|
Role string `schema:"role,omitempty"`
|
||||||
Status string `schema:"status,omitempty"`
|
Status string `schema:"status,omitempty"`
|
||||||
Tag string `schema:"tag,omitempty"`
|
Tag string `schema:"tag,omitempty"`
|
||||||
|
|
||||||
|
Offset int `schema:"offset,omitempty"`
|
||||||
|
Limit int `schema:"limit,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
const vlansPath = ipamPath + "/vlans"
|
const vlansPath = ipamPath + "/vlans"
|
||||||
|
@ -133,6 +133,35 @@ func (s *VLANsService) List(ctx context.Context, f *VLANFilter) (*VLANs, error)
|
||||||
return &vlans, nil
|
return &vlans, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ListAll vlans. VLANFilter is used to filter list all based on filters
|
||||||
|
func (s *VLANsService) ListAll(ctx context.Context, f *VLANFilter) (*VLANs, error) {
|
||||||
|
var all VLANs
|
||||||
|
var v *VLANs
|
||||||
|
var numVlans int
|
||||||
|
var err error
|
||||||
|
|
||||||
|
f.Limit = 1
|
||||||
|
v, err = s.List(ctx, f)
|
||||||
|
if err != nil {
|
||||||
|
return &all, fmt.Errorf("unable to count vlans with filter %+v: %w", f, err)
|
||||||
|
}
|
||||||
|
numVlans = v.Count
|
||||||
|
|
||||||
|
for count := 0; count < numVlans; count += 1000 {
|
||||||
|
f.Limit = 1000
|
||||||
|
f.Offset = count
|
||||||
|
|
||||||
|
v, err = s.List(ctx, f)
|
||||||
|
if err != nil {
|
||||||
|
return &all, fmt.Errorf("unable to list vlans with filter %+v: %w", f, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
all.Results = append(all.Results, v.Results...)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &all, nil
|
||||||
|
}
|
||||||
|
|
||||||
// Create a device
|
// Create a device
|
||||||
func (s *VLANsService) Create(ctx context.Context, c *NewDevice) error {
|
func (s *VLANsService) Create(ctx context.Context, c *NewDevice) error {
|
||||||
var err error
|
var err error
|
||||||
|
|
Loading…
Reference in a new issue