Skip to content
Snippets Groups Projects
Commit d6c53a94 authored by Dave Cameron's avatar Dave Cameron
Browse files

Allow user to specify their API token

parent 2b01b034
No related branches found
No related tags found
No related merge requests found
...@@ -38,16 +38,20 @@ type Client struct { ...@@ -38,16 +38,20 @@ type Client struct {
// Tenancy provides access to methods in NetBox's Tenancy API. // Tenancy provides access to methods in NetBox's Tenancy API.
Tenancy *TenancyService Tenancy *TenancyService
token string
u *url.URL u *url.URL
client *http.Client client *http.Client
} }
// NewClient returns a new instance of a NetBox client. addr specifies the address // NewClient returns a new instance of a NetBox client. addr specifies the address
// of the NetBox server, and client specifies an optional HTTP client to use // of the NetBox server, token specifies the api key to use,
// for requests. // and client specifies an optional HTTP client to use for requests.
//
// If token is the empty string, no Authentication will be included in requests,
// providing anonymous read-only access depending on your NetBox config.
// //
// If client is nil, a default HTTP client will be used. // If client is nil, a default HTTP client will be used.
func NewClient(addr string, client *http.Client) (*Client, error) { func NewClient(addr string, token string, client *http.Client) (*Client, error) {
if client == nil { if client == nil {
client = &http.Client{} client = &http.Client{}
} }
...@@ -65,6 +69,7 @@ func NewClient(addr string, client *http.Client) (*Client, error) { ...@@ -65,6 +69,7 @@ func NewClient(addr string, client *http.Client) (*Client, error) {
} }
c := &Client{ c := &Client{
token: token,
u: u, u: u,
client: client, client: client,
} }
...@@ -116,18 +121,23 @@ func (c *Client) NewDataRequest(method string, endpoint string, options Valuer, ...@@ -116,18 +121,23 @@ func (c *Client) NewDataRequest(method string, endpoint string, options Valuer,
u := c.u.ResolveReference(rel) u := c.u.ResolveReference(rel)
// If no valuer specified, create a request with no query parameters // If a valuer is specified, add the values as the query string
if options == nil { if options != nil {
return http.NewRequest(method, u.String(), body) values, err := options.Values()
if err != nil {
return nil, err
}
u.RawQuery = values.Encode()
} }
values, err := options.Values() req, err := http.NewRequest(method, u.String(), body)
if err != nil { if err != nil {
return nil, err return nil, err
} }
u.RawQuery = values.Encode() if c.token != "" {
req.Header.Set("Authorization", fmt.Sprintf("Token %s", c.token))
return http.NewRequest(method, u.String(), body) }
return req, nil
} }
// NewJSONRequest creates a HTTP request using the input HTTP method, URL // NewJSONRequest creates a HTTP request using the input HTTP method, URL
......
...@@ -152,7 +152,7 @@ func TestClientQueryParameters(t *testing.T) { ...@@ -152,7 +152,7 @@ func TestClientQueryParameters(t *testing.T) {
Bar: wantBar, Bar: wantBar,
}) })
if err != nil { if err != nil {
t.Fatal("expected an error, but no error returned") t.Fatalf("unexpected error: %v", err)
} }
q := req.URL.Query() q := req.URL.Query()
...@@ -183,7 +183,7 @@ func TestClientPrependBaseURLPath(t *testing.T) { ...@@ -183,7 +183,7 @@ func TestClientPrependBaseURLPath(t *testing.T) {
req, err := c.NewRequest(http.MethodGet, "/api/ipam/vlans", nil) req, err := c.NewRequest(http.MethodGet, "/api/ipam/vlans", nil)
if err != nil { if err != nil {
t.Fatal("expected an error, but no error returned") t.Fatalf("unexpected error: %v", err)
} }
if want, got := "/netbox/api/ipam/vlans", req.URL.Path; want != got { if want, got := "/netbox/api/ipam/vlans", req.URL.Path; want != got {
...@@ -192,6 +192,23 @@ func TestClientPrependBaseURLPath(t *testing.T) { ...@@ -192,6 +192,23 @@ func TestClientPrependBaseURLPath(t *testing.T) {
} }
} }
func TestAuthenticatingClientAddsHeader(t *testing.T) {
c, err := NewClient("localhost", "auth-token", nil)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
req, err := c.NewRequest(http.MethodGet, "/api/ipam/vlans", nil)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if want, got := "Token auth-token", req.Header.Get("Authorization"); want != got {
t.Fatalf("unexpected Authorization header:\n- want: %q\n- got: %q",
want, got)
}
}
type testValuer struct { type testValuer struct {
Foo string Foo string
Bar int Bar int
...@@ -214,7 +231,7 @@ func (q testValuer) Values() (url.Values, error) { ...@@ -214,7 +231,7 @@ func (q testValuer) Values() (url.Values, error) {
func testClient(t *testing.T, fn func(w http.ResponseWriter, r *http.Request)) (*Client, func()) { func testClient(t *testing.T, fn func(w http.ResponseWriter, r *http.Request)) (*Client, func()) {
s := httptest.NewServer(http.HandlerFunc(fn)) s := httptest.NewServer(http.HandlerFunc(fn))
c, err := NewClient(s.URL, nil) c, err := NewClient(s.URL, "", nil)
if err != nil { if err != nil {
t.Fatalf("error creating Client: %v", err) t.Fatalf("error creating Client: %v", err)
} }
......
...@@ -72,7 +72,7 @@ func ExampleNewClient() { ...@@ -72,7 +72,7 @@ func ExampleNewClient() {
defer done() defer done()
// Creates a client configured to use the test server // Creates a client configured to use the test server
c, err := NewClient(addr, nil) c, err := NewClient(addr, "", nil)
if err != nil { if err != nil {
panic(fmt.Sprintf("failed to create netbox.Client: %v", err)) panic(fmt.Sprintf("failed to create netbox.Client: %v", err))
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment