Code Monkey home page Code Monkey logo

pynetbox's People

Contributors

abhi1693 avatar abringenberg avatar arthanson avatar dimaqa avatar dvaccarosenna avatar explody avatar fach avatar h-otter avatar jeremystretch avatar jerradgit avatar johanfleury avatar jqueuniet avatar jsenecal avatar lamiskin avatar lukasjuhrich avatar mandarg avatar markkuleinio avatar meoflynn avatar nautics889 avatar raddessi avatar srfwx avatar stefanmcshane avatar steffenschumacher avatar stsmrvestas avatar tweippert avatar tyler-8 avatar victorpavlushin avatar vincentbernat avatar weisdd avatar zachmoody avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pynetbox's Issues

Filtering manufacturers by 'id' doesn't seem to work properly.

So, I'm trying to get the following NetBox call to work, but no matter which id I pass, I always get a list of all manufacturers back:

$ cat import_manufacturers.py
#!/usr/bin/env python

import pynetbox

url   = '[REMOVED]'
token = '[REMOVED]'
nb = pynetbox.api(url,token)

def manufacturer_details(id):
  print(nb.dcim.manufacturers.filter(id=id))

for i in range(1,7):
  print("ID: {}".format(i))
  manufacturer_details(1)

This should work, but all I get back is the following:

$ ./import_manufacturers.py
ID: 1
[APC, Arista, Cisco, Dell, HP, IBM, Juniper]
ID: 2
[APC, Arista, Cisco, Dell, HP, IBM, Juniper]
ID: 3
[APC, Arista, Cisco, Dell, HP, IBM, Juniper]
ID: 4
[APC, Arista, Cisco, Dell, HP, IBM, Juniper]
ID: 5
[APC, Arista, Cisco, Dell, HP, IBM, Juniper]
ID: 6
[APC, Arista, Cisco, Dell, HP, IBM, Juniper]

Filtering by name and slug both seem to work fine, it is just when using id it always returns a list of all existing manufacturers.

Running the same query via the API doesn't seem have this problem.

Any suggestions on what I'm doing incorrectly?

index_cache prefix field is integer instead of string representation of ip address/prefix

https://github.com/digitalocean/pynetbox/blob/bc759873dfb9c012548c2148ff0af73f6ff54fbb/pynetbox/lib/response.py#L24

This line causes IPNetwork object to return integer representation of IP address which causes
cache to be different than serialized data even without any attribute changes
[In]:
netaddr.IPNetwork('10.0.0.0/8').value
[Out]:
167772160

[In]:
aggregate = nb.ipam.aggregates.get(q='10.0.0.0/8')
aggregate._index_cache
[Out]:
[(u'last_updated', u'2016-08-01T15:22:20.938000Z'),
(u'description', u'Private IPv4 space'),
(u'family', 4),
(u'created', u'2016-08-01'),
(u'rir', 6),
(u'prefix', 167772160),
(u'date_added', None),
(u'id', 1),
(u'custom_fields', {}),
(u'uuid', u'a33eeba8-803d-426f-ada9-ec69633c6f77')]
[In]:
aggregate.serialize()
[Out]:
{u'created': u'2016-08-01',
u'custom_fields': {},
u'date_added': None,
u'description': u'Private IPv4 space',
u'family': 4,
u'id': 1,
u'last_updated': u'2016-08-01T15:22:20.938000Z',
u'prefix': '10.0.0.0/8',
u'rir': 6,
u'uuid': u'a33eeba8-803d-426f-ada9-ec69633c6f77'}
[In]:
aggregate._compare()
[Out]:
False

Self-signed SSL certificate failures

HTTPS connections that use self-signed SSL certificates return CERTIFICATE_VERIFY_FAILED.
It would be beneficial to have an override option for request HTTP headers verify=False or to provide verify='/path/to/certfile'.

Virtualization support

Hi,

Thanks for the lib.

Do you plan to add virtualization support in pynetbox in the near futur ?

pynetbox 3.4.0 breaks on import (probably due to setuptools_scm usage)

Repro inside virtualenv (sorry about the pip spam). I'm pretty sure this is due to 8f83639, but don't know enough about setuptools_scm to quickly submit a patch.

$ pip install pynetbox==3.3.1
Collecting pynetbox==3.3.1
Collecting six==1.11.0 (from pynetbox==3.3.1)
  Using cached https://files.pythonhosted.org/packages/67/4b/141a581104b1f6397bfa78ac9d43d8ad29a7ca43ea90a2d863fe3056e86a/six-1.11.0-py2.py3-none-any.whl
Collecting netaddr==0.7.18 (from pynetbox==3.3.1)
  Using cached https://files.pythonhosted.org/packages/04/9c/46c719f026dc87822ccce2530049f3c0865e85307b7ab50beb28008e10c0/netaddr-0.7.18-py2.py3-none-any.whl
Collecting requests==2.10.0 (from pynetbox==3.3.1)
  Using cached https://files.pythonhosted.org/packages/99/b4/63d99ba8e189c47d906b43bae18af4396e336f2b1bfec86af31efe2d2cb8/requests-2.10.0-py2.py3-none-any.whl
Installing collected packages: six, netaddr, requests, pynetbox
Successfully installed netaddr-0.7.18 pynetbox-3.3.1 requests-2.10.0 six-1.11.0
You are using pip version 7.1.2, however version 10.0.1 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.

$ python -c 'import pynetbox'

$ pip install pynetbox==3.4.0
Collecting pynetbox==3.4.0
Requirement already satisfied (use --upgrade to upgrade): six==1.* in ./lib/python2.7/site-packages (from pynetbox==3.4.0)
Requirement already satisfied (use --upgrade to upgrade): netaddr==0.* in ./lib/python2.7/site-packages (from pynetbox==3.4.0)
Collecting setuptools-scm==2.* (from pynetbox==3.4.0)
  Downloading https://files.pythonhosted.org/packages/4d/a0/371355cbd608ef1d865738b94f7681e2fe56ef951070a66a892f30042a86/setuptools_scm-2.1.0-py2.py3-none-any.whl
Requirement already satisfied (use --upgrade to upgrade): requests==2.* in ./lib/python2.7/site-packages (from pynetbox==3.4.0)
Installing collected packages: setuptools-scm, pynetbox
  Found existing installation: pynetbox 3.3.1
    Uninstalling pynetbox-3.3.1:
      Successfully uninstalled pynetbox-3.3.1
Successfully installed pynetbox-0.0.0 setuptools-scm-2.1.0
You are using pip version 7.1.2, however version 10.0.1 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.

$ python -c 'import pynetbox'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/Users/mgokhale/sandbox/pynetbox-bug/lib/python2.7/site-packages/pynetbox/__init__.py", line 6, in <module>
    __version__ = get_version(root='..', relative_to=__file__)
  File "/Users/mgokhale/sandbox/pynetbox-bug/lib/python2.7/site-packages/setuptools_scm/__init__.py", line 119, in get_version
    parsed_version = _do_parse(root, parse)
  File "/Users/mgokhale/sandbox/pynetbox-bug/lib/python2.7/site-packages/setuptools_scm/__init__.py", line 97, in _do_parse
    "use git+https://github.com/user/proj.git#egg=proj" % root)
LookupError: setuptools-scm was unable to detect version for '/Users/mgokhale/sandbox/pynetbox-bug/lib/python2.7/site-packages'.

Make sure you're either building from a fully intact git repository or PyPI tarballs. Most other sources (such as GitHub's tarballs, a git checkout without the .git folder) don't contain the necessary metadata and will not work.

For example, if you're using pip, instead of https://github.com/user/proj/archive/master.zip use git+https://github.com/user/proj.git#egg=proj

full_details doesn't add token

I'm using pynetbox version 3.0.1 and netbox with LOGIN_REQUIRED = True and I see the following behaviour:

import requests
import logging
from pprint import pprint

# These two lines enable debugging at httplib level (requests->urllib3->http.client)
# You will see the REQUEST, including HEADERS and DATA, and RESPONSE with HEADERS but without DATA.
# The only thing missing will be the response.body which is not logged.
try:
    import http.client as http_client
except ImportError:
    # Python 2
    import httplib as http_client
http_client.HTTPConnection.debuglevel = 1

# You must initialize logging, otherwise you'll not see debug output.
logging.basicConfig()
logging.getLogger().setLevel(logging.DEBUG)
requests_log = logging.getLogger("requests.packages.urllib3")
requests_log.setLevel(logging.DEBUG)
requests_log.propagate = True

url = 'https://netbox.example.com'
token = 'abcdefghijklmnopqrstuvwxyz'

try:
    import pynetbox
    from netaddr import *
except ImportError, e:
    sys.exit("Please install required python modules: pynetbox netaddr")

try:
    netbox = pynetbox.api(url, token=token)
except AttributeError:
    sys.exit("Failed to connect to netbox instance")

for host in netbox.virtualization.virtual_machines.filter(status=1):
    pprint(host)
    pprint(vars(host))
INFO:requests.packages.urllib3.connectionpool:Starting new HTTPS connection (1): netbox.example.net
send: 'GET /api/ HTTP/1.1\r\nHost: netbox.example.net\r\nConnection: keep-alive\r\nAccept-Encoding: gzip, deflate\r\nAccept: */*\r\nUser-Agent: python-requests/2.10.0\r\n\r\n'
reply: 'HTTP/1.1 200 OK\r\n'
header: Server: nginx/1.10.3 (Ubuntu)
header: Date: Wed, 07 Feb 2018 09:38:23 GMT
header: Content-Type: application/json
header: Content-Length: 353
header: Connection: keep-alive
header: Allow: GET, HEAD, OPTIONS
header: X-Frame-Options: SAMEORIGIN
header: API-Version: 2.2
header: Vary: Accept, Cookie
header: P3P: CP="ALL DSP COR PSAa PSDa OUR NOR ONL UNI COM NAV"
header: X-Cache-Status: MISS
DEBUG:requests.packages.urllib3.connectionpool:"GET /api/ HTTP/1.1" 200 353

INFO:requests.packages.urllib3.connectionpool:Starting new HTTPS connection (1): netbox.example.net
send: 'GET /api/virtualization/virtual-machines/?status=1 HTTP/1.1\r\nHost: netbox.example.net\r\nConnection: keep-alive\r\nAccept-Encoding: gzip, deflate\r\naccept: application/json; version=2.2;\r\nUser-Agent: python-requests/2.10.0\r\nauthorization: Token abcdefghijklmnopqrstuvwxyz\r\n\r\n'
reply: 'HTTP/1.1 200 OK\r\n'
header: Server: nginx/1.10.3 (Ubuntu)
header: Date: Wed, 07 Feb 2018 09:38:23 GMT
header: Content-Type: application/json
header: Content-Length: 2687
header: Connection: keep-alive
header: Allow: GET, POST, HEAD, OPTIONS
header: X-Frame-Options: SAMEORIGIN
header: API-Version: 2.2
header: Vary: Accept, Cookie
header: P3P: CP="ALL DSP COR PSAa PSDa OUR NOR ONL UNI COM NAV"
header: X-Cache-Status: MISS
DEBUG:requests.packages.urllib3.connectionpool:"GET /api/virtualization/virtual-machines/?status=1 HTTP/1.1" 200 2687
dhcp01-smarket55-sjc

INFO:requests.packages.urllib3.connectionpool:Starting new HTTPS connection (1): netbox.example.net
send: 'GET /api/ipam/ip-addresses/91/ HTTP/1.1\r\nHost: netbox.example.net\r\nConnection: keep-alive\r\nAccept-Encoding: gzip, deflate\r\naccept: application/json; version=2.2;\r\nUser-Agent: python-requests/2.10.0\r\n\r\n'
reply: 'HTTP/1.1 403 Forbidden\r\n'
header: Server: nginx/1.10.3 (Ubuntu)
header: Date: Wed, 07 Feb 2018 09:38:24 GMT
header: Content-Type: application/json
header: Content-Length: 58
header: Connection: keep-alive
header: Allow: GET, PUT, PATCH, DELETE, HEAD, OPTIONS
header: X-Frame-Options: SAMEORIGIN
header: API-Version: 2.2
header: Vary: Accept, Cookie
DEBUG:requests.packages.urllib3.connectionpool:"GET /api/ipam/ip-addresses/91/ HTTP/1.1" 403 58
Traceback (most recent call last):
  File "bug.py", line 38, in <module>
    pprint(vars(host))
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pprint.py", line 59, in pprint
    printer.pprint(object)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pprint.py", line 117, in pprint
    self._format(object, self._stream, 0, 0, {}, 0)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pprint.py", line 140, in _format
    rep = self._repr(object, context, level - 1)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pprint.py", line 226, in _repr
    self._depth, level)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pprint.py", line 238, in format
    return _safe_repr(object, context, maxlevels, level)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pprint.py", line 282, in _safe_repr
    vrepr, vreadable, vrecur = saferepr(v, context, maxlevels, level)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pprint.py", line 323, in _safe_repr
    rep = repr(object)
  File "/Library/Python/2.7/site-packages/pynetbox/lib/response.py", line 103, in __repr__
    return str(self)
  File "/Library/Python/2.7/site-packages/pynetbox/lib/response.py", line 97, in __str__
    getattr(self, 'name', None) or
  File "/Library/Python/2.7/site-packages/pynetbox/lib/response.py", line 77, in __getattr__
    if self.full_details():
  File "/Library/Python/2.7/site-packages/pynetbox/lib/response.py", line 176, in full_details
    self._parse_values(req.get())
  File "/Library/Python/2.7/site-packages/pynetbox/lib/query.py", line 215, in get
    return req_all(self.url)
  File "/Library/Python/2.7/site-packages/pynetbox/lib/query.py", line 197, in req_all
    req = make_request(url)
  File "/Library/Python/2.7/site-packages/pynetbox/lib/query.py", line 194, in make_request
    raise RequestError(req)
pynetbox.lib.query.RequestError: The request failed with code 403 Forbidden

As you can see, the third request to /ipam/ is missing the auth token. My guess is that it's missing because we don't forward it here: https://github.com/digitalocean/pynetbox/blob/master/pynetbox/lib/response.py#L172

List device_role and all other attributes of an endpoint

I can see that there is no function that returns the "attributes" of an endpoint.

For example, with nb.dcim.devices.all(), I do get all the devices by their name.
But what if I need something more specific like device_role?

This is implemented only when creating a device, where device_role is set, but after that I can not seem to be able to retrieve it somehow.

Am I correct?

If yes, will this functionality be added?

My thought for this was, to use e.g. a "show_details" function/API call to get the device role (or any other of the "facts") and then use the nb.dcim.device.filter(role=) to get a dict with the specific role.

Thanks.

how to get all the ips, their associated mac address and the device id

hello I want to get all the ip addresses , and their associated mac addresses and the device id.

When i try to get mac address associated with the Ip address I get this -

nb = pynetbox.api('http://centos7client.example.com',token='fhjskh5jk435j3khkl')

ip_addresses = nb.ipam.ip_addresses.all()
mac_adderess = ip_addresses[7].interface.mac_address
print(mac_adderess)

mac_adderess = ip_addresses[7].interface.mac_address

AttributeError: 'NoneType' object has no attribute 'mac_address'

dcim.devices.all() truncated

Hey!

It seems that dcim.devices.all() returns a truncated list of devices.
There are 1209 devices at my netbox.
dcim.devices.all() returns only 1050

v2.3.4 of NetBox adds an extra backslash ("/") between hostname and URL

Issue type

[X] Bug report

Environment

  • Python version: 3.5
  • NetBox version: 2.3.4
  • PyNetBox version: 3.3.1

Description

Using pynetbox querying against an instance of NetBox running v2.3.3 works fine.
However, when I switch the URL to an instance of NetBox running v2.3.4, it stops working.

The details and code for each version are below (the same exact data is in both versions of NetBox).


(v2.3.3)

>>> try:
...     nb.dcim.sites.get(slug='0am')
... except pynetbox.lib.query.RequestError as e:
...     print(e.req.url)
...
0am

(v2.3.4)

>>> try:
...     nb.dcim.sites.get(slug='0am')
... except pynetbox.lib.query.RequestError as e:
...     print(e)
...
The request failed with code 404 Not Found
>>> try:
...     nb.dcim.sites.get(slug='0am')
... except pynetbox.lib.query.RequestError as e:
...     print(e.req.url)
...
http://myhost:8080//api/dcim/sites/?slug=0am

Notice the extra / between the hostname and the rest of the URL?
I'm close to positive that is what is causing the issue.
However, when using the SwaggerUI and performing the same action via a PUT request, no issues.
So I'm not sure if the error exists in NetBox since that is what changed or pynetbox since everything else in v2.3.4 works fine.

Add support for NAPALM methods

This could already exist, but as I was poking around, I didn't see the function call where I expected it would be. Basically, I'm trying to use pynetbox to do something like the following REST API call:

curl -X GET -H "Accept: application/json; indent=2" -H "Authorization: Token [REMOVED]" "http://netbox.local/api/dcim/devices/20/napalm/?method=get_facts"

While poking around and doing a dir(dev1) in the python interpreter (where dev1 has theid=20 in the API call above) and all I saw was the following:

>>> dir(dev1)
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattr__', '__getattribute__', '__getitem__', '__getstate__', '__hash__', '__init__', '__iter__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_add_cache', '_compare', '_full_cache', '_index_cache', '_parse_values', 'api_kwargs', 'asset_tag', 'cluster', 'comments', 'created', 'custom_fields', 'default_ret', 'delete', 'device_role', 'device_type', 'display_name', 'endpoint_meta', 'face', 'full_details', 'has_details', 'id', 'last_updated', 'name', 'parent_device', 'platform', 'position', 'primary_ip', 'primary_ip4', 'primary_ip6', 'rack', 'save', 'serial', 'serialize', 'site', 'status', 'tenant', 'url', 'vc_position', 'vc_priority', 'virtual_chassis']

Anyways, I suppose my question boils down to the following...

  1. Is NAPALM already supported?
  2. If so, where should I be looking at (instead of the location above)?
  3. If not, could I request that it be added in the near future?

Thanks again for this library (and NetBox too)!

pip errors on new version of netaddr

When doing a pip install pynetbox, I've been getting the following recently:

pynetbox 3.3.1 has requirement netaddr==0.7.18, but you'll have netaddr 0.7.19 which is incompatible.

Forcing the netaddr version by doing pip install netaddr==0.7.18 works fine.

Probably just need a version bump for requirements.

Results seem to be limited at 1050 records

I've noticed when getting an endpoint result with an expected 4090 results (netbox UI indicates the expected record count), but seem to only be getting 1050 records.

This is happening on nb.dcim.devices, with either a filter(site_id=<>) or .all(). I have not tested other endpoints, but I imagine its a limit imposed by the netbox api?

Its logical to have some sort of limit and to return paginated results, but I can't find anything in the documentation regarding fetching the next batches of results etc.

Is there currently a way with pynetbox to handle this situation?

how does patch() work

Hi,

I try to update interfaces to had lag id.

I have seen that patch-) method is created but i don't know how to use it.

Anyone can tell me ?

Unable to retrieve available-ips

Trying to list all available IP's using this module is not working

if __name__ == "__main__":
    nb = pynetbox.api(URL, TOKEN)
    testing_this = nb.ipam.prefixes.available_ips.get(70)
    print testing_this

returns

Traceback (most recent call last):
  File "netboxtest.py", line 44, in <module>
    testing_this = nb.ipam.prefixes.available_ips.get(70)
AttributeError: 'Endpoint' object has no attribute 'available_ips'

whereas

testing_this = nb.ipam.prefixes.get(70)

Returns the expected subnet.

pynetbox ssl validation should be configurable

As TLS certs, particularly in test pipelines, may be generated from private CAs or self-signed, pynetbox should allow for not verifying SSL certs, if explicitly set to do so. The current behavior uses Requests' default, which is to require a valid cert and fail if it cannot be verified.

Is PUT don't work and PATCH not available in pynetbox?

It looks like using HTTL requestes, we can do PUT as well as POST on an object (looking at the swagger api docs). However, I am trying to do the following:

  1. I am trying to create a virtual machine.
  2. Add an interface to the created VM.
  3. Add an IP Address to the interface that we just created.

I am using the netbox version 2.2.8 and pynetbox 3.0.1

Any help is appreciated. Any way that would work other than this is also good.

the first and seconds steps, I got through somehow. [The documentation is pretty sparse and I don't know how to use or modify]. I am trying to use the PUT for the third step...but it is failing.

[root@lab-linux ~]# python netbox_python.py
<pynetbox.api.Api object at 0x2a12d50>
<pynetbox.api.App object at 0x2a12e90>
obj_name from Endpoint class Vrfs
ret value is: <class 'pynetbox.lib.response.IPRecord'>
vrf_obj is : 3
obj_name from Endpoint class IpAddresses
ret value is: <class 'pynetbox.ipam.IpAddresses'>
Traceback (most recent call last):
  File "netbox_python.py", line 11, in <module>
    nb.ipam.ip_addresses.put(address='11.11.11.11/24',status=1,vrf_id=vrf_obj.id,virtual_machine_id=6,interface_id=25)
AttributeError: 'Endpoint' object has no attribute 'put'

I have My code like the below.

import pynetbox

vm_name='vm1'

nb = pynetbox.api('http://xx.xx.xx.xx:8000', token='xxxxxxxxxxxxxxxxx')

print nb

vrf_obj=nb.ipam.vrfs.get(name='test')
print "vrf_obj is : %s" %vrf_obj.id

nb.virtualization.virtual_machines.create(name=vm_name,status=1,cluster='1')


vm_obj = nb.virtualization.virtual_machines.get(name=var_name)

if vm_obj != None:
    nb.virtualization.interfaces.create(virtual_machine=vm_obj.id,name='eth1')
else:
    print "vm with the given name doesn't exists in the netbox inventory."


nb.ipam.ip_addresses.create(address='11.11.11.11/24',status=1,vrf_id=vrf_obj.id)

#Assign the IP ADDR to the interface on the vm

nb.ipam.ip_addresses.put(address='11.11.11.11/24',status=1,vrf_id=vrf_obj.id,virtual_machine_id=6,interface_id=25)
#print ip_obj

quit()

Uncaught exception when parsing address attributes with certain formats

Right up front, this is really arguably netaddr problem, but their core issue may be harder to fix, and it's fixable here.

It appears that if an IP's fields contain a string that matches a certain pattern, netaddr.IPNetwork mistakes it for CIDR and attempts to parse it, but fails as it's not really valid CIDR, which produces an unexpected exception.

You should be able to replicate this by, for example, adding a description to an IP that triggers this problem (which is how we found it, with a circuit ID containing slashes in the description field). Presumably, this would work on any field that takes text strings.

We set an IP's decription to 22/XXXX/111111//XY

Here's the actual exception:

Traceback (most recent call last):
  File "/usr/local/opt/python/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/netaddr/ip/__init__.py", line 799, in parse_ip_network
    prefixlen = int(val2)
ValueError: invalid literal for int() with base 10: 'XXXX/111111//XY''

And here is replicating it with plain python3:

>>> import netaddr
>>> netaddr.IPNetwork('22/XXXX/111111//XY')
Traceback (most recent call last):
  File "/usr/local/opt/python/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/netaddr/ip/__init__.py", line 799, in parse_ip_network
    prefixlen = int(val2)
ValueError: invalid literal for int() with base 10: 'XXXX/111111//XY'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/opt/python/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/netaddr/ip/__init__.py", line 924, in __init__
    implicit_prefix, flags)
  File "/usr/local/opt/python/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/netaddr/ip/__init__.py", line 806, in parse_ip_network
    mask = IPAddress(val2, module.version, flags=INET_PTON)
  File "/usr/local/opt/python/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/netaddr/ip/__init__.py", line 280, in __init__
    % self.__class__.__name__)
ValueError: IPAddress() does not support netmasks or subnet prefixes! See documentation for details.

After digging around, I narrowed it down to the _parse_values method in IPRecord, wherein, the IP record's fields are parsed to create object attributes, which includes this, where fields that are detected as strings are passed as args to netaddr.IPNetwork()

                if isinstance(v, six.string_types):
                    try:
                        v = netaddr.IPNetwork(v)
                    except netaddr.AddrFormatError:
                        pass

Perhaps just catch ValueErrors as well?

nb.circuits.circuit_terminations.create does not create

fields = {"site": 1, "interface": 63648, "term_side": "A", "circuit": 747, "port_speed": 10000000}
nb.circuits.circuit_terminations.create(**fields)
returns just existing terminations but does not add new one

This works perfectly fine
curl -X POST "https://ipam1-staging.snc1/api/circuits/circuit-terminations/" -H "accept: application/json" -H "Content-Type: application/json" -H "X-CSRFToken: sometoken" -d "{"site": 1, "interface": 63648, "term_side": "A", "circuit": 747, "port_speed": 10000000}"

Error While Creating a range prefix.available_ips.create([{} for i in range(2)])

When I try to create a range of available ips, I get a 500 internal server error.

Here is the output:

>>> nb = pynetbox.api(url=url,token=token)
>>> prefix = nb.ipam.prefixes.get(q='10.10.10.0/24')
>>> prefix
10.10.10.0/24
>>> prefix.available_ips.create([{} for i in range(2)])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/davidg/Library/Python/2.7/lib/python/site-packages/pynetbox/lib/endpoint.py", line 364, in create
    return Request(**self.request_kwargs).post(data)
  File "/Users/davidg/Library/Python/2.7/lib/python/site-packages/pynetbox/lib/query.py", line 297, in post
    raise RequestError(req)
pynetbox.lib.query.RequestError: The request failed with code 500 Internal Server Error
>>> prefix.available_ips.create()
{u'status': 1, u'description': u'', u'nat_inside': None, u'role': None, u'vrf': None, u'address': u'10.10.10.13/24', u'interface': None, u'id': 12740, u'tenant': None}
>>>

Netbox Version (v2.2.6)

The __version__ variable should be set on package installation.

As is, the library attempts to read a text file (VERSION) when it is loaded. If pynetbox is packaged in a ZIP archive, or synced using SaltStack's saltutil.sync_modules, this file is unavailable.

This change would make it easier to ship pynetbox as a dependency.

Getting Error for Time Zone Required When Updating Site

Issue type

[X] Bug report

Environment

  • Python version: 3.5.2
  • NetBox version: 2.3.3
  • PyNetBox version: 3.3.0

Description

When updating an existing site via the WebUI, the field Time Zone is not required (see screenshot A).
The same is true for using the SwaggerUI (see screenshot B for patch & C for response).

However, when you try the same thing using the pynetbox code:

nb_site.status = 1    
nb_site.description = "string"
nb_site.custom_fields['reso_id'] = bgp_comm

try:
    nb_site.save()
    nb_updated_sites.append(nb_site.name)
except pynetbox.lib.query.RequestError as e:
    print("Failed due to:\n    {}".format(e.error))

The following error is recieved:

Failed due to:
    {"time_zone":["This field may not be null."]}

When time_zone is ADDED to the code:

nb_site.status = 1    
nb_site.description = "string"
nb_site.custom_fields['reso_id'] = bgp_comm
nb_site.time_zone = 'UTC'

try:
    nb_site.save()
    nb_updated_sites.append(nb_site.name)
except pynetbox.lib.query.RequestError as e:
    print("Failed due to:\n    {}".format(e.error))

No errors are returned!


Screenshot A:
image


Screenshot B:
image


Screenshot C:
image

Documentation Isn't Accurate

I'm trying to use the examples from pynetbox, but the examples are very inconsistent.

It appears to be a mixture of the API from NetBox v1.x and 2.x but I can't seem to make any sense out of it. (See code under heading of filter at the URL /en/latest/endpoint.html)

For example, I think that

nb.devices.filter(role='leaf-switch')

should be

nb.dcim.devices.filter(role='leaf-switch')

Also, I have a feeling that it might be due to the release of pynetbox v3.0.0 that caused this documentation error. I'm wondering if it would be possbible to still be able to view the documentation for previous versions of pynetbox until this is resolved?

Error when attempting to update the details of a Site with no changes.

Issue type

[X] Bug report

Environment

  • Python version: 3.5
  • NetBox version: 2.3.3
  • PyNetBox version: 3.3.1

Description

When attempting to update the details of an object within the model dcim.sites without any changes, I get the following HTML error:

int() argument must be a string, a bytes-like object or a number, not &#39;dict&#39;

If I manually change a single character in any of the fields using the WebUI of NetBox and re-run the same pynetbox code, everything is updated perfectly.

This is the actual cause of issue #60, not the "odd characters" that was previously mentioned.
I can perform the same action (sending data that is the same) using curl via a PUT without any issues.

However, whenever the nb_site.save() is called with no actual changes to the object, the above error is given.
This is especially difficult to handle, because the error isn't a pynetbox.lib.query.RequestError which I catch, but a generic server error.

I will close the other issue shortly once this gets assigned an issue number.

Issue with updating 'sites' with odd characters in values

Issue type

[X] Bug report

Environment

  • Python version: 3.5
  • NetBox version: 2.3.3
  • PyNetBox version: 3.3.1

Description

I'm able to create new sites using pynetbox with the method nb.dcim.sites.create(**data) and data including all of the required fields such as name, slug, status, and region(that last one isn't technically "required", but I'm using it nonetheless).

However, when I try to update existing sites with the following code:

nb_site = nb.dcim.sites.get(name="00j")
nb_site.physical_address = "C/ SAKURA, 8\nSAN FRUITÒS DEL BALGÈS, B, 08202, ES"
nb_site.save()

I get the following HTML error:

int() argument must be a string, a bytes-like object or a number, not &#39;dict&#39;

I can do the same action with a curl request just fine (sent via a PUT to /api/dcim/sites/434/):

{
  "name": "00j",
  "slug": "00j",
  "status": 1,
  "physical_address": "C/ SAKURA, 8\nSAN FRUITÒS DEL BALGÈS, B, 08202, ES"
}

Results in this response:

{
  "id": 434,
  "name": "00j",
  "slug": "00j",
  "status": 1,
  "region": 375,
  "tenant": null,
  "facility": "",
  "asn": null,
  "time_zone": "Europe/Madrid",
  "description": "WHOIS details were updated on 'June 06 2018 22:32:54 UTC'",
  "physical_address": "C/ SAKURA, 8\nSAN FRUITÒS DEL BALGÈS, B, 08202, ES",
  "shipping_address": "",
  "contact_name": "",
  "contact_phone": "",
  "contact_email": "",
  "comments": "",
  "custom_fields": {},
  "created": "2018-06-07",
  "last_updated": "2018-06-07T06:57:56.860491Z"
}

At first I thought it was due to an issue with the "odd" characters in the physical_address, but it appears to be more widespread than that (even values without the "odd" characters appears to also fail). Perhaps I'm doing something obviously wrong (wouldn't be the first time), but I'm not quite sure if that is the case in this scenario.

If you need further information from me, please let me know.

interfaces.get: raise ValueError get() returned more than one result

Environment: pynetbox (3.2.0)

  • device with just eth0:
>>> nbmovile.dcim.interfaces.get(device='alog10')
eth0
  • device with eth0 and eth1:
>>> nbmovile.dcim.interfaces.get(device='mcloud8')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.5/dist-packages/pynetbox/lib/endpoint.py", line 161, in get
    raise ValueError('get() returned more than one result.')
ValueError: get() returned more than one result.

Provide More Details on 'pynetbox.lib.query.RequestError'

I've been able to use the pynetbox library to develop some logic to begin to import data from all of the different sources of information that my company uses (i.e. Infoblox DNS/DHCP servers, billing databases, NetBrain, etc). Thanks for making this library which makes this process relatively easy.

One problem that I keep running into again and again is that when the request isn't formatted correctly or a required custom_field is not provided, the same error is returned no matter what: The request failed with code 400 Bad Request.

Not being a python expert, I'd like to know if is would be possible at all to reveal the specific details of the pynetbox.lib.query.RequestError similar to the way that the direct API within NetBox does, such as the following (the output below has been scrubbed):

{
  "non_field_errors": [
    "Duplicate prefix found in VRF red (100:100): 10.0.136.0/23"
  ]
}

It is entirely possible this functionality already exists, but I couldn't seem to find the documentation on how to access this information if that is the case.

Thanks again for this great library.

Can't lookup values for nested objects

Hi,

Thanks for the very nice API.

I've ran into some glict, I've reproduced this on two separate systems with pynetbox 2.0.5 and netbox 2.1.3/2.1.4

For interfaces with interface connection or circuit connections, running serialize() on the object fails, most likely due to some issue to gather certain attributes for the object:

nb.dcim.interfaces.get(2).interface_connection
Traceback (most recent call last):
File "", line 1, in
File "/home/oysteigy/pynetbox/lib/python2.7/site-packages/pynetbox/lib/response.py", line 83, in repr
return str(self)
File "/home/oysteigy/pynetbox/lib/python2.7/site-packages/pynetbox/lib/response.py", line 80, in str
return self.name or ''
File "/home/oysteigy/pynetbox/lib/python2.7/site-packages/pynetbox/lib/response.py", line 66, in getattr
raise AttributeError('object has no attribute "{}"'.format(k))
AttributeError: object has no attribute "name"

Looks ok in the database(?)

netbox=# select * from dcim_interfaceconnection where interface_a_id = 2 OR interface_b_id = 2;
id | connection_status | interface_a_id | interface_b_id
----+-------------------+----------------+----------------
1 | t | 2 | 1

Same error for serialize()

nb.dcim.interfaces.get(2).serialize()
Traceback (most recent call last):
File "", line 1, in
File "/home/oysteigy/pynetbox/lib/python2.7/site-packages/pynetbox/lib/response.py", line 175, in serialize
current_val = current_val.value
File "/home/oysteigy/pynetbox/lib/python2.7/site-packages/pynetbox/lib/response.py", line 66, in getattr
raise AttributeError('object has no attribute "{}"'.format(k))
AttributeError: object has no attribute "value"

Looks like this only occurs for interfaces with "circuit_termination" or "interface_connection" set.

nb.dcim.interfaces.get(4).serialize()
{u'lag': None, u'mgmt_only': True, u'name': u'Vlan1337', u'mac_address': None, u'enabled': True, u'circuit_termination': None, u'mtu': None, u'interface_connection': None, u'form_factor': 0, u'device': 3, u'is_connected': False, u'id': 4, u'description': u''}

Add support for deleting objects

I can't find any support for deleting objects on a endpoint. I found in the api docs for netbox itself that it is supported so it would be great if pynetbox would support this feature as well.

Python 3 support (unicode is replaced by str and str is replaced by bytes)

Hi,

I am running python3 and run into an issue with this library.
Traceback (most recent call last):
File "test.py", line 6, in
conn_nb.dcim.devices.all()
File "/usr/lib/python3.4/site-packages/pynetbox/lib/endpoint.py", line 119, in all
for i in req.get()
File "/usr/lib/python3.4/site-packages/pynetbox/lib/endpoint.py", line 119, in
for i in req.get()
File "/usr/lib/python3.4/site-packages/pynetbox/lib/response.py", line 63, in init
self._parse_values(values)
File "/usr/lib/python3.4/site-packages/pynetbox/lib/response.py", line 129, in _parse_values
v = lookup(v, api_kwargs=self.api_kwargs)
File "/usr/lib/python3.4/site-packages/pynetbox/lib/response.py", line 269, in init
super(IPRecord, self).init(*args, **kwargs)
File "/usr/lib/python3.4/site-packages/pynetbox/lib/response.py", line 63, in init
self._parse_values(values)
File "/usr/lib/python3.4/site-packages/pynetbox/lib/response.py", line 297, in _parse_values
if isinstance(v, (str, unicode)):
NameError: name 'unicode' is not defined

I checked and unicode no longer exists and is replaced by str and str is replaced by bytes in python 3.

Based on my very limited knowledge of python I would suggest something like:
if sys.version_info.major < 3:
if isinstance(v, (str, unicode)):
else:
if isinstance(v, (bytes, str)):

Some attributes can't be used as arguments for filter()

Hi,

Thanks (again) for the nice API.

Not a bug per se, more of an feature request. Using pynetbox (2.1.0 / netbox 2.1.4 ), some attributes can't be used as query arguments for model.filter() - despite that Django "permits" it:

This works via nbshell/Django

Interface.objects.filter(device=1, name='gi0')[0].id
1499
lookup ip to interface
IPAddress.objects.filter(interface=1499)[0]
<IPAddress: 10.205.101.43/25>

pynetbox will return the entire dataset for the same query

nb.dcim.interfaces.filter(id=1,name='gi0')[0].id
1499
nb.ipam.ip_addresses.filter(interface=1499)

Returns all IPaddresses

nb.ipam.ip_addresses.filter(description='FOO')

Returns all IPaddresses

This works as expected however:

nb.ipam.ip_addresses.filter(family=6)
nb.ipam.ip_addresses.filter(status=3)
nb.ipam.ip_addresses.filter('10.0.0.0/32')

pynetbox should support patching

Using pynetbox, we quickly ran into scenarios where we needed to bulk-update a resource from a python dict or similar multi-value source. But, we noticed that there didn't seem to be PATCH support, nor a way to update a resource, aside from updating an object's attributes one by one, then calling save().

It would be extremely useful to be able to do two things:

  1. Update a resource, given an ID and update data, without previously fetching it as an object, i.e.
netbox.dcim.devices.update(1, {'key': 'value', 'otherkey': 'othervalue'})
  1. Update a retrieved object with a dict
dev = netbox.dcim.devices.get(1)
dev.update({'key': 'value', 'otherkey': 'othervalue'})
dev.save()

get primary_ip incorrectly formatted url when using virtualization

Hi,

I have one device (test1), and one virtual machine (test2). Both entities have an ip address bound in the GUI.

I have instantiated netbox:

nb = pynetbox.api(
    'https://netbox.domain.tld',
    token='xxxxxxx',
)

I try loading the id and primary_ip from the device:

>>> nb.dcim.devices.get(name='test1').id                                                                                                                                                                  
43
>>> nb.dcim.devices.get(name='test1').primary_ip
10.0.12.15/27

I then proceeded to do the same for the virtual machine,

>>> nb.virtualization.virtual_machines.get(name='test2').id        
2
>>> nb.virtualization.virtual_machines.get(name='test2').primary_ip
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/jord/.virtualenvs/netbox/lib64/python3.6/site-packages/pynetbox/lib/response.py", line 103, in __repr__
    return str(self)
  File "/home/jord/.virtualenvs/netbox/lib64/python3.6/site-packages/pynetbox/lib/response.py", line 97, in __str__
    getattr(self, 'name', None) or
  File "/home/jord/.virtualenvs/netbox/lib64/python3.6/site-packages/pynetbox/lib/response.py", line 77, in __getattr__
    if self.full_details():
  File "/home/jord/.virtualenvs/netbox/lib64/python3.6/site-packages/pynetbox/lib/response.py", line 178, in full_details
    self._parse_values(req.get())
  File "/home/jord/.virtualenvs/netbox/lib64/python3.6/site-packages/pynetbox/lib/query.py", line 216, in get
    
  File "/home/jord/.virtualenvs/netbox/lib64/python3.6/site-packages/pynetbox/lib/query.py", line 198, in req_all
    def req_all(url):
  File "/home/jord/.virtualenvs/netbox/lib64/python3.6/site-packages/pynetbox/lib/query.py", line 190, in make_request
    
  File "/home/jord/.virtualenvs/netbox/lib64/python3.6/site-packages/requests/api.py", line 72, in get
    return request('get', url, params=params, **kwargs)
  File "/home/jord/.virtualenvs/netbox/lib64/python3.6/site-packages/requests/api.py", line 58, in request
    return session.request(method=method, url=url, **kwargs)
  File "/home/jord/.virtualenvs/netbox/lib64/python3.6/site-packages/requests/sessions.py", line 508, in request
    resp = self.send(prep, **send_kwargs)
  File "/home/jord/.virtualenvs/netbox/lib64/python3.6/site-packages/requests/sessions.py", line 640, in send
    history = [resp for resp in gen] if allow_redirects else []
  File "/home/jord/.virtualenvs/netbox/lib64/python3.6/site-packages/requests/sessions.py", line 640, in <listcomp>
    history = [resp for resp in gen] if allow_redirects else []
  File "/home/jord/.virtualenvs/netbox/lib64/python3.6/site-packages/requests/sessions.py", line 218, in resolve_redirects
    **adapter_kwargs
  File "/home/jord/.virtualenvs/netbox/lib64/python3.6/site-packages/requests/sessions.py", line 618, in send
    r = adapter.send(request, **kwargs)
  File "/home/jord/.virtualenvs/netbox/lib64/python3.6/site-packages/requests/adapters.py", line 508, in send
    raise ConnectionError(e, request=request)
requests.exceptions.ConnectionError: HTTPSConnectionPool(host='netbox.bahnhof.netapi', port=443): Max retries exceeded with url: /ipam/ip-addresses/1715/ (Caused by NewConnectionError('<urllib3.connection.VerifiedHTTPSConnection object at 0x7fabf52556a0>: Failed to establish a new connection: [Errno -2] Name or service not known',))

The param "host='netbox.domain.tldapi'" looks rather suspicious, but I fail to understand why it would be different when using the virtualization object, and even differently between the .id and .primary_ip attribute inside that object. Does anybody understand this better than I?

python2.6: ValueError: zero length field name in format

Hello,

Is pynetbox supposed to work with python2.6 (CentOS6?)

example:

  • install:
[tiago.cruz@mordor env]$ pip install pynetbox
Collecting pynetbox
Collecting netaddr==0.7.18 (from pynetbox)
  Using cached https://files.pythonhosted.org/packages/04/9c/46c719f026dc87822ccce2530049f3c0865e85307b7ab50beb28008e10c0/netaddr-0.7.18-py2.py3-none-any.whl
Collecting requests==2.10.0 (from pynetbox)
  Using cached https://files.pythonhosted.org/packages/99/b4/63d99ba8e189c47d906b43bae18af4396e336f2b1bfec86af31efe2d2cb8/requests-2.10.0-py2.py3-none-any.whl
Collecting six==1.11.0 (from pynetbox)
  Using cached https://files.pythonhosted.org/packages/67/4b/141a581104b1f6397bfa78ac9d43d8ad29a7ca43ea90a2d863fe3056e86a/six-1.11.0-py2.py3-none-any.whl
Installing collected packages: netaddr, requests, six, pynetbox
Successfully installed netaddr-0.7.18 pynetbox-3.3.1 requests-2.10.0 six-1.11.0
  • Try to use
[tiago.cruz@mordor env]$ python
Python 2.6.6 (r266:84292, Aug 18 2016, 15:13:37) 
[GCC 4.4.7 20120313 (Red Hat 4.4.7-17)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import pynetbox
>>> nb = pynetbox.api(
...     'http://netbox.acme.com',
...     token='xd6xf3x2dx987x70x4xf'
... )
Traceback (most recent call last):
  File "<stdin>", line 3, in <module>
  File "/tmp/teste/env/lib/python2.6/site-packages/pynetbox/api.py", line 88, in __init__
    base_url = "{}/api".format(url)
ValueError: zero length field name in format
>>>

VERSION File not copied while installing from git clone

Hi,

If i use a fresh clone from version 3.0.0 i get an error, that the VERSION File is missing in the installation (with python3). Can this be reproduced by someone?

Traceback (most recent call last):
  File "./create-dhcp-from-netbox.py", line 3, in <module>
    import pynetbox
  File "/usr/lib/python3.6/site-packages/pynetbox-3.0.0-py3.6.egg/pynetbox/__init__.py", line 5, in <module>
    with open(join(dirname(__file__), 'VERSION')) as f:
FileNotFoundError: [Errno 2] No such file or directory: '/usr/lib/python3.6/site-packages/pynetbox-3.0.0-py3.6.egg/pynetbox/VERSION'

If i copy the VERSION file manually to "/usr/lib/python3.6/site-packages/pynetbox-3.0.0-py3.6.egg/pynetbox/lib/" the packages works (beneath the urlencode change, see my pull-request).

regards,
tim

pynetbox failed to post if custom field is selection type

I am getting weird behavior for pynetbox, not sure if this some limitation of pynetbox or something I am doing wrong.

I have a custom field for devices which is selection type.

  • If I remove this custom field, it works
  • If i change custom field value to None, it also works [ using pynetbox or from netbox gui]
  • but when in general, even I am not trying to update it. It fails.

not sure if this netbox problem or pynetbox issue.

To Reproduce

  • add a custom field with selection type having 3-4 selection value.
  • Query device and verify with serialize to see if that custom field is not showing as None
  • if showing None, than make sure to choose some value from netbox GUI.
  • verify that its showing with label and value. something like this 'dev_discover_status': {'label': 'Completed', 'value': 9}
  • update another value d.serial and d.save()
In [1]: import pynetbox
In [2]: netbox = pynetbox.api('https://netbox.local', token=MYTOKEN, ssl_verify=False)
In [3]: d = netbox.dcim.devices.get(name=TEST_DEVICE_NAME)
In [4]: d.serialize()
Out[4]:
{'asset_tag': '0202',
 'cluster': None,
 'comments': '',
 'created': '2018-06-28',
 'custom_fields': {'dev_chassis_type': 'other',
  'dev_depreciation_percent': 25,
  'dev_discover_status': {'label': 'Completed', 'value': 9},
<<Truncate>>
}
In [5] d.serial = '01234'
In [6]: d.save()
---------------------------------------------------------------------------
RequestError                              Traceback (most recent call last)
<ipython-input-6-ad0d43fe2a3d> in <module>()
----> 1 d.save()

~/virtualenv/nv-snmp-env/lib/python3.4/site-packages/pynetbox/lib/response.py in save(self)
    235                     ssl_verify=self.api_kwargs.get('ssl_verify')
    236                 )
--> 237                 if req.put(self.serialize()):
    238                     return True
    239             else:

~/virtualenv/nv-snmp-env/lib/python3.4/site-packages/pynetbox/lib/query.py in put(self, data)
    268             return json.loads(req.text)
    269         else:
--> 270             raise RequestError(req)
    271
    272     def post(self, data):

RequestError: The request failed with code 500 Internal Server Error

How to create interface connections?

Was really hoping this would work.

int_a = nb.dcim.interfaces.get(name='xe-4/0/16', device='BLAHSWITCH')
int_b = nb.dcim.interfaces.get(name='eth3', device='BLAHHOST')
nb.dcim.interface_connections.create(
    interface_a=int_a,
    interface_b=int_b)

It gives:
TypeError: eth3 is not JSON serializable

Any advice on how to create new interface_connections?

The interfaces are loaded just fine, it's the connections I'm stuck on.

v2.2.1

Cant't access ipam.ip-addresses is function name contains dash

Hi,

Nice API, however I've run into a glitch.
Most of the subcontent of ipam works as pr the documentation:

import pynetbox
nb = pynetbox.api('http://localhost:8080',token=token)
nb.ipam.vrfs.all()
[customer1, customer2, cust3]
nb.ipam.prefixes.all()
[10.219.60.0/24, 10.219.60.232/29, 100.0.0.0/24]
nb.ipam.vlans.all()
[L2_PSEUDO_10000]

ip-addresses and vlan-groups does not work however, as Python will errornously interprent the dash.

nb.ipam.ip-addresses.all()
Traceback (most recent call last):
File "", line 1, in
NameError: name 'addresses' is not defined
nb.ipam.vlan-groups.all()
Traceback (most recent call last):
File "", line 1, in
NameError: name 'groups' is not defined

Got the API links from
https://github.com/digitalocean/netbox/blob/develop/netbox/ipam/urls.py

dcim.interfaces.all() object call broken

Hi,

I have instantiated netbox as so:
nb = pynetbox.api( 'https://netbox.domain.tld', token='xxxxxxx', )

When calling pynetbox.dcim.interfaces.all(), I am presented with the following stack trace:
`>>> nb.dcim.interfaces.all()

Traceback (most recent call last):
File "/home/jord/.virtualenvs/netbox/lib64/python3.6/site-packages/requests/packages/urllib3/connection.py", line 142, in _new_conn
(self.host, self.port), self.timeout, **extra_kw)
File "/home/jord/.virtualenvs/netbox/lib64/python3.6/site-packages/requests/packages/urllib3/util/connection.py", line 67, in create_connection
for res in socket.getaddrinfo(host, port, 0, socket.SOCK_STREAM):
File "/usr/lib64/python3.6/socket.py", line 745, in getaddrinfo
for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
socket.gaierror: [Errno -2] Name or service not known

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/home/jord/.virtualenvs/netbox/lib64/python3.6/site-packages/requests/packages/urllib3/connectionpool.py", line 578, in urlopen
chunked=chunked)
File "/home/jord/.virtualenvs/netbox/lib64/python3.6/site-packages/requests/packages/urllib3/connectionpool.py", line 351, in _make_request
self._validate_conn(conn)
File "/home/jord/.virtualenvs/netbox/lib64/python3.6/site-packages/requests/packages/urllib3/connectionpool.py", line 814, in _validate_conn
conn.connect()
File "/home/jord/.virtualenvs/netbox/lib64/python3.6/site-packages/requests/packages/urllib3/connection.py", line 254, in connect
conn = self._new_conn()
File "/home/jord/.virtualenvs/netbox/lib64/python3.6/site-packages/requests/packages/urllib3/connection.py", line 151, in _new_conn
self, "Failed to establish a new connection: %s" % e)
requests.packages.urllib3.exceptions.NewConnectionError: <requests.packages.urllib3.connection.VerifiedHTTPSConnection object at 0x7f92b7eb8f98>: Failed to establish a new connection: [Errno -2] Name or service not known

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/home/jord/.virtualenvs/netbox/lib64/python3.6/site-packages/requests/adapters.py", line 403, in send
timeout=timeout
File "/home/jord/.virtualenvs/netbox/lib64/python3.6/site-packages/requests/packages/urllib3/connectionpool.py", line 623, in urlopen
_stacktrace=sys.exc_info()[2])
File "/home/jord/.virtualenvs/netbox/lib64/python3.6/site-packages/requests/packages/urllib3/util/retry.py", line 281, in increment
raise MaxRetryError(_pool, url, error or ResponseError(cause))
requests.packages.urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='netbox.domain.tldapi', port=443): Max retries exceeded with url: /dcim/interfaces/?limit=1000&offset=1050 (Caused by NewConnectionError('<requests.packages.urllib3.connection.VerifiedHTTPSConnection object at 0x7f92b7eb8f98>: Failed to establish a new connection: [Errno -2] Name or service not known',))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "", line 1, in
File "/home/jord/.virtualenvs/netbox/lib64/python3.6/site-packages/pynetbox/lib/endpoint.py", line 119, in all
for i in req.get()
File "/home/jord/.virtualenvs/netbox/lib64/python3.6/site-packages/pynetbox/lib/query.py", line 227, in get
return req_all(self.url)
File "/home/jord/.virtualenvs/netbox/lib64/python3.6/site-packages/pynetbox/lib/query.py", line 220, in req_all
req = make_request(next_url)
File "/home/jord/.virtualenvs/netbox/lib64/python3.6/site-packages/pynetbox/lib/query.py", line 202, in make_request
req = requests.get(url, headers=headers)
File "/home/jord/.virtualenvs/netbox/lib64/python3.6/site-packages/requests/api.py", line 71, in get
return request('get', url, params=params, **kwargs)
File "/home/jord/.virtualenvs/netbox/lib64/python3.6/site-packages/requests/api.py", line 57, in request
return session.request(method=method, url=url, **kwargs)
File "/home/jord/.virtualenvs/netbox/lib64/python3.6/site-packages/requests/sessions.py", line 475, in request
resp = self.send(prep, **send_kwargs)
File "/home/jord/.virtualenvs/netbox/lib64/python3.6/site-packages/requests/sessions.py", line 606, in send
history = [resp for resp in gen] if allow_redirects else []
File "/home/jord/.virtualenvs/netbox/lib64/python3.6/site-packages/requests/sessions.py", line 606, in
history = [resp for resp in gen] if allow_redirects else []
File "/home/jord/.virtualenvs/netbox/lib64/python3.6/site-packages/requests/sessions.py", line 179, in resolve_redirects
**adapter_kwargs
File "/home/jord/.virtualenvs/netbox/lib64/python3.6/site-packages/requests/sessions.py", line 585, in send
r = adapter.send(request, **kwargs)
File "/home/jord/.virtualenvs/netbox/lib64/python3.6/site-packages/requests/adapters.py", line 467, in send
raise ConnectionError(e, request=request)
requests.exceptions.ConnectionError: HTTPSConnectionPool(host='netbox.domain.tldapi', port=443): Max retries exceeded with url: /dcim/interfaces/?limit=1000&offset=1050 (Caused by NewConnectionError('<requests.packages.urllib3.connection.VerifiedHTTPSConnection object at 0x7f92b7eb8f98>: Failed to establish a new connection: [Errno -2] Name or service not known',))
`

I've tried to look at the data returned for that pagination range, but to my untrained eye I could not find any fields requiring a specifically serialized object much like the IPAddress object issue I struck in #42. I understand these issues might be completely unrelated, I'm only referencing since the stacktrace I am presented with looks much the same.

Would anyone have some ideas of where to start troubleshooting this?

Some urls are not fully urlencoded

We had some trouble with devices that have special chars in their name, such as #. Here's an example:

>>> i =  netbox.dcim.interfaces.get(name='ipmi', device='New TwinU db #2 / D')
>>> i is None
True

The access log looks like this

"GET /api/dcim/interfaces/?name=ipmi&device=New%20TwinU%20db%20 HTTP/1.1"

It's clear the rest of the device name is getting cut off because the # was not encoded.

getting primary ipv4/ipv6 from device

Hello!

I tried to get active primary ip4/ipv6 address from device id, is it possible? I saw it in json output, device id brought primary ip address (both ipv4 and ipv6), but I didn't found any reference how to do it using pynetbox.

This is the example json output :

// 20180217132447
// http://192.168.39.33:8000/api/dcim/devices/3/?format=json

{
  "id": 3,
  "name": "R1U7-4U8N-A",
  "display_name": "R1U7-4U8N-A",
  "device_type": {
    "id": 5,
    "url": "http://192.168.39.33:8000/api/dcim/device-types/5/?format=json",
    "manufacturer": {
      "id": 1,
      "url": "http://192.168.39.33:8000/api/dcim/manufacturers/1/?format=json",
      "name": "Supermicro",
      "slug": "supermicro"
    },
    "model": "F618R2-RC0PT+ Node",
    "slug": "f618r2-rc0pt-node"
  },
  "device_role": {
    "id": 1,
    "url": "http://192.168.39.33:8000/api/dcim/device-roles/1/?format=json",
    "name": "Server Node",
    "slug": "server-node"
  },
  "tenant": {
    "id": 1,
    "url": "http://192.168.39.33:8000/api/tenancy/tenants/1/?format=json",
    "name": "Infrastructure",
    "slug": "infrastructure"
  },
  "platform": null,
  "serial": "",
  "asset_tag": null,
  "site": {
    "id": 2,
    "url": "http://192.168.39.33:8000/api/dcim/sites/2/?format=json",
    "name": "Ampera Office",
    "slug": "ampera-office"
  },
  "rack": {
    "id": 1,
    "url": "http://192.168.39.33:8000/api/dcim/racks/1/?format=json",
    "name": "Rack1",
    "display_name": "Rack1 (STG1-R1)"
  },
  "position": null,
  "face": null,
  "parent_device": {
    "id": 1,
    "url": "http://192.168.39.33:8000/api/dcim/devices/1/?format=json",
    "name": "R1U7-4U8N",
    "display_name": "R1U7-4U8N",
    "device_bay": {
      "id": 33,
      "url": "http://192.168.39.33:8000/api/dcim/device-bays/33/?format=json",
      "name": "1"
    }
  },
  "status": {
    "value": 4,
    "label": "Failed"
  },
  "primary_ip": {
    "id": 22,
    "url": "http://192.168.39.33:8000/api/ipam/ip-addresses/22/?format=json",
    "family": 4,
    "address": "192.168.39.41/24"
  },
  "primary_ip4": {
    "id": 22,
    "url": "http://192.168.39.33:8000/api/ipam/ip-addresses/22/?format=json",
    "family": 4,
    "address": "192.168.39.41/24"
  },
  "primary_ip6": null,
  "cluster": null,
  "virtual_chassis": null,
  "vc_position": null,
  "vc_priority": null,
  "comments": "",
  "custom_fields": {
    
  },
  "created": "2018-02-08",
  "last_updated": "2018-02-17T06:23:40.457262Z"
}

I've tried using :

nb = pynetbox.api('http://192.168.39.33:8000', token='abcd1234')
print nb.ipam.ip_addresses.filter(role=['server-node'])

Return is None.

But if I am using print nb.dcim.devices.filter(role=['server-node'])

Return is [R1U7-4U8N-A, R1U7-4U8N-B, R1U7-4U8N-C, R1U7-4U8N-D]

My goal is, get all active ip address from nb.dcim.devices so I can put it on array.

Any hints?
Thanks

Python3 issues with basestring

I've run in to an issue with the use of basestring, this seems to be deprecated in Python3 and instead the use of str is suggested.

There's a few occurrences within lib/response.py, which locally I've tried replacing with str, which seems to be working.

Example traceback from p3.4:

>>> nb.dcim.devices.all()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/opt/NDC-Dev-Envs/ndc-pynetbox/lib/python3.4/site-packages/pynetbox/lib/endpoint.py", line 111, in all
    for i in req.get()
  File "/opt/NDC-Dev-Envs/ndc-pynetbox/lib/python3.4/site-packages/pynetbox/lib/endpoint.py", line 111, in <listcomp>
    for i in req.get()
  File "/opt/NDC-Dev-Envs/ndc-pynetbox/lib/python3.4/site-packages/pynetbox/lib/response.py", line 47, in __init__
    self._parse_values(values)
  File "/opt/NDC-Dev-Envs/ndc-pynetbox/lib/python3.4/site-packages/pynetbox/lib/response.py", line 102, in _parse_values
    setattr(self, k, lookup(v, api_kwargs=self.api_kwargs))
  File "/opt/NDC-Dev-Envs/ndc-pynetbox/lib/python3.4/site-packages/pynetbox/lib/response.py", line 242, in __init__
    super(IPRecord, self).__init__(*args, **kwargs)
  File "/opt/NDC-Dev-Envs/ndc-pynetbox/lib/python3.4/site-packages/pynetbox/lib/response.py", line 47, in __init__
    self._parse_values(values)
  File "/opt/NDC-Dev-Envs/ndc-pynetbox/lib/python3.4/site-packages/pynetbox/lib/response.py", line 275, in _parse_values
    if isinstance(v, basestring):
NameError: name 'basestring' is not defined

I can submit a pull request with the changes, if there is no objections.

Updating the 'site' Model causes an HTTP error, but correctly updates attributes anyways

Issue type

[X] Bug report

Environment

  • Python version: 3.6
  • NetBox version: 2.4-beta1
  • PyNetBox version: 3.4.4

Although it is a beta-release that I'm testing against, I thought I would note it anyways as it has the potential to cause issues when the stable version is released.

When trying to update attributes to any site via pynetbox and performing a nb_site.save(), an HTML error is returned but the actual object in NetBox is updated correctly.

I've tried to single out which attribute is causing this error, but all of the ones I've tested (description, physical_address, timezone, custom_fields) appear to produce the same result:


<!DOCTYPE html>
<html lang="en">

<head>
    <title>Server Error</title>
    <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css">
    <link rel="stylesheet" href="/static/font-awesome-4.7.0/css/font-awesome.min.css">
    <meta charset="UTF-8">
</head>

<body>
    <div class="container-fluid">
        <div class="row">
            <div class="col-md-6 col-md-offset-3">
                <div class="panel panel-danger" style="margin-top: 200px">
                    <div class="panel-heading">
                        <strong>
                            <i class="fa fa-warning"></i>
                            Server Error
                        </strong>
                    </div>
                    <div class="panel-body">

                            <p>
                                There was a problem with your request. Please contact an administrator.
                            </p>

                        <hr />
                        <p>
                            The complete exception is provided below:
                        </p>
<pre><strong></strong><br />
</pre>
                        <p>
                            If further assistance is required, please post to the <a href="https://groups.google.com/forum/#!forum/netbox-discuss">NetBox mailing list</a>.
                        </p>
                        <div class="text-right">
                            <a href="/" class="btn btn-primary">Home Page</a>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</body>

</html>

It could be due to some changes in the core of NetBox v2.4 that hasn't been updated in pynetbox just yet, however, the more time to investigate the better.

Let me know what other information you need to troubleshoot this issue.

Problem with all() and filter() methods for circuits

circ = nb.circuits.circuits.filter(status=5)

retrurns
[, , , , , , , , , , , , , , , , , , , , , , , ]

works with requests
log shows proper working call
"GET /api/circuits/circuits/?status=5 HTTP/1.1" 200 52

circ = nb.circuits.circuits.all()

returns
[,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
]
log shows proper working call
"GET /api/circuits/circuits/ HTTP/1.1" 200 516

I can get individual circuits by get() method no problem

how to get all the ips (not just primary ip4), their associated mac address and the device id

hello I want to get all the ip addresses (not just primary ip4) , and their associated mac addresses and the device id.

When i try to get mac address associated with the Ip address I get this -

nb = pynetbox.api('http://centos7client.example.com',token='fhjskh5jk435j3khkl')

ip_addresses = nb.ipam.ip_addresses.all()
mac_adderess = ip_addresses[7].interface.mac_address
print(mac_adderess)

mac_adderess = ip_addresses[7].interface.mac_address

AttributeError: 'NoneType' object has no attribute 'mac_address'

But when I try to take all the primary ip4 addresses it shows me correct mac address.
ipli = []
roles = nb.dcim.devices.filter(role='server')
for host in roles:
host = str(host)
host_data = nb.dcim.devices.get(name=host)
ips = host_data.primary_ip4
ipli.append(ips)
macid = ipli[7].interface.mac_address
print(macid)

Output -
00:9C:73:8C:DB:71

`get()` and `filter()` methods for `ipam.ip_addresses` don't work as (naïvely?) expected

After instantiating my Netbox instance like this:

import pynetbox
nb = pynetbox.api("http://localhost:8000", token='mysupersecrettoken')
(Pdb) nb.ipam.ip_addresses.create(address='8.8.8.8/32')
{u'status': 1, u'last_updated': u'2018-05-01T17:52:03.678390Z', u'description': u'', u'nat_inside': None, u'created': u'2018-05-01', u'role': None, u'vrf': None, u'address': u'8.8.8.8/32', u'interface': None, u'id': 50, u'tenant': None}
(Pdb) nb.ipam.ip_addresses.get(address='8.8.8.8/32')
*** ValueError: get() returned more than one result.
(Pdb) nb.ipam.ip_addresses.get(address='8.8.8.8')
*** ValueError: get() returned more than one result.
(Pdb) nb.ipam.ip_addresses.filter(address='8.8.8.8/32')
[8.8.8.8/32, <long list of other IP addresses in my instance>]
(Pdb) nb.ipam.ip_addresses.filter(address='8.8.8.8')
[8.8.8.8/32, <long list of other IP addresses in my instance>]
(Pdb) pynetbox.__version__
'3.3.1'

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.