Merge pull request 'migrate-to-new-standard' (#1) from migrate-to-new-standard into master

Reviewed-on: #1
This commit is contained in:
Kalle Carlbark 2021-11-29 08:03:17 +00:00
commit 6a496accb3
26 changed files with 2004 additions and 1928 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
.pre-commit-config.yaml

View file

@ -98,8 +98,7 @@ type Circuits struct {
} `json:"termination_z"` } `json:"termination_z"`
Comments string `json:"comments"` Comments string `json:"comments"`
Tags []string `json:"tags"` Tags []string `json:"tags"`
CustomFields struct { CustomFields struct{} `json:"custom_fields"`
} `json:"custom_fields"`
Created string `json:"created"` Created string `json:"created"`
LastUpdated time.Time `json:"last_updated"` LastUpdated time.Time `json:"last_updated"`
} `json:"results"` } `json:"results"`

183
clusters.go Normal file
View file

@ -0,0 +1,183 @@
package netboxgo
import (
"context"
"fmt"
"net/http"
"net/url"
"time"
"github.com/gorilla/schema"
)
type ClustersService service
// NewCluster is used to create new VirtualizationClusters
type NewCluster struct {
ID int `json:"id"`
Name string `json:"name"`
Type struct {
ID int `json:"id"`
URL string `json:"url"`
Name string `json:"name"`
Slug string `json:"slug"`
ClusterCount int `json:"cluster_count"`
} `json:"type"`
Group struct {
ID int `json:"id"`
URL string `json:"url"`
Name string `json:"name"`
Slug string `json:"slug"`
ClusterCount int `json:"cluster_count"`
} `json:"group"`
Site struct {
ID int `json:"id"`
URL string `json:"url"`
Name string `json:"name"`
Slug string `json:"slug"`
} `json:"site"`
Comments string `json:"comments"`
Tags []struct {
ID int `json:"id"`
URL string `json:"url"`
Name string `json:"name"`
Slug string `json:"slug"`
Color string `json:"color"`
} `json:"tags"`
CustomFields struct{} `json:"custom_fields"`
Created string `json:"created"`
LastUpdated time.Time `json:"last_updated"`
DeviceCount int `json:"device_count"`
VirtualmachineCount int `json:"virtualmachine_count"`
}
// Clusters is used to list VirtualizationClusters
type Clusters struct {
Count int `json:"count"`
Next string `json:"next"`
Previous string `json:"previous"`
Results []struct {
ID int `json:"id"`
Name string `json:"name"`
Type struct {
ID int `json:"id"`
URL string `json:"url"`
Name string `json:"name"`
Slug string `json:"slug"`
ClusterCount int `json:"cluster_count"`
} `json:"type"`
Group struct {
ID int `json:"id"`
URL string `json:"url"`
Name string `json:"name"`
Slug string `json:"slug"`
ClusterCount int `json:"cluster_count"`
} `json:"group"`
Site struct {
ID int `json:"id"`
URL string `json:"url"`
Name string `json:"name"`
Slug string `json:"slug"`
} `json:"site"`
Comments string `json:"comments"`
Tags []struct {
ID int `json:"id"`
URL string `json:"url"`
Name string `json:"name"`
Slug string `json:"slug"`
Color string `json:"color"`
} `json:"tags"`
CustomFields struct{} `json:"custom_fields"`
Created string `json:"created"`
LastUpdated time.Time `json:"last_updated"`
DeviceCount int `json:"device_count"`
VirtualmachineCount int `json:"virtualmachine_count"`
} `json:"results"`
}
// ClusterFilter is used to filter out VirtualizationClusters
type ClusterFilter struct {
Offset int64 `schema:"offset,omitempty"`
Limit int64 `schema:"limit,omitempty"`
// User specific filters
Name string `schema:"name,omitempty"`
Group string `schema:"group,omitempty"`
GroupID string `schema:"group_id,omitempty"`
TypeID string `schema:"type_id,omitempty"`
Type string `schema:"type,omitempty"`
SiteID string `schema:"site_id,omitempty"`
Site string `schema:"site,omitempty"`
Tenant string `schema:"tenant,omitempty"`
IDIn string `schema:"id__in,omitempty"`
Q string `schema:"q,omitempty"`
Tag string `schema:"tag,omitempty"`
}
const clustersPath = virtualizationPath + "/clusters"
// List clusters. ClusterFilter is used to list based on filter queries.
func (s *ClustersService) List(ctx context.Context, f *ClusterFilter) (*Clusters, error) {
var clusters Clusters
var query string
var req *http.Request
var err error
encoder := schema.NewEncoder()
form := url.Values{}
err = encoder.Encode(f, form)
if err != nil {
return &clusters, err
}
query = form.Encode()
req, err = s.client.newRequest(ctx, "GET", clustersPath, query, nil)
if err != nil {
return &clusters, err
}
_, err = s.client.do(req, &clusters)
if err != nil {
return &clusters, err
}
return &clusters, nil
}
// Create a cluster
func (s *ClustersService) Create(ctx context.Context, c *NewCluster) error {
var err error
var req *http.Request
req, err = s.client.newRequest(ctx, "POST", clustersPath, "", c)
if err != nil {
return fmt.Errorf("unable to create request: %w", err)
}
_, err = s.client.do(req, nil)
if err != nil {
return fmt.Errorf("unable to do request: %w", err)
}
return nil
}
// // Update a cluster
// func (s *ClustersService) Update(ctx context.Context, id string, c *UpdateCluster) error {
// var req *http.Request
// var err error
// path := fmt.Sprintf("%s/%s", clustersPath, id)
// req, err = s.client.newRequest(ctx, "PATCH", path, "", c)
// if err != nil {
// return fmt.Errorf("unable to create request: %w", err)
// }
// _, err = s.client.do(req, nil)
// if err != nil {
// return fmt.Errorf("unable to do request: %w", err)
// }
// return nil

View file

@ -1,18 +1,16 @@
package netboxgo package netboxgo
import ( import (
"crypto/tls" "context"
"encoding/json"
"io/ioutil"
"net/http" "net/http"
"net/url" "net/url"
"time"
"github.com/gorilla/schema" "github.com/gorilla/schema"
"github.com/pkg/errors"
) )
type ListDeviceRoles struct { type DeviceRolesService service
type DeviceRoles struct {
Count int `json:"count"` Count int `json:"count"`
Next string `json:"next"` Next string `json:"next"`
Previous string `json:"previous"` Previous string `json:"previous"`
@ -45,58 +43,69 @@ type DeviceRoleFilter struct {
Q string `schema:"q,omitempty"` Q string `schema:"q,omitempty"`
} }
// ListDeviceTypes method returns dcim_device_roles from Netbox API const deviceRolesPath = dcimPath + "/device-roles"
func (n *NetBox) ListDeviceRoles(d *ListDeviceRoles, f *DeviceRoleFilter) error {
// List deviceroles. DeviceRoleFilter is used to list based on filter queries.
func (s *DeviceRolesService) List(ctx context.Context, f *DeviceRoleFilter) (*DeviceRoles, error) {
var deviceroles DeviceRoles
var query string
var req *http.Request
var err error
encoder := schema.NewEncoder() encoder := schema.NewEncoder()
transport := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: n.InsecureSkipVerify},
}
timeout := time.Duration(60 * time.Second)
client := &http.Client{
Timeout: timeout,
Transport: transport,
}
deviceurl := n.RootURL + "/api/dcim/device-roles/"
if f != nil {
form := url.Values{} form := url.Values{}
err := encoder.Encode(f, form) err = encoder.Encode(f, form)
if err != nil { if err != nil {
return err return &deviceroles, err
} }
query := form.Encode() query = form.Encode()
deviceurl = deviceurl + "?" + query
} req, err = s.client.newRequest(ctx, "GET", deviceRolesPath, query, nil)
var request *http.Request
var err error
request, err = http.NewRequest("GET", deviceurl, nil)
if err != nil { if err != nil {
return err return &deviceroles, err
}
request.Header.Add("Accept", "application/json")
request.Header.Add("Authorization", " Token "+n.Token)
response, err := client.Do(request)
if err != nil {
return err
} }
if response.StatusCode != http.StatusOK { _, err = s.client.do(req, &deviceroles)
return errors.Errorf("Error: response was: %d should be %d (%s)\n", response.StatusCode, http.StatusOK, deviceurl) if err != nil {
return &deviceroles, err
} }
data, err := ioutil.ReadAll(response.Body) return &deviceroles, nil
if err != nil {
return err
}
err = response.Body.Close()
if err != nil {
return err
}
err = json.Unmarshal(data, &d)
if err != nil {
return err
}
return nil
} }
// var err error
// var req *http.Request
// req, err = s.client.newRequest(ctx, "POST", deviceRolesPath, "", c)
// if err != nil {
// return fmt.Errorf("unable to create request: %w", err)
// }
// _, err = s.client.do(req, nil)
// if err != nil {
// return fmt.Errorf("unable to do request: %w", err)
// }
// return nil
// }
// // Update a device-role
// func (s *DeviceRolesService) Update(ctx context.Context, id string, c *UpdateDevice) error {
// var req *http.Request
// var err error
// path := fmt.Sprintf("%s/%s", deviceRolesPath, id)
// req, err = s.client.newRequest(ctx, "PATCH", path, "", c)
// if err != nil {
// return fmt.Errorf("unable to create request: %w", err)
// }
// _, err = s.client.do(req, nil)
// if err != nil {
// return fmt.Errorf("unable to do request: %w", err)
// }
// return nil
// }

View file

@ -1,18 +1,17 @@
package netboxgo package netboxgo
import ( import (
"crypto/tls" "context"
"encoding/json"
"io/ioutil"
"net/http" "net/http"
"net/url" "net/url"
"time" "time"
"github.com/gorilla/schema" "github.com/gorilla/schema"
"github.com/pkg/errors"
) )
type ListDeviceTypes struct { type DeviceTypesService service
type DeviceTypes struct {
Count int `json:"count"` Count int `json:"count"`
Next string `json:"next"` Next string `json:"next"`
Previous string `json:"previous"` Previous string `json:"previous"`
@ -49,8 +48,7 @@ type DeviceType struct {
Slug string `json:"slug"` Slug string `json:"slug"`
Color string `json:"color"` Color string `json:"color"`
} `json:"tags"` } `json:"tags"`
CustomFields struct { CustomFields struct{} `json:"custom_fields"`
} `json:"custom_fields"`
Created string `json:"created"` Created string `json:"created"`
LastUpdated time.Time `json:"last_updated"` LastUpdated time.Time `json:"last_updated"`
DeviceCount int `json:"device_count"` DeviceCount int `json:"device_count"`
@ -72,58 +70,126 @@ type DeviceTypeFilter struct {
Tag string `schema:"tag,omitempty"` Tag string `schema:"tag,omitempty"`
} }
// ListDeviceTypes method returns dcim_device_types_list from Netbox API const deviceTypesPath = dcimPath + "/device-types"
func (n *NetBox) ListDeviceTypes(d *ListDeviceTypes, f *DeviceTypeFilter) error {
// List device-types. DeviceTypeFilter is used to list based on filter queries.
func (s *DeviceTypesService) List(ctx context.Context, f *DeviceTypeFilter) (*DeviceTypes, error) {
var devicetypes DeviceTypes
var query string
var req *http.Request
var err error
encoder := schema.NewEncoder() encoder := schema.NewEncoder()
transport := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: n.InsecureSkipVerify},
}
timeout := time.Duration(60 * time.Second)
client := &http.Client{
Timeout: timeout,
Transport: transport,
}
deviceurl := n.RootURL + "/api/dcim/device-types/"
if f != nil {
form := url.Values{} form := url.Values{}
err := encoder.Encode(f, form) err = encoder.Encode(f, form)
if err != nil { if err != nil {
return err return &devicetypes, err
} }
query := form.Encode() query = form.Encode()
deviceurl = deviceurl + "?" + query
} req, err = s.client.newRequest(ctx, "GET", deviceTypesPath, query, nil)
var request *http.Request
var err error
request, err = http.NewRequest("GET", deviceurl, nil)
if err != nil { if err != nil {
return err return &devicetypes, err
}
request.Header.Add("Accept", "application/json")
request.Header.Add("Authorization", " Token "+n.Token)
response, err := client.Do(request)
if err != nil {
return err
} }
if response.StatusCode != http.StatusOK { _, err = s.client.do(req, &devicetypes)
return errors.Errorf("Error: response was: %d should be %d (%s)\n", response.StatusCode, http.StatusOK, deviceurl) if err != nil {
return &devicetypes, err
} }
data, err := ioutil.ReadAll(response.Body) return &devicetypes, nil
if err != nil {
return err
}
err = response.Body.Close()
if err != nil {
return err
}
err = json.Unmarshal(data, &d)
if err != nil {
return err
}
return nil
} }
// // Create a device
// func (s *DeviceTypesService) Create(ctx context.Context, c *NewDeviceType) error {
// var err error
// var req *http.Request
// req, err = s.client.newRequest(ctx, "POST", deviceTypesPath, "", c)
// if err != nil {
// return fmt.Errorf("unable to create request: %w", err)
// }
// _, err = s.client.do(req, nil)
// if err != nil {
// return fmt.Errorf("unable to do request: %w", err)
// }
// return nil
// }
// // Update a device
// func (s *DeviceTypesService) Update(ctx context.Context, id string, c *UpdateDevice) error {
// var req *http.Request
// var err error
// path := fmt.Sprintf("%s/%s", deviceTypesPath, id)
// req, err = s.client.newRequest(ctx, "PATCH", path, "", c)
// if err != nil {
// return fmt.Errorf("unable to create request: %w", err)
// }
// _, err = s.client.do(req, nil)
// if err != nil {
// return fmt.Errorf("unable to do request: %w", err)
// }
// return nil
// }
// // ListDeviceTypes method returns dcim_device_types_list from Netbox API
// func (n *NetBox) ListDeviceTypes(d *DeviceTypes, f *DeviceTypeFilter) error {
// encoder := schema.NewEncoder()
// transport := &http.Transport{
// TLSClientConfig: &tls.Config{InsecureSkipVerify: n.InsecureSkipVerify},
// }
// timeout := time.Duration(60 * time.Second)
// client := &http.Client{
// Timeout: timeout,
// Transport: transport,
// }
// deviceurl := n.RootURL + "/api/dcim/device-types/"
// if f != nil {
// form := url.Values{}
// err := encoder.Encode(f, form)
// if err != nil {
// return err
// }
// query := form.Encode()
// deviceurl = deviceurl + "?" + query
// }
// var request *http.Request
// var err error
// request, err = http.NewRequest("GET", deviceurl, nil)
// if err != nil {
// return err
// }
// request.Header.Add("Accept", "application/json")
// request.Header.Add("Authorization", " Token "+n.Token)
// response, err := client.Do(request)
// if err != nil {
// return err
// }
// if response.StatusCode != http.StatusOK {
// return errors.Errorf("Error: response was: %d should be %d (%s)\n", response.StatusCode, http.StatusOK, deviceurl)
// }
// data, err := ioutil.ReadAll(response.Body)
// if err != nil {
// return err
// }
// err = response.Body.Close()
// if err != nil {
// return err
// }
// err = json.Unmarshal(data, &d)
// if err != nil {
// return err
// }
// return nil
// }

View file

@ -1,21 +1,19 @@
package netboxgo package netboxgo
import ( import (
"bytes" "context"
"crypto/tls" "fmt"
"encoding/json"
"io/ioutil"
"net/http" "net/http"
"net/url" "net/url"
"strconv"
"time" "time"
"github.com/gorilla/schema" "github.com/gorilla/schema"
"github.com/pkg/errors"
) )
// DcimDevicesList is used for Netbox dcim_device_list return struct type DevicesService service
type DcimDevicesList struct {
// Devices is used for Netbox dcim_device_list return struct
type Devices struct {
Count int `json:"count"` Count int `json:"count"`
Next string `json:"next"` Next string `json:"next"`
Previous string `json:"previous"` Previous string `json:"previous"`
@ -172,12 +170,12 @@ type Device struct {
LastUpdated time.Time `json:"last_updated"` LastUpdated time.Time `json:"last_updated"`
} }
type DcimCreateDevice struct { type NewDevice struct {
Name string `json:"name,omitempty,omitempty"` Name string `json:"name,omitempty"`
DeviceType int `json:"device_type,omitempty,omitempty"` DeviceType int `json:"device_type,omitempty"`
DeviceRole int `json:"device_role,omitempty,omitempty"` DeviceRole int `json:"device_role,omitempty"`
Tenant int `json:"tenant,omitempty,omitempty"` Tenant int `json:"tenant,omitempty"`
Platform int `json:"platform,omitempty,omitempty"` Platform int `json:"platform,omitempty"`
Serial string `json:"serial,omitempty"` Serial string `json:"serial,omitempty"`
AssetTag string `json:"asset_tag,omitempty"` AssetTag string `json:"asset_tag,omitempty"`
Site int `json:"site,omitempty"` Site int `json:"site,omitempty"`
@ -230,7 +228,7 @@ type DcimCreateDevice struct {
} `json:"custom_fields,omitempty"` } `json:"custom_fields,omitempty"`
} }
type DcimUpdateDevice struct { type UpdateDevice struct {
Name string `json:"name,omitempty"` Name string `json:"name,omitempty"`
DeviceType int `json:"device_type,omitempty"` DeviceType int `json:"device_type,omitempty"`
DeviceRole int `json:"device_role,omitempty"` DeviceRole int `json:"device_role,omitempty"`
@ -259,7 +257,7 @@ type DcimUpdateDevice struct {
DcimDeviceBelongsToService int `json:"dcim_device_belongs_to_service,omitempty"` DcimDeviceBelongsToService int `json:"dcim_device_belongs_to_service,omitempty"`
DcimDeviceCendotid string `json:"dcim_device_cendotid,omitempty"` DcimDeviceCendotid string `json:"dcim_device_cendotid,omitempty"`
DcimDeviceExposedToInternet int `json:"dcim_device_exposed_to_internet,omitempty"` DcimDeviceExposedToInternet int `json:"dcim_device_exposed_to_internet,omitempty"`
DcimDeviceImportOsVersion bool `json:"dcim_device_import_os_version,omitempty,omitempty"` DcimDeviceImportOsVersion bool `json:"dcim_device_import_os_version,omitempty"`
DcimDevicePod int `json:"dcim_device_pod,omitempty"` DcimDevicePod int `json:"dcim_device_pod,omitempty"`
} `json:"custom_fields,omitempty"` } `json:"custom_fields,omitempty"`
} }
@ -312,121 +310,70 @@ type DeviceFilter struct {
Tag string `schema:"tag,omitempty"` Tag string `schema:"tag,omitempty"`
} }
// ListDevices method returns dcim_device_list from Netbox API const devicesPath = dcimPath + "/devices"
func (n *NetBox) ListDevices(d *DcimDevicesList, f *DeviceFilter) error {
// List devices. DeviceFilter is used to list based on filter queries.
func (s *DevicesService) List(ctx context.Context, f *DeviceFilter) (*Devices, error) {
var devices Devices
var query string
var req *http.Request
var err error
encoder := schema.NewEncoder() encoder := schema.NewEncoder()
transport := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: n.InsecureSkipVerify},
}
timeout := time.Duration(60 * time.Second)
client := &http.Client{
Timeout: timeout,
Transport: transport,
}
deviceurl := n.RootURL + "/api/dcim/devices/"
if f != nil {
form := url.Values{} form := url.Values{}
err := encoder.Encode(f, form) err = encoder.Encode(f, form)
if err != nil { if err != nil {
return err return &devices, err
} }
query := form.Encode() query = form.Encode()
deviceurl = deviceurl + "?" + query
req, err = s.client.newRequest(ctx, "GET", devicesPath, query, nil)
if err != nil {
return &devices, err
} }
var request *http.Request
_, err = s.client.do(req, &devices)
if err != nil {
return &devices, err
}
return &devices, nil
}
// Create a device
func (s *DevicesService) Create(ctx context.Context, c *NewDevice) error {
var err error var err error
request, err = http.NewRequest("GET", deviceurl, nil) var req *http.Request
req, err = s.client.newRequest(ctx, "POST", devicesPath, "", c)
if err != nil { if err != nil {
return err return fmt.Errorf("unable to create request: %w", err)
}
request.Header.Add("Accept", "application/json")
request.Header.Add("Authorization", " Token "+n.Token)
response, err := client.Do(request)
if err != nil {
return err
} }
if response.StatusCode != http.StatusOK { _, err = s.client.do(req, nil)
return errors.Errorf("Error: response was: %d should be %d (%s)\n", response.StatusCode, http.StatusOK, deviceurl)
}
data, err := ioutil.ReadAll(response.Body)
if err != nil { if err != nil {
return err return fmt.Errorf("unable to do request: %w", err)
} }
err = response.Body.Close() return nil
if err != nil { }
return err
} // Update a device
func (s *DevicesService) Update(ctx context.Context, id string, c *UpdateDevice) error {
err = json.Unmarshal(data, &d) var req *http.Request
if err != nil { var err error
return err
} path := fmt.Sprintf("%s/%s", devicesPath, id)
return nil
} req, err = s.client.newRequest(ctx, "PATCH", path, "", c)
if err != nil {
func (n *NetBox) CreateDevice(v *DcimCreateDevice) error { return fmt.Errorf("unable to create request: %w", err)
data, err := json.Marshal(v) }
if err != nil {
return err _, err = s.client.do(req, nil)
} if err != nil {
transport := &http.Transport{ return fmt.Errorf("unable to do request: %w", err)
TLSClientConfig: &tls.Config{InsecureSkipVerify: n.InsecureSkipVerify},
}
timeout := time.Duration(60 * time.Second)
client := &http.Client{
Timeout: timeout,
Transport: transport,
}
request, err := http.NewRequest("POST", n.RootURL+"/api/dcim/devices/", bytes.NewBuffer(data))
if err != nil {
return err
}
request.Header.Add("Accept", "application/json")
request.Header.Add("Content-Type", "application/json")
request.Header.Add("Authorization", " Token "+n.Token)
response, err := client.Do(request)
if err != nil {
return err
}
err = response.Body.Close()
if err != nil {
return err
}
if response.StatusCode == http.StatusCreated {
return nil
}
return errors.Errorf("Error: response was: %d should be %d\n", response.StatusCode, http.StatusCreated)
}
func (n *NetBox) UpdateDevice(v *DcimUpdateDevice, id int) error {
data, err := json.Marshal(v)
if err != nil {
return err
}
transport := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: n.InsecureSkipVerify},
}
timeout := time.Duration(60 * time.Second)
client := &http.Client{
Timeout: timeout,
Transport: transport,
}
request, err := http.NewRequest("PATCH", n.RootURL+"/api/dcim/devices/"+strconv.Itoa(id)+"/", bytes.NewBuffer(data))
if err != nil {
return err
}
request.Header.Add("Accept", "application/json")
request.Header.Add("Content-Type", "application/json")
request.Header.Add("Authorization", " Token "+n.Token)
_, err = client.Do(request)
if err != nil {
return err
} }
return nil return nil

4
go.mod
View file

@ -1,6 +1,6 @@
module git.kcbark.net/kcbark/netboxgo module git.kcbark.net/kc/netboxgo
go 1.15 go 1.17
require ( require (
github.com/gorilla/schema v1.1.0 github.com/gorilla/schema v1.1.0

View file

@ -1,22 +1,20 @@
package netboxgo package netboxgo
import ( import (
"bytes" "context"
"crypto/tls" "fmt"
"encoding/json"
// "fmt"
"io/ioutil"
"net/http" "net/http"
"net/url" "net/url"
"time"
// "fmt"
"github.com/gorilla/schema" "github.com/gorilla/schema"
"github.com/pkg/errors"
) )
// DcimInterfacesCreate is used for the return values from Netbox API dcim_interfaces_create type InterfacesService service
type DcimInterfacesCreate struct {
// NewInterface is used for the return values from Netbox API dcim_interfaces_create
type NewInterface struct {
Device int `json:"device"` Device int `json:"device"`
Name string `json:"name"` Name string `json:"name"`
Type int `json:"type,omitempty"` Type int `json:"type,omitempty"`
@ -36,8 +34,8 @@ type DcimInterfacesCreate struct {
Tags []string `json:"tags,omitempty"` Tags []string `json:"tags,omitempty"`
} }
// DcimInterfacesList is used for the return value from NetBox API dcim_interfaces_list // Interfaces is used for the return value from NetBox API dcim_interfaces_list
type DcimInterfacesList struct { type Interfaces struct {
Count int `json:"count,omitempty"` Count int `json:"count,omitempty"`
Next interface{} `json:"next,omitempty"` Next interface{} `json:"next,omitempty"`
Previous interface{} `json:"previous,omitempty"` Previous interface{} `json:"previous,omitempty"`
@ -93,7 +91,7 @@ type InterfaceFilter struct {
Offset int64 `schema:"offset,omitempty"` Offset int64 `schema:"offset,omitempty"`
Limit int64 `schema:"limit,omitempty"` Limit int64 `schema:"limit,omitempty"`
//User specific filters // User specific filters
ID string `schema:"id,omitempty"` ID string `schema:"id,omitempty"`
Name string `schema:"name,omitempty"` Name string `schema:"name,omitempty"`
ConnectionStatus string `schema:"connection_status,omitempty"` ConnectionStatus string `schema:"connection_status,omitempty"`
@ -114,89 +112,51 @@ type InterfaceFilter struct {
VLAN string `schema:"vlan,omitempty"` VLAN string `schema:"vlan,omitempty"`
} }
// ListInterfaces returns Netbox dcim_interfaces_list const interfacesPath = dcimPath + "/interfaces"
func (n *NetBox) ListInterfaces(i *DcimInterfacesList, f *InterfaceFilter) error {
var encoder = schema.NewEncoder() // List devices. DeviceFilter is used to list based on filter queries.
func (s *InterfacesService) List(ctx context.Context, f *InterfaceFilter) (*Interfaces, error) {
var interfaces Interfaces
var query string
var req *http.Request
var err error
encoder := schema.NewEncoder()
form := url.Values{} form := url.Values{}
err := encoder.Encode(f, form) err = encoder.Encode(f, form)
if err != nil { if err != nil {
return err return &interfaces, err
} }
query := form.Encode() query = form.Encode()
transport := &http.Transport{ req, err = s.client.newRequest(ctx, "GET", interfacesPath, query, nil)
TLSClientConfig: &tls.Config{InsecureSkipVerify: n.InsecureSkipVerify},
}
timeout := time.Duration(60 * time.Second)
client := &http.Client{
Timeout: timeout,
Transport: transport,
}
request, err := http.NewRequest("GET", n.RootURL+"/api/dcim/interfaces/?"+query, nil)
if err != nil { if err != nil {
return err return &interfaces, err
}
request.Header.Add("Accept", "application/json")
request.Header.Add("Authorization", " Token "+n.Token)
response, err := client.Do(request)
if err != nil {
return err
} }
if response.StatusCode != http.StatusOK { _, err = s.client.do(req, &interfaces)
return errors.Errorf("Error: response was: %d should be %d\n", response.StatusCode, http.StatusOK) if err != nil {
return &interfaces, err
} }
data, err := ioutil.ReadAll(response.Body) return &interfaces, nil
if err != nil {
return err
}
err = response.Body.Close()
if err != nil {
return err
}
err = json.Unmarshal(data, &i)
if err != nil {
return err
}
return nil
} }
// CreateInterfaces creates interfaces via Netbox API dcim_interfaces_create // Create a interfaces
func (n *NetBox) CreateInterfaces(i *DcimInterfacesCreate) error { func (s *InterfacesService) Create(ctx context.Context, c *NewInterface) error {
interfaceData, err := json.Marshal(i) var err error
var req *http.Request
req, err = s.client.newRequest(ctx, "POST", interfacesPath, "", c)
if err != nil { if err != nil {
return err return fmt.Errorf("unable to create request: %w", err)
}
transport := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: n.InsecureSkipVerify},
}
timeout := time.Duration(60 * time.Second)
client := &http.Client{
Timeout: timeout,
Transport: transport,
}
request, err := http.NewRequest("POST", n.RootURL+"/api/dcim/interfaces/", bytes.NewBuffer(interfaceData))
if err != nil {
return err
}
request.Header.Add("Accept", "application/json")
request.Header.Add("Content-Type", "application/json")
request.Header.Add("Authorization", " Token "+n.Token)
response, err := client.Do(request)
if err != nil {
return err
}
err = response.Body.Close()
if err != nil {
return err
} }
if response.StatusCode == http.StatusCreated { _, err = s.client.do(req, nil)
return nil if err != nil {
return fmt.Errorf("unable to do request: %w", err)
} }
return errors.Errorf("Error: response was: %d should be %d\n", response.StatusCode, http.StatusCreated)
return nil
} }

108
inventory.go Normal file
View file

@ -0,0 +1,108 @@
package netboxgo
import (
"context"
"fmt"
"net/http"
"net/url"
"github.com/gorilla/schema"
)
type InventoryItemsService service
type NewInventoryItem struct {
Device int `json:"device"`
Parent int `json:"parent"`
Name string `json:"name"`
Manufacturer int `json:"manufacturer"`
PartID string `json:"part_id"`
Serial string `json:"serial"`
AssetTag string `json:"asset_tag"`
Discovered bool `json:"discovered"`
Description string `json:"description"`
Tags []string `json:"tags"`
}
type InventoryItems struct {
Count int `json:"count"`
Next string `json:"next"`
Previous string `json:"previous"`
Results []struct {
ID int `json:"id"`
Device struct {
ID int `json:"id"`
URL string `json:"url"`
Name string `json:"name"`
DisplayName string `json:"display_name"`
} `json:"device"`
Parent int `json:"parent"`
Name string `json:"name"`
Manufacturer struct {
ID int `json:"id"`
URL string `json:"url"`
Name string `json:"name"`
Slug string `json:"slug"`
DevicetypeCount int `json:"devicetype_count"`
} `json:"manufacturer"`
PartID string `json:"part_id"`
Serial string `json:"serial"`
AssetTag string `json:"asset_tag"`
Discovered bool `json:"discovered"`
Description string `json:"description"`
Tags []string `json:"tags"`
} `json:"results"`
}
type InventoryItemFilter struct {
Device string `schema:"device"`
}
const inventoryItemsPath = dcimPath + "/inventory-items"
// List inventory-items. InventoryItemFilter is used to list based on filter queries.
func (s *InventoryItemsService) List(ctx context.Context, f *InventoryItemFilter) (*InventoryItems, error) {
var inventoryitems InventoryItems
var query string
var req *http.Request
var err error
encoder := schema.NewEncoder()
form := url.Values{}
err = encoder.Encode(f, form)
if err != nil {
return &inventoryitems, err
}
query = form.Encode()
req, err = s.client.newRequest(ctx, "GET", inventoryItemsPath, query, nil)
if err != nil {
return &inventoryitems, err
}
_, err = s.client.do(req, &inventoryitems)
if err != nil {
return &inventoryitems, err
}
return &inventoryitems, nil
}
// Create a inventory-item
func (s *InventoryItemsService) Create(ctx context.Context, c *NewInventoryItem) error {
var err error
var req *http.Request
req, err = s.client.newRequest(ctx, "POST", inventoryItemsPath, "", c)
if err != nil {
return fmt.Errorf("unable to create request: %w", err)
}
_, err = s.client.do(req, nil)
if err != nil {
return fmt.Errorf("unable to do request: %w", err)
}
return nil
}

326
netbox.go
View file

@ -1,9 +1,13 @@
package netboxgo package netboxgo
import ( import (
"bytes"
"context"
"crypto/tls" "crypto/tls"
"encoding/json" "encoding/json"
"io/ioutil" "fmt"
"io"
"log"
"net/http" "net/http"
"net/url" "net/url"
"strings" "strings"
@ -12,78 +16,312 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
) )
// NetBox settings struct type DCIM struct {
type NetBox struct { Devices *DevicesService
RootURL string DeviceRoles *DeviceRolesService
DeviceTypes *DeviceTypesService
Interfaces *InterfacesService
InventoryItems *InventoryItemsService
RearPorts *RearPortsService
}
type Virtualization struct {
Clusters *ClustersService
VirtualMachines *VirtualMachinesService
}
type IPAM struct {
VLANs *VLANsService
VRFs *VRFsService
Prefixes *PrefixesService
}
type Secret struct {
Secrets *SecretsService
}
type Tenancy struct {
Tenants *TenantsService
Sites *SitesService
SiteGroups *SiteGroupsService
}
// Client struct is used to create a new NetBox endpoint
type Client struct {
// DCIM *DCIM
// Tenancy *Tenancy
// IPAM *IPAM
// Virtualization *Virtualization
// Secret *Secret
Tenants *TenantsService
Sites *SitesService
SiteGroups *SiteGroupsService
VirtualMachines *VirtualMachinesService
Clusters *ClustersService
VLANs *VLANsService
Secrets *SecretsService
InventoryItems *InventoryItemsService
Devices *DevicesService
DeviceRoles *DeviceRolesService
DeviceTypes *DeviceTypesService
Interfaces *InterfacesService
Prefixes *PrefixesService
VRFs *VRFsService
RearPorts *RearPortsService
// baseURL is the URL used for the base URL of the API
baseURL *url.URL
// httpClient is used for HTTP requests
httpClient *http.Client
// Reuse a single struct instead of allocating one for each service on the heap.
common service
// UserAgent is used to set the UserAgent on the HTTP requests
UserAgent string
// Token is set for authentication of the API
Token string Token string
// TokenPrefix is optional to set token prefix other than "Token"
TokenPrefix string
// SessionKey is used to read authentication data
SessionKey string SessionKey string
// Used by golang wasm
FetchMode string FetchMode string
// Debug enables verbose debugging messages to console.
Debug bool
// InsecureSkipVerify is used to selectively skip InsecureVerifications
InsecureSkipVerify bool InsecureSkipVerify bool
} }
type service struct {
client *Client
}
const (
circuitsPath = "/circuits"
dcimPath = "/dcim"
extrasPath = "/extras"
ipamPath = "/ipam"
tenancyPath = "/tenancy"
usersPath = "/users"
virtualizationPath = "/virtualization"
)
// NetBoxSessionKey sets the session key for secrets retrieval // NetBoxSessionKey sets the session key for secrets retrieval
type NetBoxSessionKey struct { type NetBoxSessionKey struct {
XSessionKey string `json:"session_key"` XSessionKey string `json:"session_key"`
} }
// New populates the NetBox settings struct // NewClient returns a new NetBox API client
func (n *NetBox) New(root, token string, TLSSkipVerify bool) { func NewClient(apiurl string, httpClient *http.Client) (*Client, error) {
n.RootURL = root c := &Client{}
n.Token = token
n.InsecureSkipVerify = TLSSkipVerify api, err := url.Parse(apiurl)
if err != nil {
return c, fmt.Errorf("unable to parse url %s: %w", apiurl, err)
}
c.baseURL = api
c.SetDebug(false)
c.SetUserAgent("netboxgo/0.0.6")
c.httpClient = httpClient
if httpClient == nil {
transport := &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: false,
CipherSuites: []uint16{
tls.TLS_AES_128_GCM_SHA256,
tls.TLS_AES_256_GCM_SHA384,
tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
tls.TLS_CHACHA20_POLY1305_SHA256,
},
MinVersion: tls.VersionTLS12,
},
Proxy: http.ProxyFromEnvironment,
}
timeout := time.Duration(60 * time.Second)
c.httpClient = &http.Client{
Transport: transport,
Jar: nil,
Timeout: timeout,
}
}
c.common.client = c
c.Clusters = (*ClustersService)(&c.common)
c.Devices = (*DevicesService)(&c.common)
c.DeviceRoles = (*DeviceRolesService)(&c.common)
c.DeviceTypes = (*DeviceTypesService)(&c.common)
c.Interfaces = (*InterfacesService)(&c.common)
c.InventoryItems = (*InventoryItemsService)(&c.common)
c.Prefixes = (*PrefixesService)(&c.common)
c.RearPorts = (*RearPortsService)(&c.common)
c.Tenants = (*TenantsService)(&c.common)
c.Secrets = (*SecretsService)(&c.common)
c.Sites = (*SitesService)(&c.common)
c.SiteGroups = (*SiteGroupsService)(&c.common)
c.VirtualMachines = (*VirtualMachinesService)(&c.common)
c.VLANs = (*VLANsService)(&c.common)
c.VRFs = (*VRFsService)(&c.common)
return c, nil
}
// SetUserAgent is used to set the user agent for interaction with the API
func (c *Client) SetUserAgent(u string) {
c.UserAgent = u
}
// SetDebug is used to toggle debugging, set to true for debug
func (c *Client) SetDebug(b bool) {
c.Debug = b
}
// SetToken is used to set the http token bearer for interaction with the API
func (c *Client) SetToken(token string) {
c.Token = token
} }
// FetchSessionKey fetches sessionkey // FetchSessionKey fetches sessionkey
func (n *NetBox) FetchSessionKey(privatekey string) error { func (c *Client) FetchSessionKey(privatekey string) error {
form := url.Values{} form := url.Values{}
form.Add("private_key", privatekey) form.Add("private_key", privatekey)
query := form.Encode() query := form.Encode()
transport := &http.Transport{ ctx := context.Background()
TLSClientConfig: &tls.Config{InsecureSkipVerify: n.InsecureSkipVerify}, req, err := http.NewRequestWithContext(ctx, "POST", c.baseURL.String()+secretsPath+"/get-session-key/", strings.NewReader(query))
}
timeout := time.Duration(60 * time.Second)
client := &http.Client{
Timeout: timeout,
Transport: transport,
}
request, err := http.NewRequest("POST", n.RootURL+"/api/secrets/get-session-key/", strings.NewReader(query))
if err != nil {
return err
}
request.Header.Add("Accept", "application/json")
request.Header.Add("Content-Type", "application/x-www-form-urlencoded")
if n.FetchMode != "" {
request.Header.Add("js.fetch:mode", "no-cors")
}
request.Header.Add("Authorization", " Token "+n.Token)
response, err := client.Do(request)
if err != nil { if err != nil {
return err return err
} }
if response.StatusCode != http.StatusOK { req.Header.Add("Accept", "application/json")
return errors.Errorf("Error: response was: %d should be %d\n%s\n", response.StatusCode, http.StatusOK, response.Header) req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
if c.FetchMode != "" {
req.Header.Add("js.fetch:mode", "no-cors")
} }
data, err := ioutil.ReadAll(response.Body) req.Header.Add("Authorization", " Token "+c.Token)
if err != nil {
return err
}
err = response.Body.Close()
if err != nil {
return err
}
var sessionkey NetBoxSessionKey var sessionkey NetBoxSessionKey
err = json.Unmarshal(data, &sessionkey)
res, err := c.do(req, &sessionkey)
if err != nil { if err != nil {
return err return err
} }
n.SessionKey = sessionkey.XSessionKey
if res.StatusCode != http.StatusOK {
return errors.Errorf("response was: %d should be %d\n%s\n", res.StatusCode, http.StatusOK, res.Header)
}
c.SessionKey = sessionkey.XSessionKey
return nil return nil
} }
// newRequest is used to make new request to endpoints
func (c *Client) newRequest(ctx context.Context, method, path string, query string, body interface{}) (*http.Request, error) {
var err error
var buf io.ReadWriter
u := &url.URL{
Scheme: c.baseURL.Scheme,
Host: c.baseURL.Host,
Path: c.baseURL.Path + path,
RawQuery: query,
}
if body != nil {
buf = new(bytes.Buffer)
err = json.NewEncoder(buf).Encode(body)
if err != nil {
return nil, err
}
}
readBuf, _ := json.Marshal(body)
c.debugf("debug: method:%s url:%s body:%s", method, u.String(), string(readBuf))
req, err := http.NewRequestWithContext(ctx, method, u.String(), buf)
if err != nil {
return nil, err
}
if body != nil {
req.Header.Set("Content-Type", "application/json")
}
if c.SessionKey != "" {
req.Header.Add("X-Session-Key", c.SessionKey)
}
req.Header.Set("Accept", "application/json")
if c.UserAgent != "" {
req.Header.Set("User-Agent", c.UserAgent)
}
if c.Token != "" {
req.Header.Add("Authorization", "Token "+c.Token)
}
if c.Token != "" && c.TokenPrefix != "" {
req.Header.Add("Authorization", c.TokenPrefix+" "+c.Token)
}
if c.SessionKey != "" {
req.Header.Add("X-Session-Key", c.SessionKey)
}
return req, nil
}
// do method is used to decode request response to proper struct
func (c *Client) do(req *http.Request, v interface{}) (*http.Response, error) {
var err error
var resp *http.Response
resp, err = c.httpClient.Do(req)
if err != nil {
return nil, fmt.Errorf("client unable to do request: %w", err)
}
if resp.StatusCode < 200 || resp.StatusCode > 299 {
var data []byte
data, err = io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("unable to read body response: %w", err)
}
return nil, fmt.Errorf("request failed: body=%s", string(data))
}
if v != nil {
err = json.NewDecoder(resp.Body).Decode(v)
if err != nil {
return resp, fmt.Errorf("unable to decode response body: %w", err)
}
}
return resp, nil
}
// debugf is used as a formtter for debugging information
func (c *Client) debugf(fmt string, v ...interface{}) {
if c.Debug {
log.Printf("cendot client: "+fmt, v...)
}
}

View file

@ -1,152 +0,0 @@
package netboxgo
import (
"bytes"
"crypto/tls"
"encoding/json"
"io/ioutil"
"net/http"
"net/url"
"time"
"github.com/gorilla/schema"
"github.com/pkg/errors"
)
type AddInventory struct {
Device int `json:"device"`
Parent int `json:"parent"`
Name string `json:"name"`
Manufacturer int `json:"manufacturer"`
PartID string `json:"part_id"`
Serial string `json:"serial"`
AssetTag string `json:"asset_tag"`
Discovered bool `json:"discovered"`
Description string `json:"description"`
Tags []string `json:"tags"`
}
type DcimInventoryItemsList struct {
Count int `json:"count"`
Next string `json:"next"`
Previous string `json:"previous"`
Results []struct {
ID int `json:"id"`
Device struct {
ID int `json:"id"`
URL string `json:"url"`
Name string `json:"name"`
DisplayName string `json:"display_name"`
} `json:"device"`
Parent int `json:"parent"`
Name string `json:"name"`
Manufacturer struct {
ID int `json:"id"`
URL string `json:"url"`
Name string `json:"name"`
Slug string `json:"slug"`
DevicetypeCount int `json:"devicetype_count"`
} `json:"manufacturer"`
PartID string `json:"part_id"`
Serial string `json:"serial"`
AssetTag string `json:"asset_tag"`
Discovered bool `json:"discovered"`
Description string `json:"description"`
Tags []string `json:"tags"`
} `json:"results"`
}
type InventoryFilter struct {
Device string `schema:"device"`
}
// ListDevices method returns dcim_device_list from Netbox API
func (n *NetBox) ListInventory(d *DcimInventoryItemsList, f *InventoryFilter) error {
encoder := schema.NewEncoder()
transport := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: n.InsecureSkipVerify},
}
timeout := time.Duration(60 * time.Second)
client := &http.Client{
Timeout: timeout,
Transport: transport,
}
deviceurl := n.RootURL + "/api/dcim/inventory-items/"
if f != nil {
form := url.Values{}
err := encoder.Encode(f, form)
if err != nil {
return err
}
query := form.Encode()
deviceurl = deviceurl + "?" + query
}
var request *http.Request
var err error
request, err = http.NewRequest("GET", deviceurl, nil)
if err != nil {
return err
}
request.Header.Add("Accept", "application/json")
request.Header.Add("Authorization", " Token "+n.Token)
response, err := client.Do(request)
if err != nil {
return err
}
if response.StatusCode != http.StatusOK {
return errors.Errorf("Error: response was: %d should be %d (%s)\n", response.StatusCode, http.StatusOK, deviceurl)
}
data, err := ioutil.ReadAll(response.Body)
if err != nil {
return err
}
err = response.Body.Close()
if err != nil {
return err
}
err = json.Unmarshal(data, &d)
if err != nil {
return err
}
return nil
}
func (n *NetBox) AddInventory(v *AddInventory) error {
data, err := json.Marshal(v)
if err != nil {
return err
}
transport := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: n.InsecureSkipVerify},
}
timeout := time.Duration(60 * time.Second)
client := &http.Client{
Timeout: timeout,
Transport: transport,
}
request, err := http.NewRequest("POST", n.RootURL+"/api/dcim/inventory-items/", bytes.NewBuffer(data))
if err != nil {
return err
}
request.Header.Add("Accept", "application/json")
request.Header.Add("Content-Type", "application/json")
request.Header.Add("Authorization", " Token "+n.Token)
response, err := client.Do(request)
if err != nil {
return err
}
err = response.Body.Close()
if err != nil {
return err
}
if response.StatusCode == http.StatusCreated {
return nil
}
return errors.Errorf("Error: response was: %d should be %d\n", response.StatusCode, http.StatusCreated)
}

View file

@ -1,217 +0,0 @@
package netboxgo
import (
"bytes"
"crypto/tls"
"encoding/json"
// "fmt"
"io/ioutil"
"net/http"
"net/url"
"time"
"github.com/gorilla/schema"
"github.com/pkg/errors"
)
// IpamPrefixesCreate is used for the return values from Netbox API ipam_prefixes_create
type IpamPrefixesCreate struct {
Prefix string `json:"prefix"`
Site int `json:"site"`
Vrf int `json:"vrf"`
Tenant int `json:"tenant"`
VLAN int `json:"vlan"`
Status int `json:"status"`
Role int `json:"role"`
IsPool bool `json:"is_pool"`
Description string `json:"description"`
Tags []string `json:"tags"`
CustomFields struct {
} `json:"custom_fields"`
}
// IpamPrefixesList is used for the return value from NetBox API ipam_prefixes_list
type IpamPrefixesList struct {
Count int `json:"count"`
Next string `json:"next"`
Previous string `json:"previous"`
Results []struct {
ID int `json:"id"`
Family struct {
Label string `json:"label"`
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"`
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"`
} `json:"vlan"`
Status struct {
Label string `json:"label"`
Value string `json:"value"`
} `json:"status"`
Role struct {
ID int `json:"id"`
URL string `json:"url"`
Name string `json:"name"`
Slug string `json:"slug"`
PrefixCount int `json:"prefix_count"`
VLANCount int `json:"vlan_count"`
} `json:"role"`
IsPool bool `json:"is_pool"`
Description string `json:"description"`
Tags []struct {
ID int `json:"id"`
URL string `json:"url"`
Name string `json:"name"`
Slug string `json:"slug"`
Color string `json:"color"`
} `json:"tags"`
CustomFields struct {
} `json:"custom_fields"`
Created string `json:"created"`
LastUpdated time.Time `json:"last_updated"`
} `json:"results"`
}
// PrefixFilter is used to filter out returned object from Netbox API ipam_prefixes_list
type PrefixFilter struct {
Offset int64 `schema:"offset,omitempty"`
Limit int64 `schema:"limit,omitempty"`
// User specific filters
Family string `schema:"family,omitempty"`
IsPool string `schema:"is_pool,omitempty"`
EnforceUnique string `schema:"enforce_unique,omitempty"`
TenantGroupID string `schema:"tenant_group_id,omitempty"`
TenantGroup string `schema:"tenant_group,omitempty"`
TenantID string `schema:"tenant_id,omitempty"`
Tenant string `schema:"tenant,omitempty"`
IDIn string `schema:"id__in,omitempty"`
Q string `schema:"q,omitempty"`
Tag string `schema:"tag,omitempty"`
Prefix string `schema:"prefix,omitempty"`
Within string `schema:"within,omitempty"`
WithinInclude string `schema:"within_include,omitempty"`
Contains string `schema:"contains,omitempty"`
MaskLength string `schema:"mask_length,omitempty"`
VrfID string `schema:"vrf_id,omitempty"`
Vrf string `schema:"vrf,omitempty"`
RegionID string `schema:"region_id,omitempty"`
Region string `schema:"region,omitempty"`
SiteID string `schema:"site_id,omitempty"`
Site string `schema:"site,omitempty"`
VLANID string `schema:"vlan_id,omitempty"`
Role string `schema:"role,omitempty"`
Status string `schema:"status,omitempty"`
}
// ListPrefixes returns Netbox ipam_prefixes_list
func (n *NetBox) ListPrefixes(i *IpamPrefixesList, f *PrefixFilter) error {
encoder := schema.NewEncoder()
form := url.Values{}
err := encoder.Encode(f, form)
if err != nil {
return err
}
query := form.Encode()
transport := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: n.InsecureSkipVerify},
}
timeout := time.Duration(60 * time.Second)
client := &http.Client{
Timeout: timeout,
Transport: transport,
}
request, err := http.NewRequest("GET", n.RootURL+"/api/ipam/prefixes/?"+query, nil)
if err != nil {
return err
}
request.Header.Add("Accept", "application/json")
request.Header.Add("Authorization", " Token "+n.Token)
response, err := client.Do(request)
if err != nil {
return err
}
if response.StatusCode != http.StatusOK {
return errors.Errorf("Error: response was: %d should be %d\n", response.StatusCode, http.StatusOK)
}
data, err := ioutil.ReadAll(response.Body)
if err != nil {
return err
}
err = response.Body.Close()
if err != nil {
return err
}
err = json.Unmarshal(data, &i)
if err != nil {
return err
}
return nil
}
// CreatePrefixes creates interfaces via Netbox API ipam_prefixes_create
func (n *NetBox) CreatePrefixes(i *IpamPrefixesCreate) error {
vrfData, err := json.Marshal(i)
if err != nil {
return err
}
transport := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: n.InsecureSkipVerify},
}
timeout := time.Duration(60 * time.Second)
client := &http.Client{
Timeout: timeout,
Transport: transport,
}
request, err := http.NewRequest("POST", n.RootURL+"/api/ipam/prefixes/", bytes.NewBuffer(vrfData))
if err != nil {
return err
}
request.Header.Add("Accept", "application/json")
request.Header.Add("Content-Type", "application/json")
request.Header.Add("Authorization", " Token "+n.Token)
response, err := client.Do(request)
if err != nil {
return err
}
err = response.Body.Close()
if err != nil {
return err
}
if response.StatusCode == http.StatusCreated {
return nil
}
return errors.Errorf("Error: response was: %d should be %d\n", response.StatusCode, http.StatusCreated)
}

View file

@ -1,157 +0,0 @@
package netboxgo
import (
"crypto/tls"
"encoding/json"
// "fmt"
"io/ioutil"
"net/http"
"net/url"
"time"
"github.com/gorilla/schema"
"github.com/pkg/errors"
)
type SiteGroupsList struct {
Count int `json:"count"`
Next string `json:"next"`
Previous string `json:"previous"`
Results []SiteGroupList `json:"results"`
}
type SiteGroupList struct {
ID int `json:"id"`
URL string `json:"url"`
Display string `json:"display"`
Name string `json:"name"`
Slug string `json:"slug"`
Parent struct {
ID int `json:"id"`
URL string `json:"url"`
Display string `json:"display"`
Name string `json:"name"`
Slug string `json:"slug"`
SiteCount int `json:"site_count"`
Depth int `json:"_depth"`
} `json:"parent"`
Description string `json:"description"`
CustomFields struct {
} `json:"custom_fields"`
Created string `json:"created"`
LastUpdated time.Time `json:"last_updated"`
SiteCount int `json:"site_count"`
Depth int `json:"_depth"`
}
// SiteFilter is used to filter out returned object from Netbox API tenancy_tenants_list
type SiteGroupFilter struct {
Offset int64 `schema:"offset,omitempty"`
Limit int64 `schema:"limit,omitempty"`
// User specific filters
Name string `schema:"name,omitempty"`
ID string `schema:"id,omitempty"`
Slug string `schema:"slug,omitempty"`
Description string `schema:"description,omitempty"`
Group string `schema:"group,omitempty"`
GroupID string `schema:"group_id,omitempty"`
Parent string `schema:"parent,omitempty"`
IDIn string `schema:"id__in,omitempty"`
Q string `schema:"q,omitempty"`
Tag string `schema:"tag,omitempty"`
}
// ListSitegroups returns Netbox tenancy_tenants_list
func (n *NetBox) ListSiteGroups(i *SiteGroupsList, f *SiteFilter) error {
encoder := schema.NewEncoder()
form := url.Values{}
err := encoder.Encode(f, form)
if err != nil {
return err
}
query := form.Encode()
transport := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: n.InsecureSkipVerify},
}
timeout := time.Duration(60 * time.Second)
client := &http.Client{
Timeout: timeout,
Transport: transport,
}
request, err := http.NewRequest("GET", n.RootURL+"/api/dcim/sites/?"+query, nil)
if err != nil {
return err
}
request.Header.Add("Accept", "application/json")
request.Header.Add("Authorization", " Token "+n.Token)
response, err := client.Do(request)
if err != nil {
return err
}
if response.StatusCode != http.StatusOK {
return errors.Errorf("Error: response was: %d should be %d\n", response.StatusCode, http.StatusOK)
}
data, err := ioutil.ReadAll(response.Body)
if err != nil {
return err
}
err = response.Body.Close()
if err != nil {
return err
}
err = json.Unmarshal(data, &i)
if err != nil {
return err
}
return nil
}
// GetSiteGroup returns a Netbox site-group
func (n *NetBox) GetSiteGroup(i *SiteGroupList, id string) error {
transport := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: n.InsecureSkipVerify},
}
timeout := time.Duration(60 * time.Second)
client := &http.Client{
Timeout: timeout,
Transport: transport,
}
request, err := http.NewRequest("GET", n.RootURL+"/api/dcim/site-groups/"+id, nil)
if err != nil {
return err
}
request.Header.Add("Accept", "application/json")
request.Header.Add("Authorization", " Token "+n.Token)
response, err := client.Do(request)
if err != nil {
return err
}
if response.StatusCode != http.StatusOK {
return errors.Errorf("Error: response was: %d should be %d\n", response.StatusCode, http.StatusOK)
}
data, err := ioutil.ReadAll(response.Body)
if err != nil {
return err
}
err = response.Body.Close()
if err != nil {
return err
}
err = json.Unmarshal(data, &i)
if err != nil {
return err
}
return nil
}

View file

@ -1,167 +0,0 @@
package netboxgo
import (
"bytes"
"crypto/tls"
"encoding/json"
// "fmt"
"io/ioutil"
"net/http"
"net/url"
"time"
"github.com/gorilla/schema"
"github.com/pkg/errors"
)
// TenancyTenantsCreate is used for the return values from Netbox API tenancy_tenants_create
type TenancyTenantsCreate struct {
Name string `json:"name"`
Slug string `json:"slug"`
Group int `json:"group"`
Description string `json:"description"`
Comments string `json:"comments"`
Tags []string `json:"tags"`
CustomFields struct {
} `json:"custom_fields"`
}
// TenancyTenantsList is used for the return value from NetBox API tenancy_tenants_list
type TenancyTenantsList struct {
Count int `json:"count"`
Next string `json:"next"`
Previous interface{} `json:"previous"`
Results []struct {
ID int `json:"id"`
Name string `json:"name"`
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 struct {
AccountNumber string `json:"account_number"`
AtlasCustNumber interface{} `json:"atlas_cust_number"`
TextField interface{} `json:"text_field"`
} `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
type TenantFilter struct {
Offset int64 `schema:"offset,omitempty"`
Limit int64 `schema:"limit,omitempty"`
// User specific filters
Name string `schema:"name,omitempty"`
Slug string `schema:"slug,omitempty"`
Group string `schema:"group,omitempty"`
GroupID string `schema:"group_id,omitempty"`
IDIn string `schema:"id__in,omitempty"`
Q string `schema:"q,omitempty"`
Tag string `schema:"tag,omitempty"`
}
// ListTenants returns Netbox tenancy_tenants_list
func (n *NetBox) ListTenants(i *TenancyTenantsList, f *TenantFilter) error {
encoder := schema.NewEncoder()
form := url.Values{}
err := encoder.Encode(f, form)
if err != nil {
return err
}
query := form.Encode()
transport := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: n.InsecureSkipVerify},
}
timeout := time.Duration(60 * time.Second)
client := &http.Client{
Timeout: timeout,
Transport: transport,
}
request, err := http.NewRequest("GET", n.RootURL+"/api/tenancy/tenants/?"+query, nil)
if err != nil {
return err
}
request.Header.Add("Accept", "application/json")
request.Header.Add("Authorization", " Token "+n.Token)
response, err := client.Do(request)
if err != nil {
return err
}
if response.StatusCode != http.StatusOK {
return errors.Errorf("Error: response was: %d should be %d\n", response.StatusCode, http.StatusOK)
}
data, err := ioutil.ReadAll(response.Body)
if err != nil {
return err
}
err = response.Body.Close()
if err != nil {
return err
}
err = json.Unmarshal(data, &i)
if err != nil {
return err
}
return nil
}
// CreateTenants creates interfaces via Netbox API tenancy_tenants_create
func (n *NetBox) CreateTenants(i *TenancyTenantsCreate) error {
vrfData, err := json.Marshal(i)
if err != nil {
return err
}
transport := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: n.InsecureSkipVerify},
}
timeout := time.Duration(60 * time.Second)
client := &http.Client{
Timeout: timeout,
Transport: transport,
}
request, err := http.NewRequest("POST", n.RootURL+"/api/tenancy/tenants/", bytes.NewBuffer(vrfData))
if err != nil {
return err
}
request.Header.Add("Accept", "application/json")
request.Header.Add("Content-Type", "application/json")
request.Header.Add("Authorization", " Token "+n.Token)
response, err := client.Do(request)
if err != nil {
return err
}
err = response.Body.Close()
if err != nil {
return err
}
if response.StatusCode == http.StatusCreated {
return nil
}
return errors.Errorf("Error: response was: %d should be %d\n", response.StatusCode, http.StatusCreated)
}

View file

@ -1,284 +0,0 @@
package netboxgo
import (
"bytes"
"crypto/tls"
"encoding/json"
"io/ioutil"
"net/http"
"net/url"
"time"
"github.com/gorilla/schema"
"github.com/pkg/errors"
)
//VirtualizationVirtualMachinesCreate is used to create new VirtualizationVirtualMachines
type VirtualizationVirtualMachinesCreate struct {
ID int `json:"id"`
Name string `json:"name"`
Status struct {
Label string `json:"label"`
Value int `json:"value"`
} `json:"status"`
Site struct {
ID int `json:"id"`
URL string `json:"url"`
Name string `json:"name"`
Slug string `json:"slug"`
} `json:"site"`
Cluster struct {
ID int `json:"id"`
URL string `json:"url"`
Name string `json:"name"`
VirtualmachineCount int `json:"virtualmachine_count"`
} `json:"cluster"`
Role struct {
ID int `json:"id"`
URL string `json:"url"`
Name string `json:"name"`
Slug string `json:"slug"`
DeviceCount int `json:"device_count"`
VirtualmachineCount int `json:"virtualmachine_count"`
} `json:"role"`
Tenant struct {
ID int `json:"id"`
URL string `json:"url"`
Name string `json:"name"`
Slug string `json:"slug"`
} `json:"tenant"`
Platform struct {
ID int `json:"id"`
URL string `json:"url"`
Name string `json:"name"`
Slug string `json:"slug"`
DeviceCount int `json:"device_count"`
VirtualmachineCount int `json:"virtualmachine_count"`
} `json:"platform"`
PrimaryIP struct {
ID int `json:"id"`
URL string `json:"url"`
Family int `json:"family"`
Address string `json:"address"`
} `json:"primary_ip"`
PrimaryIP4 struct {
ID int `json:"id"`
URL string `json:"url"`
Family int `json:"family"`
Address string `json:"address"`
} `json:"primary_ip4"`
PrimaryIP6 struct {
ID int `json:"id"`
URL string `json:"url"`
Family int `json:"family"`
Address string `json:"address"`
} `json:"primary_ip6"`
Vcpus int `json:"vcpus"`
Memory int `json:"memory"`
Disk int `json:"disk"`
Comments string `json:"comments"`
LocalContextData string `json:"local_context_data"`
Tags []string `json:"tags"`
CustomFields struct {
} `json:"custom_fields"`
ConfigContext struct {
AdditionalProp1 string `json:"additionalProp1"`
AdditionalProp2 string `json:"additionalProp2"`
AdditionalProp3 string `json:"additionalProp3"`
} `json:"config_context"`
Created string `json:"created"`
LastUpdated time.Time `json:"last_updated"`
}
//VirtualizationClustersCreate is used to create new VirtualizationClusters
type VirtualizationClustersCreate struct {
ID int `json:"id"`
Name string `json:"name"`
Type struct {
ID int `json:"id"`
URL string `json:"url"`
Name string `json:"name"`
Slug string `json:"slug"`
ClusterCount int `json:"cluster_count"`
} `json:"type"`
Group struct {
ID int `json:"id"`
URL string `json:"url"`
Name string `json:"name"`
Slug string `json:"slug"`
ClusterCount int `json:"cluster_count"`
} `json:"group"`
Site struct {
ID int `json:"id"`
URL string `json:"url"`
Name string `json:"name"`
Slug string `json:"slug"`
} `json:"site"`
Comments string `json:"comments"`
Tags []struct {
ID int `json:"id"`
URL string `json:"url"`
Name string `json:"name"`
Slug string `json:"slug"`
Color string `json:"color"`
} `json:"tags"`
CustomFields struct {
} `json:"custom_fields"`
Created string `json:"created"`
LastUpdated time.Time `json:"last_updated"`
DeviceCount int `json:"device_count"`
VirtualmachineCount int `json:"virtualmachine_count"`
}
// VirtualizationClustersList is used to list VirtualizationClusters
type VirtualizationClustersList struct {
Count int `json:"count"`
Next string `json:"next"`
Previous string `json:"previous"`
Results []struct {
ID int `json:"id"`
Name string `json:"name"`
Type struct {
ID int `json:"id"`
URL string `json:"url"`
Name string `json:"name"`
Slug string `json:"slug"`
ClusterCount int `json:"cluster_count"`
} `json:"type"`
Group struct {
ID int `json:"id"`
URL string `json:"url"`
Name string `json:"name"`
Slug string `json:"slug"`
ClusterCount int `json:"cluster_count"`
} `json:"group"`
Site struct {
ID int `json:"id"`
URL string `json:"url"`
Name string `json:"name"`
Slug string `json:"slug"`
} `json:"site"`
Comments string `json:"comments"`
Tags []struct {
ID int `json:"id"`
URL string `json:"url"`
Name string `json:"name"`
Slug string `json:"slug"`
Color string `json:"color"`
} `json:"tags"`
CustomFields struct {
} `json:"custom_fields"`
Created string `json:"created"`
LastUpdated time.Time `json:"last_updated"`
DeviceCount int `json:"device_count"`
VirtualmachineCount int `json:"virtualmachine_count"`
} `json:"results"`
}
// ClusterFilter is used to filter out VirtualizationClusters
type ClusterFilter struct {
Offset int64 `schema:"offset,omitempty"`
Limit int64 `schema:"limit,omitempty"`
//User specific filters
Name string `schema:"name,omitempty"`
Group string `schema:"group,omitempty"`
GroupID string `schema:"group_id,omitempty"`
TypeID string `schema:"type_id,omitempty"`
Type string `schema:"type,omitempty"`
SiteID string `schema:"site_id,omitempty"`
Site string `schema:"site,omitempty"`
Tenant string `schema:"tenant,omitempty"`
IDIn string `schema:"id__in,omitempty"`
Q string `schema:"q,omitempty"`
Tag string `schema:"tag,omitempty"`
}
// ListClusters returns Netbox virtualization_clusters
func (n *NetBox) ListClusters(i *VirtualizationClustersList, f *ClusterFilter) error {
var encoder = schema.NewEncoder()
form := url.Values{}
err := encoder.Encode(f, form)
if err != nil {
return err
}
query := form.Encode()
transport := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: n.InsecureSkipVerify},
}
timeout := time.Duration(60 * time.Second)
client := &http.Client{
Timeout: timeout,
Transport: transport,
}
request, err := http.NewRequest("GET", n.RootURL+"/api/virtualization/clusters/?"+query, nil)
if err != nil {
return err
}
request.Header.Add("Accept", "application/json")
request.Header.Add("Authorization", " Token "+n.Token)
response, err := client.Do(request)
if err != nil {
return err
}
if response.StatusCode != http.StatusOK {
return errors.Errorf("Error: response was: %d should be %d\n", response.StatusCode, http.StatusOK)
}
data, err := ioutil.ReadAll(response.Body)
if err != nil {
return err
}
err = response.Body.Close()
if err != nil {
return err
}
err = json.Unmarshal(data, &i)
if err != nil {
return err
}
return nil
}
// CreateVirtualMachine creates VirtualMachines via Netbox API dcim_interfaces_create
func (n *NetBox) CreateVirtualMachine(v *VirtualizationClustersCreate) error {
data, err := json.Marshal(v)
if err != nil {
return err
}
transport := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: n.InsecureSkipVerify},
}
timeout := time.Duration(60 * time.Second)
client := &http.Client{
Timeout: timeout,
Transport: transport,
}
request, err := http.NewRequest("POST", n.RootURL+"/api/virtualization/virtual-machines/", bytes.NewBuffer(data))
if err != nil {
return err
}
request.Header.Add("Accept", "application/json")
request.Header.Add("Content-Type", "application/json")
request.Header.Add("Authorization", " Token "+n.Token)
response, err := client.Do(request)
if err != nil {
return err
}
err = response.Body.Close()
if err != nil {
return err
}
if response.StatusCode == http.StatusCreated {
return nil
}
return errors.Errorf("Error: response was: %d should be %d\n", response.StatusCode, http.StatusCreated)
}

View file

@ -1,240 +0,0 @@
package netboxgo
import (
"bytes"
"crypto/tls"
"encoding/json"
// "fmt"
"io/ioutil"
"net/http"
"net/url"
"time"
"github.com/gorilla/schema"
"github.com/pkg/errors"
)
// IpamVLANsCreate is used for the return values from Netbox API ipam_vlans_create
type IpamVLANsCreate struct {
Site int `json:"site"`
Group int `json:"group"`
Vid int `json:"vid"`
Name string `json:"name"`
Tenant int `json:"tenant"`
Status int `json:"status"`
Role int `json:"role"`
Description string `json:"description"`
Tags []string `json:"tags"`
CustomFields struct {
} `json:"custom_fields"`
}
type IpamVLAN struct {
ID int `json:"id"`
Site struct {
ID int `json:"id"`
URL string `json:"url"`
Name string `json:"name"`
Slug string `json:"slug"`
} `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 {
ID int `json:"id"`
URL string `json:"url"`
Name string `json:"name"`
Slug string `json:"slug"`
} `json:"tenant"`
Status struct {
Label string `json:"label"`
Value string `json:"value"`
} `json:"status"`
Role struct {
ID int `json:"id"`
URL string `json:"url"`
Name string `json:"name"`
Slug string `json:"slug"`
PrefixCount int `json:"prefix_count"`
VLANCount int `json:"vlan_count"`
} `json:"role"`
Description string `json:"description"`
Tags []string `json:"tags"`
DisplayName string `json:"display_name"`
CustomFields struct {
} `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
type IpamVLANsList struct {
Count int `json:"count"`
Next string `json:"next"`
Previous string `json:"previous"`
Results []IpamVLAN `json:"results"`
}
type VLAN struct {
ID int `json:"id"`
Site struct {
ID int `json:"id"`
URL string `json:"url"`
Name string `json:"name"`
Slug string `json:"slug"`
} `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 {
ID int `json:"id"`
URL string `json:"url"`
Name string `json:"name"`
Slug string `json:"slug"`
} `json:"tenant"`
Status struct {
Label string `json:"label"`
Value string `json:"value"`
} `json:"status"`
Role struct {
ID int `json:"id"`
URL string `json:"url"`
Name string `json:"name"`
Slug string `json:"slug"`
PrefixCount int `json:"prefix_count"`
VLANCount int `json:"vlan_count"`
} `json:"role"`
Description string `json:"description"`
Tags []string `json:"tags"`
DisplayName string `json:"display_name"`
CustomFields struct {
} `json:"custom_fields"`
Created string `json:"created"`
LastUpdated time.Time `json:"last_updated"`
PrefixCount int `json:"prefix_count"`
}
// VLANFilter is used to filter out returned object from Netbox API ipam_vlans_list
type VLANFilter struct {
Offset int64 `schema:"offset,omitempty"`
Limit int64 `schema:"limit,omitempty"`
// User specific filters
Vid string `schema:"vid,omitempty"`
Name string `schema:"name,omitempty"`
TenantGroupID string `schema:"tenant_group_id,omitempty"`
TenantGroup string `schema:"tenant_group,omitempty"`
TenantID string `schema:"tenant_id,omitempty"`
Tenant string `schema:"tenant,omitempty"`
IDIn string `schema:"id__in,omitempty"`
Q string `schema:"q,omitempty"`
SiteID string `schema:"site_id,omitempty"`
Site string `schema:"site,omitempty"`
GroupID string `schema:"group_id,omitempty"`
Group string `schema:"group,omitempty"`
RoleID string `schema:"role_id,omitempty"`
Role string `schema:"role,omitempty"`
Status string `schema:"status,omitempty"`
Tag string `schema:"tag,omitempty"`
}
// ListVLANs returns Netbox ipam_vlans_list
func (n *NetBox) ListVLANs(i *IpamVLANsList, f *VLANFilter) error {
encoder := schema.NewEncoder()
form := url.Values{}
err := encoder.Encode(f, form)
if err != nil {
return err
}
query := form.Encode()
transport := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: n.InsecureSkipVerify},
}
timeout := time.Duration(60 * time.Second)
client := &http.Client{
Timeout: timeout,
Transport: transport,
}
request, err := http.NewRequest("GET", n.RootURL+"/api/ipam/vlans/?"+query, nil)
if err != nil {
return err
}
request.Header.Add("Accept", "application/json")
request.Header.Add("Authorization", " Token "+n.Token)
response, err := client.Do(request)
if err != nil {
return err
}
if response.StatusCode != http.StatusOK {
return errors.Errorf("Error: response was: %d should be %d\n", response.StatusCode, http.StatusOK)
}
data, err := ioutil.ReadAll(response.Body)
if err != nil {
return err
}
err = response.Body.Close()
if err != nil {
return err
}
err = json.Unmarshal(data, &i)
if err != nil {
return err
}
return nil
}
// CreateVLANs creates interfaces via Netbox API ipam_vlans_create
func (n *NetBox) CreateVLANs(i *IpamVLANsCreate) error {
vrfData, err := json.Marshal(i)
if err != nil {
return err
}
transport := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: n.InsecureSkipVerify},
}
timeout := time.Duration(60 * time.Second)
client := &http.Client{
Timeout: timeout,
Transport: transport,
}
request, err := http.NewRequest("POST", n.RootURL+"/api/ipam/vlans/", bytes.NewBuffer(vrfData))
if err != nil {
return err
}
request.Header.Add("Accept", "application/json")
request.Header.Add("Content-Type", "application/json")
request.Header.Add("Authorization", " Token "+n.Token)
response, err := client.Do(request)
if err != nil {
return err
}
err = response.Body.Close()
if err != nil {
return err
}
if response.StatusCode == http.StatusCreated {
return nil
}
return errors.Errorf("Error: response was: %d should be %d\n", response.StatusCode, http.StatusCreated)
}

View file

@ -1,161 +0,0 @@
package netboxgo
import (
"bytes"
"crypto/tls"
"encoding/json"
// "fmt"
"io/ioutil"
"net/http"
"net/url"
"time"
"github.com/gorilla/schema"
"github.com/pkg/errors"
)
// IpamVrfsCreate is used for the return values from Netbox API ipam_vrfs_create
type IpamVrfsCreate struct {
Name string `json:"name"`
Rd string `json:"rd"`
Tenant int `json:"tenant"`
EnforceUnique bool `json:"enforce_unique"`
Description string `json:"description"`
Tags []string `json:"tags"`
CustomFields struct {
} `json:"custom_fields"`
}
// IpamVrfsList is used for the return value from NetBox API ipam_vrfs_list
type IpamVrfsList struct {
Count int `json:"count"`
Next string `json:"next"`
Previous string `json:"previous"`
Results []struct {
ID int `json:"id"`
Name string `json:"name"`
Rd string `json:"rd"`
Tenant struct {
ID int `json:"id"`
URL string `json:"url"`
Name string `json:"name"`
Slug string `json:"slug"`
} `json:"tenant"`
EnforceUnique bool `json:"enforce_unique"`
Description string `json:"description"`
Tags []string `json:"tags"`
DisplayName string `json:"display_name"`
CustomFields struct {
} `json:"custom_fields"`
Created string `json:"created"`
LastUpdated time.Time `json:"last_updated"`
IpaddressCount int `json:"ipaddress_count"`
PrefixCount int `json:"prefix_count"`
} `json:"results"`
}
// VrfFilter is used to filter out returned object from Netbox API ipam_vrfs_list
type VrfFilter struct {
Offset int64 `schema:"offset,omitempty"`
Limit int64 `schema:"limit,omitempty"`
//User specific filters
Name string `schema:"name,omitempty"`
RD string `schema:"rd,omitempty"`
EnforceUnique string `schema:"enforce_unique,omitempty"`
TenantGroupID string `schema:"tenant_group_id,omitempty"`
TenantGroup string `schema:"tenant_group,omitempty"`
TenantID string `schema:"tenant_id,omitempty"`
Tenant string `schema:"tenant,omitempty"`
IDIn string `schema:"id__in,omitempty"`
Q string `schema:"q,omitempty"`
Tag string `schema:"tag,omitempty"`
}
// ListVrfs returns Netbox ipam_vrfs_list
func (n *NetBox) ListVrfs(i *IpamVrfsList, f *VrfFilter) error {
var encoder = schema.NewEncoder()
form := url.Values{}
err := encoder.Encode(f, form)
if err != nil {
return err
}
query := form.Encode()
transport := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: n.InsecureSkipVerify},
}
timeout := time.Duration(60 * time.Second)
client := &http.Client{
Timeout: timeout,
Transport: transport,
}
request, err := http.NewRequest("GET", n.RootURL+"/api/ipam/vrfs/?"+query, nil)
if err != nil {
return err
}
request.Header.Add("Accept", "application/json")
request.Header.Add("Authorization", " Token "+n.Token)
response, err := client.Do(request)
if err != nil {
return err
}
if response.StatusCode != http.StatusOK {
return errors.Errorf("Error: response was: %d should be %d\n", response.StatusCode, http.StatusOK)
}
data, err := ioutil.ReadAll(response.Body)
if err != nil {
return err
}
err = response.Body.Close()
if err != nil {
return err
}
err = json.Unmarshal(data, &i)
if err != nil {
return err
}
return nil
}
// CreateVrfs creates interfaces via Netbox API ipam_vrfs_create
func (n *NetBox) CreateVrfs(i *IpamVrfsCreate) error {
vrfData, err := json.Marshal(i)
if err != nil {
return err
}
transport := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: n.InsecureSkipVerify},
}
timeout := time.Duration(60 * time.Second)
client := &http.Client{
Timeout: timeout,
Transport: transport,
}
request, err := http.NewRequest("POST", n.RootURL+"/api/ipam/vrfs/", bytes.NewBuffer(vrfData))
if err != nil {
return err
}
request.Header.Add("Accept", "application/json")
request.Header.Add("Content-Type", "application/json")
request.Header.Add("Authorization", " Token "+n.Token)
response, err := client.Do(request)
if err != nil {
return err
}
err = response.Body.Close()
if err != nil {
return err
}
if response.StatusCode == http.StatusCreated {
return nil
}
return errors.Errorf("Error: response was: %d should be %d\n", response.StatusCode, http.StatusCreated)
}

282
prefixes.go Normal file
View file

@ -0,0 +1,282 @@
package netboxgo
import (
"context"
"fmt"
"net/http"
"net/url"
"time"
// "fmt"
"github.com/gorilla/schema"
)
type PrefixesService service
// NewPrefix is used for the return values from Netbox API ipam_prefixes_create
type NewPrefix struct {
Prefix string `json:"prefix"`
Site int `json:"site"`
Vrf int `json:"vrf"`
Tenant int `json:"tenant"`
VLAN int `json:"vlan"`
Status int `json:"status"`
Role int `json:"role"`
IsPool bool `json:"is_pool"`
Description string `json:"description"`
Tags []string `json:"tags"`
CustomFields struct{} `json:"custom_fields"`
}
// Prefixes is used for the return value from NetBox API ipam_prefixes_list
type Prefixes struct {
Count int `json:"count"`
Next string `json:"next"`
Previous string `json:"previous"`
Results []struct {
ID int `json:"id"`
Family struct {
Label string `json:"label"`
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"`
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"`
} `json:"vlan"`
Status struct {
Label string `json:"label"`
Value string `json:"value"`
} `json:"status"`
Role struct {
ID int `json:"id"`
URL string `json:"url"`
Name string `json:"name"`
Slug string `json:"slug"`
PrefixCount int `json:"prefix_count"`
VLANCount int `json:"vlan_count"`
} `json:"role"`
IsPool bool `json:"is_pool"`
Description string `json:"description"`
Tags []struct {
ID int `json:"id"`
URL string `json:"url"`
Name string `json:"name"`
Slug string `json:"slug"`
Color string `json:"color"`
} `json:"tags"`
CustomFields struct{} `json:"custom_fields"`
Created string `json:"created"`
LastUpdated time.Time `json:"last_updated"`
} `json:"results"`
}
// PrefixFilter is used to filter out returned object from Netbox API ipam_prefixes_list
type PrefixFilter struct {
Offset int64 `schema:"offset,omitempty"`
Limit int64 `schema:"limit,omitempty"`
// User specific filters
Family string `schema:"family,omitempty"`
IsPool string `schema:"is_pool,omitempty"`
EnforceUnique string `schema:"enforce_unique,omitempty"`
TenantGroupID string `schema:"tenant_group_id,omitempty"`
TenantGroup string `schema:"tenant_group,omitempty"`
TenantID string `schema:"tenant_id,omitempty"`
Tenant string `schema:"tenant,omitempty"`
IDIn string `schema:"id__in,omitempty"`
Q string `schema:"q,omitempty"`
Tag string `schema:"tag,omitempty"`
Prefix string `schema:"prefix,omitempty"`
Within string `schema:"within,omitempty"`
WithinInclude string `schema:"within_include,omitempty"`
Contains string `schema:"contains,omitempty"`
MaskLength string `schema:"mask_length,omitempty"`
VrfID string `schema:"vrf_id,omitempty"`
Vrf string `schema:"vrf,omitempty"`
RegionID string `schema:"region_id,omitempty"`
Region string `schema:"region,omitempty"`
SiteID string `schema:"site_id,omitempty"`
Site string `schema:"site,omitempty"`
VLANID string `schema:"vlan_id,omitempty"`
Role string `schema:"role,omitempty"`
Status string `schema:"status,omitempty"`
}
const prefixesPath = ipamPath + "/prefixes"
// List prefixes. PrefixFilter is used to list based on filter queries.
func (s *PrefixesService) List(ctx context.Context, f *PrefixFilter) (*Prefixes, error) {
var prefixes Prefixes
var query string
var req *http.Request
var err error
encoder := schema.NewEncoder()
form := url.Values{}
err = encoder.Encode(f, form)
if err != nil {
return &prefixes, err
}
query = form.Encode()
req, err = s.client.newRequest(ctx, "GET", prefixesPath, query, nil)
if err != nil {
return &prefixes, err
}
_, err = s.client.do(req, &prefixes)
if err != nil {
return &prefixes, err
}
return &prefixes, nil
}
// Create a prefix
func (s *PrefixesService) Create(ctx context.Context, c *NewPrefix) error {
var err error
var req *http.Request
req, err = s.client.newRequest(ctx, "POST", prefixesPath, "", c)
if err != nil {
return fmt.Errorf("unable to create request: %w", err)
}
_, err = s.client.do(req, nil)
if err != nil {
return fmt.Errorf("unable to do request: %w", err)
}
return nil
}
// // Update a prefix
// func (s *PrefixesService) Update(ctx context.Context, id string, c *UpdatePrefix) error {
// var req *http.Request
// var err error
// path := fmt.Sprintf("%s/%s", prefixesPath, id)
// req, err = s.client.newRequest(ctx, "PATCH", path, "", c)
// if err != nil {
// return fmt.Errorf("unable to create request: %w", err)
// }
// _, err = s.client.do(req, nil)
// if err != nil {
// return fmt.Errorf("unable to do request: %w", err)
// }
// return nil
// }
// // ListPrefixes returns Netbox ipam_prefixes_list
// func (n *NetBox) ListPrefixes(i *Prefixes, f *PrefixFilter) error {
// encoder := schema.NewEncoder()
// form := url.Values{}
// err := encoder.Encode(f, form)
// if err != nil {
// return err
// }
// query := form.Encode()
// transport := &http.Transport{
// TLSClientConfig: &tls.Config{InsecureSkipVerify: n.InsecureSkipVerify},
// }
// timeout := time.Duration(60 * time.Second)
// client := &http.Client{
// Timeout: timeout,
// Transport: transport,
// }
// request, err := http.NewRequest("GET", n.RootURL+"/api/ipam/prefixes/?"+query, nil)
// if err != nil {
// return err
// }
// request.Header.Add("Accept", "application/json")
// request.Header.Add("Authorization", " Token "+n.Token)
// response, err := client.Do(request)
// if err != nil {
// return err
// }
// if response.StatusCode != http.StatusOK {
// return errors.Errorf("Error: response was: %d should be %d\n", response.StatusCode, http.StatusOK)
// }
// data, err := ioutil.ReadAll(response.Body)
// if err != nil {
// return err
// }
// err = response.Body.Close()
// if err != nil {
// return err
// }
// err = json.Unmarshal(data, &i)
// if err != nil {
// return err
// }
// return nil
// }
// // CreatePrefixes creates interfaces via Netbox API ipam_prefixes_create
// func (n *NetBox) CreatePrefixes(i *NewPrefix) error {
// vrfData, err := json.Marshal(i)
// if err != nil {
// return err
// }
// transport := &http.Transport{
// TLSClientConfig: &tls.Config{InsecureSkipVerify: n.InsecureSkipVerify},
// }
// timeout := time.Duration(60 * time.Second)
// client := &http.Client{
// Timeout: timeout,
// Transport: transport,
// }
// request, err := http.NewRequest("POST", n.RootURL+"/api/ipam/prefixes/", bytes.NewBuffer(vrfData))
// if err != nil {
// return err
// }
// request.Header.Add("Accept", "application/json")
// request.Header.Add("Content-Type", "application/json")
// request.Header.Add("Authorization", " Token "+n.Token)
// response, err := client.Do(request)
// if err != nil {
// return err
// }
// err = response.Body.Close()
// if err != nil {
// return err
// }
// if response.StatusCode == http.StatusCreated {
// return nil
// }
// return errors.Errorf("Error: response was: %d should be %d\n", response.StatusCode, http.StatusCreated)
// }

View file

@ -1,18 +1,16 @@
package netboxgo package netboxgo
import ( import (
"crypto/tls" "context"
"encoding/json"
"io/ioutil"
"net/http" "net/http"
"net/url" "net/url"
"time"
"github.com/gorilla/schema" "github.com/gorilla/schema"
"github.com/pkg/errors"
) )
type RearPortList struct { type RearPortsService service
type RearPorts struct {
Count int `json:"count"` Count int `json:"count"`
Next string `json:"next"` Next string `json:"next"`
Previous string `json:"previous"` Previous string `json:"previous"`
@ -54,58 +52,33 @@ type RearPortFilter struct {
Device string `schema:"device,omitempty"` Device string `schema:"device,omitempty"`
} }
// ListRearPorts method returns dcim_device_list from Netbox API const rearPortsPath = dcimPath + "/rear-ports"
func (n *NetBox) ListRearPorts(d *RearPortList, f *RearPortFilter) error {
// List rearports. RearPortFilter is used to list based on filter queries.
func (s *RearPortsService) List(ctx context.Context, f *RearPortFilter) (*RearPorts, error) {
var rearports RearPorts
var query string
var req *http.Request
var err error
encoder := schema.NewEncoder() encoder := schema.NewEncoder()
transport := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: n.InsecureSkipVerify},
}
timeout := time.Duration(60 * time.Second)
client := &http.Client{
Timeout: timeout,
Transport: transport,
}
deviceurl := n.RootURL + "/api/dcim/rear-ports/"
if f != nil {
form := url.Values{} form := url.Values{}
err := encoder.Encode(f, form) err = encoder.Encode(f, form)
if err != nil { if err != nil {
return err return &rearports, err
} }
query := form.Encode() query = form.Encode()
deviceurl = deviceurl + "?" + query
} req, err = s.client.newRequest(ctx, "GET", rearPortsPath, query, nil)
var request *http.Request
var err error
request, err = http.NewRequest("GET", deviceurl, nil)
if err != nil { if err != nil {
return err return &rearports, err
}
request.Header.Add("Accept", "application/json")
request.Header.Add("Authorization", " Token "+n.Token)
response, err := client.Do(request)
if err != nil {
return err
} }
if response.StatusCode != http.StatusOK { _, err = s.client.do(req, &rearports)
return errors.Errorf("Error: response was: %d should be %d (%s)\n", response.StatusCode, http.StatusOK, deviceurl) if err != nil {
return &rearports, err
} }
data, err := ioutil.ReadAll(response.Body) return &rearports, nil
if err != nil {
return err
}
err = response.Body.Close()
if err != nil {
return err
}
err = json.Unmarshal(data, &d)
if err != nil {
return err
}
return nil
} }

View file

@ -1,19 +1,19 @@
package netboxgo package netboxgo
import ( import (
"crypto/tls" "context"
"encoding/json" "fmt"
"io/ioutil"
"net/http" "net/http"
"net/url" "net/url"
"time" "time"
"github.com/gorilla/schema" "github.com/gorilla/schema"
"github.com/pkg/errors"
) )
// SecretsList contains secrets type SecretsService service
type SecretsList struct {
// Secrets contains secrets
type Secrets struct {
Count int `json:"count"` Count int `json:"count"`
Next string `json:"next"` Next string `json:"next"`
Previous string `json:"previous"` Previous string `json:"previous"`
@ -42,8 +42,7 @@ type SecretsList struct {
Slug string `json:"slug"` Slug string `json:"slug"`
Color string `json:"color"` Color string `json:"color"`
} `json:"tags"` } `json:"tags"`
CustomFields struct { CustomFields struct{} `json:"custom_fields"`
} `json:"custom_fields"`
Created string `json:"created"` Created string `json:"created"`
LastUpdated time.Time `json:"last_updated"` LastUpdated time.Time `json:"last_updated"`
} `json:"results"` } `json:"results"`
@ -66,54 +65,37 @@ type SecretFilter struct {
Tag string `schema:"tag,omitempty"` Tag string `schema:"tag,omitempty"`
} }
// ListSecrets returns Netbox Secrets const secretsPath = "/secrets"
func (n *NetBox) ListSecrets(i *SecretsList, f *SecretFilter) error {
// List secrets. SecretsFilter is used to list based on filter queries.
func (s *SecretsService) List(ctx context.Context, f *SecretFilter) (*Secrets, error) {
var secrets Secrets
var query string
var req *http.Request
var err error
if s.client.SessionKey == "" {
return &secrets, fmt.Errorf("session key needed when interacting with secrets. no session key found: you need to fetch a session key with FetchSessionKey()")
}
encoder := schema.NewEncoder() encoder := schema.NewEncoder()
form := url.Values{} form := url.Values{}
err := encoder.Encode(f, form) err = encoder.Encode(f, form)
if err != nil { if err != nil {
return err return &secrets, err
} }
query := form.Encode() query = form.Encode()
transport := &http.Transport{ req, err = s.client.newRequest(ctx, "GET", secretsPath+"/secrets", query, nil)
TLSClientConfig: &tls.Config{InsecureSkipVerify: n.InsecureSkipVerify},
}
timeout := time.Duration(60 * time.Second)
client := &http.Client{
Timeout: timeout,
Transport: transport,
}
request, err := http.NewRequest("GET", n.RootURL+"/api/secrets/secrets/?"+query, nil)
if err != nil { if err != nil {
return err return &secrets, err
}
request.Header.Add("Accept", "application/json")
request.Header.Add("Authorization", " Token "+n.Token)
request.Header.Add("X-Session-Key", n.SessionKey)
response, err := client.Do(request)
if err != nil {
return err
} }
if response.StatusCode != http.StatusOK { _, err = s.client.do(req, &secrets)
return errors.Errorf("Error: response was: %d should be %d\n", response.StatusCode, http.StatusOK) if err != nil {
return &secrets, err
} }
data, err := ioutil.ReadAll(response.Body) return &secrets, nil
if err != nil {
return err
}
err = response.Body.Close()
if err != nil {
return err
}
err = json.Unmarshal(data, &i)
if err != nil {
return err
}
return nil
} }

151
site_groups.go Normal file
View file

@ -0,0 +1,151 @@
package netboxgo
import (
"context"
"fmt"
"net/http"
"net/url"
"time"
"github.com/gorilla/schema"
)
type SiteGroupsService service
type SiteGroups struct {
Count int `json:"count"`
Next string `json:"next"`
Previous string `json:"previous"`
Results []SiteGroup `json:"results"`
}
type SiteGroup struct {
ID int `json:"id"`
URL string `json:"url"`
Display string `json:"display"`
Name string `json:"name"`
Slug string `json:"slug"`
Parent struct {
ID int `json:"id"`
URL string `json:"url"`
Display string `json:"display"`
Name string `json:"name"`
Slug string `json:"slug"`
SiteCount int `json:"site_count"`
Depth int `json:"_depth"`
} `json:"parent"`
Description string `json:"description"`
CustomFields struct{} `json:"custom_fields"`
Created string `json:"created"`
LastUpdated time.Time `json:"last_updated"`
SiteCount int `json:"site_count"`
Depth int `json:"_depth"`
}
// SiteFilter is used to filter out returned object from Netbox API tenancy_tenants_list
type SiteGroupFilter struct {
Offset int64 `schema:"offset,omitempty"`
Limit int64 `schema:"limit,omitempty"`
// User specific filters
Name string `schema:"name,omitempty"`
ID string `schema:"id,omitempty"`
Slug string `schema:"slug,omitempty"`
Description string `schema:"description,omitempty"`
Group string `schema:"group,omitempty"`
GroupID string `schema:"group_id,omitempty"`
Parent string `schema:"parent,omitempty"`
IDIn string `schema:"id__in,omitempty"`
Q string `schema:"q,omitempty"`
Tag string `schema:"tag,omitempty"`
}
const siteGroupsPath = dcimPath + "/site-groups"
// List sitegroups. SiteGroupFilter is used to list based on filter queries.
func (s *SiteGroupsService) List(ctx context.Context, f *SiteGroupFilter) (*SiteGroups, error) {
var sitegroups SiteGroups
var query string
var req *http.Request
var err error
encoder := schema.NewEncoder()
form := url.Values{}
err = encoder.Encode(f, form)
if err != nil {
return &sitegroups, err
}
query = form.Encode()
req, err = s.client.newRequest(ctx, "GET", siteGroupsPath, query, nil)
if err != nil {
return &sitegroups, err
}
_, err = s.client.do(req, &sitegroups)
if err != nil {
return &sitegroups, err
}
return &sitegroups, nil
}
// Create a sitegroup
// func (s *SiteGroupsService) Create(ctx context.Context, c *NewSiteGroup) error {
// var err error
// var req *http.Request
//
// req, err = s.client.newRequest(ctx, "POST", siteGroupsPath, "", c)
// if err != nil {
// return fmt.Errorf("unable to create request: %w", err)
// }
//
// _, err = s.client.do(req, nil)
// if err != nil {
// return fmt.Errorf("unable to do request: %w", err)
// }
//
// return nil
// }
// Get a SiteGroup based on id
func (s *SiteGroupsService) Get(ctx context.Context, id string) (*SiteGroup, error) {
var sitegroup SiteGroup
var err error
path := fmt.Sprintf("%s/%s", siteGroupsPath, id)
req, err := s.client.newRequest(ctx, "GET", path, "", nil)
if err != nil {
return &sitegroup, err
}
_, err = s.client.do(req, &sitegroup)
if err != nil {
return &sitegroup, err
}
return &sitegroup, err
}
// // Update a device
// func (s *SiteGroupsService) Update(ctx context.Context, id string, c *UpdateDevice) error {
// var req *http.Request
// var err error
// path := fmt.Sprintf("%s/%s", siteGroupsPath, id)
// req, err = s.client.newRequest(ctx, "PATCH", path, "", c)
// if err != nil {
// return fmt.Errorf("unable to create request: %w", err)
// }
// _, err = s.client.do(req, nil)
// if err != nil {
// return fmt.Errorf("unable to do request: %w", err)
// }
// return nil
// }

View file

@ -1,27 +1,25 @@
package netboxgo package netboxgo
import ( import (
"crypto/tls" "context"
"encoding/json" "fmt"
// "fmt"
"io/ioutil"
"net/http" "net/http"
"net/url" "net/url"
"time" "time"
"github.com/gorilla/schema" "github.com/gorilla/schema"
"github.com/pkg/errors"
) )
type SitesList struct { type SitesService service
type Sites struct {
Count int `json:"count"` Count int `json:"count"`
Next string `json:"next"` Next string `json:"next"`
Previous string `json:"previous"` Previous string `json:"previous"`
Results []SiteList `json:"results"` Results []Site `json:"results"`
} }
type SiteList struct { type Site struct {
ID int `json:"id"` ID int `json:"id"`
URL string `json:"url"` URL string `json:"url"`
Display string `json:"display"` Display string `json:"display"`
@ -76,8 +74,7 @@ type SiteList struct {
Slug string `json:"slug"` Slug string `json:"slug"`
Color string `json:"color"` Color string `json:"color"`
} `json:"tags"` } `json:"tags"`
CustomFields struct { CustomFields struct{} `json:"custom_fields"`
} `json:"custom_fields"`
Created string `json:"created"` Created string `json:"created"`
LastUpdated time.Time `json:"last_updated"` LastUpdated time.Time `json:"last_updated"`
CircuitCount int `json:"circuit_count"` CircuitCount int `json:"circuit_count"`
@ -104,95 +101,92 @@ type SiteFilter struct {
Tag string `schema:"tag,omitempty"` Tag string `schema:"tag,omitempty"`
} }
// ListTenants returns Netbox tenancy_tenants_list const sitesPath = dcimPath + "/sites"
func (n *NetBox) ListSites(i *SitesList, f *SiteFilter) error {
// List sites. SiteFilter is used to list based on filter queries.
func (s *SitesService) List(ctx context.Context, f *SiteFilter) (*Sites, error) {
var sites Sites
var query string
var req *http.Request
var err error
encoder := schema.NewEncoder() encoder := schema.NewEncoder()
form := url.Values{} form := url.Values{}
err := encoder.Encode(f, form) err = encoder.Encode(f, form)
if err != nil { if err != nil {
return err return &sites, err
} }
query := form.Encode() query = form.Encode()
transport := &http.Transport{ req, err = s.client.newRequest(ctx, "GET", sitesPath, query, nil)
TLSClientConfig: &tls.Config{InsecureSkipVerify: n.InsecureSkipVerify},
}
timeout := time.Duration(60 * time.Second)
client := &http.Client{
Timeout: timeout,
Transport: transport,
}
request, err := http.NewRequest("GET", n.RootURL+"/api/dcim/sites/?"+query, nil)
if err != nil { if err != nil {
return err return &sites, err
}
request.Header.Add("Accept", "application/json")
request.Header.Add("Authorization", " Token "+n.Token)
response, err := client.Do(request)
if err != nil {
return err
} }
if response.StatusCode != http.StatusOK { _, err = s.client.do(req, &sites)
return errors.Errorf("Error: response was: %d should be %d\n", response.StatusCode, http.StatusOK) if err != nil {
return &sites, err
} }
data, err := ioutil.ReadAll(response.Body) return &sites, nil
if err != nil {
return err
}
err = response.Body.Close()
if err != nil {
return err
}
err = json.Unmarshal(data, &i)
if err != nil {
return err
}
return nil
} }
// GetSite returns Netbox tenancy_tenants_list // Get a Site based on id
func (n *NetBox) GetSite(i *SiteList, id string) error { func (s *SitesService) Get(ctx context.Context, id string) (*Site, error) {
transport := &http.Transport{ var site Site
TLSClientConfig: &tls.Config{InsecureSkipVerify: n.InsecureSkipVerify},
} var err error
timeout := time.Duration(60 * time.Second)
client := &http.Client{ path := fmt.Sprintf("%s/%s", sitesPath, id)
Timeout: timeout,
Transport: transport, req, err := s.client.newRequest(ctx, "GET", path, "", nil)
}
request, err := http.NewRequest("GET", n.RootURL+"/api/dcim/sites/"+id, nil)
if err != nil { if err != nil {
return err return &site, err
}
request.Header.Add("Accept", "application/json")
request.Header.Add("Authorization", " Token "+n.Token)
response, err := client.Do(request)
if err != nil {
return err
} }
if response.StatusCode != http.StatusOK { _, err = s.client.do(req, &site)
return errors.Errorf("Error: response was: %d should be %d\n", response.StatusCode, http.StatusOK) if err != nil {
return &site, err
} }
data, err := ioutil.ReadAll(response.Body) return &site, err
if err != nil {
return err
}
err = response.Body.Close()
if err != nil {
return err
}
err = json.Unmarshal(data, &i)
if err != nil {
return err
}
return nil
} }
// // Create a site
// func (s *SitesService) Create(ctx context.Context, c *NewSite) error {
// var err error
// var req *http.Request
// req, err = s.client.newRequest(ctx, "POST", sitesPath, "", c)
// if err != nil {
// return fmt.Errorf("unable to create request: %w", err)
// }
// _, err = s.client.do(req, nil)
// if err != nil {
// return fmt.Errorf("unable to do request: %w", err)
// }
// return nil
// }
// // Update a device
// func (s *SitesService) Update(ctx context.Context, id string, c *UpdateDevice) error {
// var req *http.Request
// var err error
// path := fmt.Sprintf("%s/%s", sitesPath, id)
// req, err = s.client.newRequest(ctx, "PATCH", path, "", c)
// if err != nil {
// return fmt.Errorf("unable to create request: %w", err)
// }
// _, err = s.client.do(req, nil)
// if err != nil {
// return fmt.Errorf("unable to do request: %w", err)
// }
// return nil
// }

145
tenants.go Normal file
View file

@ -0,0 +1,145 @@
package netboxgo
import (
"context"
"fmt"
"net/http"
"net/url"
"time"
"github.com/gorilla/schema"
)
type TenantsService service
// NewTenant is used for the return values from Netbox API tenancy_tenants_create
type NewTenant struct {
Name string `json:"name"`
Slug string `json:"slug"`
Group int `json:"group"`
Description string `json:"description"`
Comments string `json:"comments"`
Tags []string `json:"tags"`
CustomFields struct{} `json:"custom_fields"`
}
// Tenants is used for the return value from NetBox API tenancy_tenants_list
type Tenants struct {
Count int `json:"count"`
Next string `json:"next"`
Previous interface{} `json:"previous"`
Results []struct {
ID int `json:"id"`
Name string `json:"name"`
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 struct {
AccountNumber string `json:"account_number"`
AtlasCustNumber interface{} `json:"atlas_cust_number"`
TextField interface{} `json:"text_field"`
} `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
type TenantFilter struct {
Offset int64 `schema:"offset,omitempty"`
Limit int64 `schema:"limit,omitempty"`
// User specific filters
Name string `schema:"name,omitempty"`
Slug string `schema:"slug,omitempty"`
Group string `schema:"group,omitempty"`
GroupID string `schema:"group_id,omitempty"`
IDIn string `schema:"id__in,omitempty"`
Q string `schema:"q,omitempty"`
Tag string `schema:"tag,omitempty"`
}
const tenantsPath = tenancyPath + "/tenants"
// List tenants. TenantFilter is used to list based on filter queries.
func (s *TenantsService) List(ctx context.Context, f *TenantFilter) (*Tenants, error) {
var tenants Tenants
var query string
var req *http.Request
var err error
encoder := schema.NewEncoder()
form := url.Values{}
err = encoder.Encode(f, form)
if err != nil {
return &tenants, err
}
query = form.Encode()
req, err = s.client.newRequest(ctx, "GET", tenantsPath, query, nil)
if err != nil {
return &tenants, err
}
_, err = s.client.do(req, &tenants)
if err != nil {
return &tenants, err
}
return &tenants, nil
}
// Create a tenant
func (s *TenantsService) Create(ctx context.Context, c *NewTenant) error {
var err error
var req *http.Request
req, err = s.client.newRequest(ctx, "POST", tenantsPath, "", c)
if err != nil {
return fmt.Errorf("unable to create request: %w", err)
}
_, err = s.client.do(req, nil)
if err != nil {
return fmt.Errorf("unable to do request: %w", err)
}
return nil
}
// // Update a device
// func (s *TenantsService) Update(ctx context.Context, id string, c *UpdateDevice) error {
// var req *http.Request
// var err error
// path := fmt.Sprintf("%s/%s", tenantsPath, id)
// req, err = s.client.newRequest(ctx, "PATCH", path, "", c)
// if err != nil {
// return fmt.Errorf("unable to create request: %w", err)
// }
// _, err = s.client.do(req, nil)
// if err != nil {
// return fmt.Errorf("unable to do request: %w", err)
// }
// return nil
// }

106
virtual_machines.go Normal file
View file

@ -0,0 +1,106 @@
package netboxgo
import (
"context"
"fmt"
"net/http"
"time"
)
type VirtualMachinesService service
// NewVirtualMachine is used to create new VirtualizationVirtualMachines
type NewVirtualMachine struct {
ID int `json:"id"`
Name string `json:"name"`
Status struct {
Label string `json:"label"`
Value int `json:"value"`
} `json:"status"`
Site struct {
ID int `json:"id"`
URL string `json:"url"`
Name string `json:"name"`
Slug string `json:"slug"`
} `json:"site"`
Cluster struct {
ID int `json:"id"`
URL string `json:"url"`
Name string `json:"name"`
VirtualmachineCount int `json:"virtualmachine_count"`
} `json:"cluster"`
Role struct {
ID int `json:"id"`
URL string `json:"url"`
Name string `json:"name"`
Slug string `json:"slug"`
DeviceCount int `json:"device_count"`
VirtualmachineCount int `json:"virtualmachine_count"`
} `json:"role"`
Tenant struct {
ID int `json:"id"`
URL string `json:"url"`
Name string `json:"name"`
Slug string `json:"slug"`
} `json:"tenant"`
Platform struct {
ID int `json:"id"`
URL string `json:"url"`
Name string `json:"name"`
Slug string `json:"slug"`
DeviceCount int `json:"device_count"`
VirtualmachineCount int `json:"virtualmachine_count"`
} `json:"platform"`
PrimaryIP struct {
ID int `json:"id"`
URL string `json:"url"`
Family int `json:"family"`
Address string `json:"address"`
} `json:"primary_ip"`
PrimaryIP4 struct {
ID int `json:"id"`
URL string `json:"url"`
Family int `json:"family"`
Address string `json:"address"`
} `json:"primary_ip4"`
PrimaryIP6 struct {
ID int `json:"id"`
URL string `json:"url"`
Family int `json:"family"`
Address string `json:"address"`
} `json:"primary_ip6"`
Vcpus int `json:"vcpus"`
Memory int `json:"memory"`
Disk int `json:"disk"`
Comments string `json:"comments"`
LocalContextData string `json:"local_context_data"`
Tags []string `json:"tags"`
CustomFields struct{} `json:"custom_fields"`
ConfigContext struct {
AdditionalProp1 string `json:"additionalProp1"`
AdditionalProp2 string `json:"additionalProp2"`
AdditionalProp3 string `json:"additionalProp3"`
} `json:"config_context"`
Created string `json:"created"`
LastUpdated time.Time `json:"last_updated"`
}
const virtualMachinesPath = virtualizationPath + "/virtual-machines"
// Create a virtual-machine
func (s *VirtualMachinesService) Create(ctx context.Context, c *NewVirtualMachine) error {
var err error
var req *http.Request
req, err = s.client.newRequest(ctx, "POST", virtualMachinesPath, "", c)
if err != nil {
return fmt.Errorf("unable to create request: %w", err)
}
_, err = s.client.do(req, nil)
if err != nil {
return fmt.Errorf("unable to do request: %w", err)
}
return nil
}

172
vlans.go Normal file
View file

@ -0,0 +1,172 @@
package netboxgo
import (
"context"
"fmt"
"net/http"
"net/url"
"time"
"github.com/gorilla/schema"
)
type VLANsService service
// NewVLAN is used for the return values from Netbox API ipam_vlans_create
type NewVLAN struct {
Site int `json:"site"`
Group int `json:"group"`
Vid int `json:"vid"`
Name string `json:"name"`
Tenant int `json:"tenant"`
Status int `json:"status"`
Role int `json:"role"`
Description string `json:"description"`
Tags []string `json:"tags"`
CustomFields struct{} `json:"custom_fields"`
}
type VLAN struct {
ID int `json:"id"`
Site struct {
ID int `json:"id"`
URL string `json:"url"`
Name string `json:"name"`
Slug string `json:"slug"`
} `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 {
ID int `json:"id"`
URL string `json:"url"`
Name string `json:"name"`
Slug string `json:"slug"`
} `json:"tenant"`
Status struct {
Label string `json:"label"`
Value string `json:"value"`
} `json:"status"`
Role struct {
ID int `json:"id"`
URL string `json:"url"`
Name string `json:"name"`
Slug string `json:"slug"`
PrefixCount int `json:"prefix_count"`
VLANCount int `json:"vlan_count"`
} `json:"role"`
Description string `json:"description"`
Tags []string `json:"tags"`
DisplayName string `json:"display_name"`
CustomFields struct{} `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
type VLANs struct {
Count int `json:"count"`
Next string `json:"next"`
Previous string `json:"previous"`
Results []VLAN `json:"results"`
}
// VLANFilter is used to filter out returned object from Netbox API ipam_vlans_list
type VLANFilter struct {
Offset int64 `schema:"offset,omitempty"`
Limit int64 `schema:"limit,omitempty"`
// User specific filters
Vid string `schema:"vid,omitempty"`
Name string `schema:"name,omitempty"`
TenantGroupID string `schema:"tenant_group_id,omitempty"`
TenantGroup string `schema:"tenant_group,omitempty"`
TenantID string `schema:"tenant_id,omitempty"`
Tenant string `schema:"tenant,omitempty"`
IDIn string `schema:"id__in,omitempty"`
Q string `schema:"q,omitempty"`
SiteID string `schema:"site_id,omitempty"`
Site string `schema:"site,omitempty"`
GroupID string `schema:"group_id,omitempty"`
Group string `schema:"group,omitempty"`
RoleID string `schema:"role_id,omitempty"`
Role string `schema:"role,omitempty"`
Status string `schema:"status,omitempty"`
Tag string `schema:"tag,omitempty"`
}
const vlansPath = ipamPath + "/vlans"
// List vlans. VLANFilter is used to list based on filter queries.
func (s *VLANsService) List(ctx context.Context, f *VLANFilter) (*VLANs, error) {
var vlans VLANs
var query string
var req *http.Request
var err error
encoder := schema.NewEncoder()
form := url.Values{}
err = encoder.Encode(f, form)
if err != nil {
return &vlans, err
}
query = form.Encode()
req, err = s.client.newRequest(ctx, "GET", vlansPath, query, nil)
if err != nil {
return &vlans, err
}
_, err = s.client.do(req, &vlans)
if err != nil {
return &vlans, err
}
return &vlans, nil
}
// Create a device
func (s *VLANsService) Create(ctx context.Context, c *NewDevice) error {
var err error
var req *http.Request
req, err = s.client.newRequest(ctx, "POST", vlansPath, "", c)
if err != nil {
return fmt.Errorf("unable to create request: %w", err)
}
_, err = s.client.do(req, nil)
if err != nil {
return fmt.Errorf("unable to do request: %w", err)
}
return nil
}
// // Update a device
// func (s *VLANsService) Update(ctx context.Context, id string, c *UpdateVLAN) error {
// var req *http.Request
// var err error
// path := fmt.Sprintf("%s/%s", vlansPath, id)
// req, err = s.client.newRequest(ctx, "PATCH", path, "", c)
// if err != nil {
// return fmt.Errorf("unable to create request: %w", err)
// }
// _, err = s.client.do(req, nil)
// if err != nil {
// return fmt.Errorf("unable to do request: %w", err)
// }
// return nil
// }

138
vrfs.go Normal file
View file

@ -0,0 +1,138 @@
package netboxgo
import (
"context"
"fmt"
"net/http"
"net/url"
"time"
"github.com/gorilla/schema"
)
type VRFsService service
// NewVRF is used for the return values from Netbox API ipam_vrfs_create
type NewVRF struct {
Name string `json:"name"`
Rd string `json:"rd"`
Tenant int `json:"tenant"`
EnforceUnique bool `json:"enforce_unique"`
Description string `json:"description"`
Tags []string `json:"tags"`
CustomFields struct{} `json:"custom_fields"`
}
// VRFs is used for the return value from NetBox API ipam_vrfs_list
type VRFs struct {
Count int `json:"count"`
Next string `json:"next"`
Previous string `json:"previous"`
Results []struct {
ID int `json:"id"`
Name string `json:"name"`
Rd string `json:"rd"`
Tenant struct {
ID int `json:"id"`
URL string `json:"url"`
Name string `json:"name"`
Slug string `json:"slug"`
} `json:"tenant"`
EnforceUnique bool `json:"enforce_unique"`
Description string `json:"description"`
Tags []string `json:"tags"`
DisplayName string `json:"display_name"`
CustomFields struct{} `json:"custom_fields"`
Created string `json:"created"`
LastUpdated time.Time `json:"last_updated"`
IpaddressCount int `json:"ipaddress_count"`
PrefixCount int `json:"prefix_count"`
} `json:"results"`
}
// VRFFilter is used to filter out returned object from Netbox API ipam_vrfs_list
type VRFFilter struct {
Offset int64 `schema:"offset,omitempty"`
Limit int64 `schema:"limit,omitempty"`
// User specific filters
Name string `schema:"name,omitempty"`
RD string `schema:"rd,omitempty"`
EnforceUnique string `schema:"enforce_unique,omitempty"`
TenantGroupID string `schema:"tenant_group_id,omitempty"`
TenantGroup string `schema:"tenant_group,omitempty"`
TenantID string `schema:"tenant_id,omitempty"`
Tenant string `schema:"tenant,omitempty"`
IDIn string `schema:"id__in,omitempty"`
Q string `schema:"q,omitempty"`
Tag string `schema:"tag,omitempty"`
}
const vrfsPath = ipamPath + "/vrfs"
// List vrfs. VRFFilter is used to list based on filter queries.
func (s *VRFsService) List(ctx context.Context, f *VRFFilter) (*VRFs, error) {
var vrfs VRFs
var query string
var req *http.Request
var err error
encoder := schema.NewEncoder()
form := url.Values{}
err = encoder.Encode(f, form)
if err != nil {
return &vrfs, err
}
query = form.Encode()
req, err = s.client.newRequest(ctx, "GET", vrfsPath, query, nil)
if err != nil {
return &vrfs, err
}
_, err = s.client.do(req, &vrfs)
if err != nil {
return &vrfs, err
}
return &vrfs, nil
}
// Create a device
func (s *VRFsService) Create(ctx context.Context, c *NewVRF) error {
var err error
var req *http.Request
req, err = s.client.newRequest(ctx, "POST", vrfsPath, "", c)
if err != nil {
return fmt.Errorf("unable to create request: %w", err)
}
_, err = s.client.do(req, nil)
if err != nil {
return fmt.Errorf("unable to do request: %w", err)
}
return nil
}
// // Update a device
// func (s *VRFsService) Update(ctx context.Context, id string, c *UpdateVRF) error {
// var req *http.Request
// var err error
// path := fmt.Sprintf("%s/%s", vrfsPath, id)
// req, err = s.client.newRequest(ctx, "PATCH", path, "", c)
// if err != nil {
// return fmt.Errorf("unable to create request: %w", err)
// }
// _, err = s.client.do(req, nil)
// if err != nil {
// return fmt.Errorf("unable to do request: %w", err)
// }
// return nil
// }