GithubHelp home page GithubHelp logo

ninech / netbox-client-ruby Goto Github PK

View Code? Open in Web Editor NEW
24.0 15.0 21.0 538 KB

A ruby client library for Netbox v2.

License: MIT License

Ruby 99.87% Shell 0.06% Dockerfile 0.07%
ruby faraday netbox docker-compose

netbox-client-ruby's Introduction

NetboxClientRuby

Build Status Gem Version Code Climate

This is a gem to pragmatically access your Netbox instance via it's API from Ruby. This gem is currently only compatible with Netbox v2.4 or newer.

Installation

Add this line to your application's Gemfile:

gem 'netbox-client-ruby'

If your application already uses Faraday 0.x or 1.x and you cannot otherwise upgrade to Faraday 2, you must also add this line to your application's Gemfile:

gem 'faraday_middleware' # remove when upgrading to Faraday 2+

And then execute:

$ bundle

Or install it manually:

$ gem install netbox-client-ruby

Usage

Configuration

Put this somewhere, where it runs, before any call to anything else of Netbox. If you are using Rails, then this would probably be somewhere underneath /config.

require 'netbox-client-ruby'
NetboxClientRuby.configure do |config|
  config.netbox.auth.token = 'YOUR_API_TOKEN'
  config.netbox.api_base_url = 'http://netbox.local/api/'

  # these are optional:
  config.netbox.auth.rsa_private_key.path = '~/.ssh/netbox_rsa'
  config.netbox.auth.rsa_private_key.password = ''
  config.netbox.pagination.default_limit = 50
  config.faraday.adapter = Faraday.default_adapter
  config.faraday.request_options = { open_timeout: 1, timeout: 5 }
  config.faraday.logger = :logger # built-in options: :logger, :detailed_logger; default: nil
end

Structure

The methods are aligned with the API as it is defined in Netbox. You can explore the API endpoints in your browser by opening the API endpoint. Usually that's http://YOUR_NETBOX/api/.

So if the URL is /api/dcim/sites.json, then the corresponding Ruby code would be NetboxClientRuby.dcim.sites.

Examples

# configuration
NetboxClientRuby.configure do |c|
  c.netbox.auth.token = '2e35594ec8710e9922d14365a1ea66f27ea69450'
  c.netbox.api_base_url = 'http://netbox.local/api/'
  c.netbox.auth.rsa_private_key.path = '~/.ssh/netbox_rsa'
end

# get all sites
sites = NetboxClientRuby.dcim.sites
puts "There are #{sites.total} sites in your Netbox instance."

# get the first site of the result set
first_site = sites.first
puts "The first site is called #{first_site.name}."

# filter devices by site
# Note that Netbox filters by *slug*
devices_of_site = NetboxClientRuby.dcim.devices.filter(site: first_site.slug)
puts "#{devices_of_site.total} devices belong to the site. #{devices_of_site}.length devices have been fetched."

# Finds a specific device
NetboxClientRuby.dcim.devices.find_by(name: 'my-device', other_field: 'other-value')

# Finds a specific device with a certain custom field
NetboxClientRuby.dcim.devices.find_by(cf_custom_url: 'https://google.com')

# Or a mix of regular and custom fields
NetboxClientRuby.dcim.devices.find_by(name: 'my-device', cf_custom_field: 'custom-value')

# get a site by id
s = NetboxClientRuby.dcim.site(1)

# update a site
s.update(name: 'Zurich', slug: 'zrh')

# update a site (alternative)
s.name = 'Amsterdam'
s.slug = 'ams'
s.save

# create a site
new_s = NetboxClientRuby::DCIM::Site.new
new_s.name = 'Berlin'
new_s.slug = 'ber'
new_s.save

# create a site (alternative)
new_s = NetboxClientRuby::DCIM::Site
          .new(name: 'Berlin', slug: 'ber')
          .save

# delete a site
s = NetboxClientRuby.dcim.site(1)
s.delete

# working with secrets
secrets = NetboxClientRuby.secrets.secrets
puts "#{secrets.total} secrets are in your Netbox."
secrets[0].plaintext # => nil, because you have not yet defined a session_key
NetboxClientRuby.secrets.get_session_key # now get a session_key
secrets = NetboxClientRuby.secrets.secrets # you must reload the data from the server
secrets[0].plaintext # => 'super secret password'

# optionally, you can persist the session_key:
session_key = NetboxClientRuby.secrets.get_session_key.session_key
FILE_NAME = File.expand_path('~/.netbox_session_key').freeze
File.write(FILE_NAME, session_key)

# later on, you can restore the persisted session_key:
persisted_session_key = File.read(FILE_NAME)
NetboxClientRuby.secrets.session_key = persisted_session_key

Available Objects

Not all objects which the Netbox API exposes are currently implemented. Implementing new objects is trivial, though.

  • Circuits:
    • Circuits: NetboxClientRuby.circuits.circuits
    • Circuit Types: NetboxClientRuby.circuits.circuit_types
    • Circuit Terminations: NetboxClientRuby.circuits.circuit_terminations
    • Providers: NetboxClientRuby.circuits.providers
  • DCIM:
    • Console Connections: NetboxClientRuby.dcim.console_connections
    • Console Ports: NetboxClientRuby.dcim.console_ports
    • Console Server Ports: NetboxClientRuby.dcim.console_server_ports
    • Devices: NetboxClientRuby.dcim.devices
    • Device Roles: NetboxClientRuby.dcim.device_roles
    • Device Types: NetboxClientRuby.dcim.device_types
    • Interfaces: NetboxClientRuby.dcim.interfaces
    • Interface Connections: NetboxClientRuby.dcim.interface_connections
    • Manufacturers: NetboxClientRuby.dcim.manufacturers
    • Platforms: NetboxClientRuby.dcim.platforms
    • Power Connections: NetboxClientRuby.dcim.power_connections
    • Power Outlets: NetboxClientRuby.dcim.power_outlets
    • Power Ports: NetboxClientRuby.dcim.power_ports
    • Racks: NetboxClientRuby.dcim.racks
    • Rack Groups: NetboxClientRuby.dcim.rack_groups
    • Rack Roles: NetboxClientRuby.dcim.rack_roles
    • Rack Reservations: NetboxClientRuby.dcim.rack_reservations
    • Regions: NetboxClientRuby.dcim.regions
    • Sites: NetboxClientRuby.dcim.sites
    • Virtual Chassis: NetboxClientRuby.dcim.virtual_chassis_list (โš ๏ธ Exception: The access is different and the class is called VirtualChassisList because the plural and singular names are the same and this poses a conflict.)
  • Extras:
    • Config Contexts: NetboxClientRuby.extras.config_contexts
    • Journal Entries: NetboxClientRuby.extras.journal_entries
    • Tags: NetboxClientRuby.extras.tags
  • IPAM:
    • Aggregates: NetboxClientRuby.ipam.aggregates
    • IP Addresses: NetboxClientRuby.ipam.ip_addresses
    • IP Ranges: NetboxClientRuby.ipam.ip_ranges
    • Prefixes: NetboxClientRuby.ipam.prefixes
    • RIRs: NetboxClientRuby.ipam.rirs
    • Roles: NetboxClientRuby.ipam.roles
    • Services: NetboxClientRuby.ipam.services
    • VLANs: NetboxClientRuby.ipam.vlans
    • VLAN Groups: NetboxClientRuby.ipam.vlan_groups
    • VRFs: NetboxClientRuby.ipam.vrfs
  • Secrets:
    • Secrets: NetboxClientRuby.secrets.secrets
    • Secret Roles: NetboxClientRuby.secrets.secret_roles
    • generate-rsa-key-pair: NetboxClientRuby.secrets.generate_rsa_key_pair
    • get-session-key: NetboxClientRuby.secrets.get_session_key
  • Tenancy:
    • Tenant: NetboxClientRuby.tenancy.tenants
    • Tenant Groups: NetboxClientRuby.tenancy.tenant_groups
  • Virtualization:
    • Cluster Types: NetboxClientRuby.virtualization.cluster_types
    • Cluster Groups: NetboxClientRuby.virtualization.cluster_groups
    • Clusters: NetboxClientRuby.virtualization.clusters
    • Virtual Machines: NetboxClientRuby.virtualization.virtual_machines
    • Interfaces: NetboxClientRuby.virtualization.interfaces

If you can't find the object you need, also check the source code if it was added in the meantime without the list above having been updated.

Development

After checking out the repo, run bin/setup to install dependencies. Then, run rake spec to run the tests.

To install this gem onto your local machine, run bundle exec rake install.

To experiment interactively, fire up the Netbox Docker container by running docker-compose up -d. Then, run bin/console for an interactive prompt that will allow you to experiment against your local Netbox.

Load Development Data

To simplify development, e.g. via the bin/console described above, there is a very complete sample set of Netbox data readily available. You can use it to query almost every object and relation in Netbox.

docker exec -i netbox-client-ruby_postgres_1 psql -U postgres < dump.sql

Dump Development from Database

Should you want to export the current set of data, use the command below.

docker-compose exec postgres pg_dump -U netbox --exclude-table-data=extras_objectchange -Cc netbox > dump.sql

(Remove --exclude-table-data=extras_objectchange from the command if you want to retain the history!)

Contributing

Bug reports and pull requests are very welcome on GitHub.

Before opening a PR, please

  • extend the existing specs
  • run rspec
  • run rubocop and fix your warnings
  • check if this README.md file needs adjustments

License

The gem is available as open source under the terms of the MIT License.

About

This gem is currently maintained and funded by nine.

logo of the company 'nine'

netbox-client-ruby's People

Contributors

ahmeij avatar bleything avatar born4new avatar btriller avatar cimnine avatar ekohl avatar fkshom avatar gregoryp avatar ikke avatar jlemesh avatar lukassup avatar mame avatar n-rodriguez avatar ninech-bot avatar rossta avatar severinkaelin avatar thde avatar tvl2386 avatar twhiston 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

Watchers

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

netbox-client-ruby's Issues

Unable to fetch VirtualMachine.Primary_IP.address

Hello,

I'm building an RoR app that fetch my Netbox instance to show our virtual machines.

I'm happy to find your lib, it work as well but I got issues to fetch a variable.

Maybe it's my low level in Ruby the cause, but I don't find any answer.

# I fetch VMs in my Controller
      vms = NetboxClientRuby.virtualization.virtual_machines.filter(cluster_id: cluster_id)

# I use the @vms var in my ERB html files

 <% @vms.each do |vm| %>
        <tr>
# This Work well
            <td><%= vm.name %></td>
            <td><%= vm.vcpus %></td>
            <td><%= vm.memory %>Mo</td>
            <td><%= vm.disk %>Go</td>
# This doesn't work
            <td> <%= vm.primary_ip.name %></td>   
        </tr>
<% end %>
                

I have tried vm.primary_ip['address'], vm.primary_ip('address') and few other way, but I'm unable to get my VM Primary IP Address.

I got error like this :

undefined method name' for #NetboxClientRuby::IPAM::IpAddress:0x00007ffff51d63c8`

Any idea ?

Thanks by advance

Available ip's

Prefixes and Ip-Ranges support an additional endpoint 'available-ips' like this: /ipam/prefixes/{id}/available-ips/

I'm looking to create a pull-request to implement these however the mechanism of a 'dynamic' url (including the prefix-id) for a class with Entities does not come naturally to the current Entities implementation.

Do you have a preference on how to implement these endpoints?

sha256 mismatch on gem v0.4.8

According to rubygems.org the SHA-256 sum of v0.4.8 should be 923da7747009e3bbb8acc37b56dca3e1b7e86720929ec9d000d32f37db82a475. But when I download the file:

$ curl -sLO https://rubygems.org/downloads/netbox-client-ruby-0.4.8.gem
$ shasum -a 256 netbox-client-ruby-0.4.8.gem
7369d19d40d39d060abe413bfa026170f94403a8c2c31d97dea077bba3b84108  netbox-client-ruby-0.4.8.gem

This is relevant because bundler will refuse to install the gem if the SHA-256 doesn't match.

I did some digging and turned up rubygems/rubygems.org#1551, and in particular this comment which discusses causes and potential resolutions.

It seems like the only solution right now is to release a new version :/

Faraday Gem is outdated

Faraday dependency version 0.x is very old and causes dependency issues with other RubyGems which require Faraday >=1.0.

Could you please update the client to use a more recent Faraday version so the users would not have to use the old version?

Example error:

Bundler could not find compatible versions for gem "faraday":
  In Gemfile:
    netbox-client-ruby (~> 0.6.0) was resolved to 0.6.0, which depends on
      faraday (>= 0.11.0, ~> 0.11)

    slack-ruby-client (~> 1.0.0) was resolved to 1.0.0, which depends on
      faraday (>= 1.0)

can't access an interface's virtual_machine

For various reason I'm iterating over IP address's interfaces and trying to find their related devices or VMs. Devices work okay, but VMs don't:

$nb.ipam.ip_addresses.first.interface.virtual_machine
NoMethodError: undefined method `virtual_machine' for #<NetboxClientRuby::DCIM::Interface:0x00007f80c512e5b0>
	from /Users/bleything/.chefdk/gem/ruby/2.4.0/gems/netbox-client-ruby-0.4.6/lib/netbox_client_ruby/entity.rb:207:in `method_missing'
	from (irb):9
	from /opt/chefdk/embedded/bin/irb:11:in `<main>'

I tried editing lib/netbox_client_ruby/api/dcim/interface.rb:

require 'netbox_client_ruby/entity'
require 'netbox_client_ruby/api/dcim/device'
require 'netbox_client_ruby/api/virtualization/virtual_machine'

module NetboxClientRuby
  module DCIM
    class Interface
      include Entity

      id id: :id
      deletable true
      path 'dcim/interfaces/:id.json'
      creation_path 'dcim/interfaces/'
      object_fields device: proc { |raw_data| Device.new raw_data['id'] },
                    virtual_machine: proc { |raw_data| Virtualization::VirtualMachine.new raw_data['id'] }
    end
  end
end

and that makes the NoMethodError go away but it returns nil, even when there's a virtual_machine attached. I assume that I'm just doing something wrong but I don't understand the code well enough to figure out how to resolve it.

Search for IP address with given address and pagination

Hi! First of all, thanks for you library it is really awesome! Everything works nicely.

I'm making OpenStack to NetBox exporter and I want to check if IP address with given IP exists or not. I can obtain all ip addresses and then search if there is object with address same as one I obtain from OpenStack but I wonder if there is a way to search for IP with given address. It is not a big issue but requesting couple of thousands IP addresses and search in them is not so effective as one search query.

I tried NetboxClientRuby.ipam.ip_addresses.filter(address: '192.168.4.40/24') but it doesn't work for me.

Pagination also seems to be not documented(just one entry in example config file). It would be really nice to see an example code block about working with pagination IPAM module.

EDIT: Ok, in code I found out that you can use #all method to get all objects. But you need to remember to set your MAX_PAGE_SIZE to 0 in configuration.py in your NetBox installation if you want to get all objects at once from api.

So is it possible?

How do I get all the interfaces for the device

Hi, tell me how, having only the hostname (name/display), to get all the interfaces of the device with addresses?
In my case, I'm trying to use a device query and I get nil.

>> NetboxClientRuby.dcim.interfaces.find_by(device: 'brz-v-itmg-1')


I, [2024-03-12T23:14:48.133484 #73591]  INFO -- request: GET https://netbox.../api/dcim/interfaces.json?device=brz-v-itmg-1&limit=50
I, [2024-03-12T23:14:48.133513 #73591]  INFO -- request: Authorization: "Token ***"
User-Agent: "Faraday v1.10.3"
I, [2024-03-12T23:14:49.461606 #73591]  INFO -- response: Status 200
I, [2024-03-12T23:14:49.461814 #73591]  INFO -- response: content-type: "application/json"
vary: "HX-Request, Cookie, origin, Accept-Encoding"
allow: "GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS, TRACE"
x-request-id: "1129bd3c-283c-49a0-9be5-14a6eefaf198"
x-content-type-options: "nosniff"
referrer-policy: "same-origin"
cross-origin-opener-policy: "same-origin"
x-frame-options: "SAMEORIGIN"
server: "envoy"
date: "Tue, 12 Mar 2024 20:14:49 GMT"
x-envoy-upstream-service-time: "862"
transfer-encoding: "chunked"
nil

But the same request in the console works and I get the necessary interfaces

curl -H "Authorization: Token ***" 'https://netbox.../api/dcim/interfaces.json?device=brz-v-itmg-1&limit=50' | jq
{
  "count": 7,
...

Dirty-tracking for not-changes attributes?

I'm currently importing a larger number of configurations from different sources into Netbox, and this causes a lot of (unnecessary) PATCH requests.

Let's say I've got this device role, created by a previous import run:

role = NetboxClientRuby.dcim.device_roles.find_by(slug: "access-point")
#=> #<NetboxClientRuby::DCIM::DeviceRole @data={"id"=>6, "name"=>"Access Point", "slug"=>"access-point", "color"=>"009688", "vm_role"=>false}, @dirty_data={}, @id=6>

When setting its attributes, it gets tracked:

role.name = role.name
role.send :dirty_data
#=> {"name"=>"Access Point"}

Should NetboxClientRuby::Entity#method_missing track dirty attributes when the value did not change?

The patch should be relatively easy:

@@ lib/netbox_client_ruby/entity.rb @@
     def method_missing(name_as_symbol, *args, &block)
       if name.end_with?('=')
          ...
+        dirty_data[name[0..-2]] = args[0] unless dirty_data[name[0..-2]] == args[0] 
-        dirty_data[name[0..-2]] = args[0]
         return arg[0]

flatten throws an error

I've worked around this issue by concatting arrays, however, I think it is a bug that the following code throws an error:

> [[NetboxClientRuby::DCIM::Interface.new(name: 'ge-0/0/0', device_id: 488)]].flatten
NetboxClientRuby::LocalError: Received 'nil' while replacing ':id' in 'dcim/interfaces/:id.json' with a value.
from /usr/local/bundle/gems/netbox-client-ruby-0.5.2/lib/netbox_client_ruby/entity.rb:310:in `block in replace_path_variables_in'

The problem is Interface responds to flatten and throws an error:

> NetboxClientRuby::DCIM::Interface.new(name: 'ge-0/0/0', device_id: 488).flatten
NetboxClientRuby::LocalError: Received 'nil' while replacing ':id' in 'dcim/interfaces/:id.json' with a value.
from /usr/local/bundle/gems/netbox-client-ruby-0.5.2/lib/netbox_client_ruby/entity.rb:310:in `block in replace_path_variables_in'

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.