README.md in oxidized-0.7.2 vs README.md in oxidized-0.8.0

- old
+ new

@@ -10,30 +10,33 @@ * will signal ios/junos user who made change, which output module can (git does) use (via POST) * 'git blame' will show for each line who and when the change was made * restful API to reload list of nodes (GET /reload) * restful API to fetch configurations (/node/fetch/[NODE] or /node/fetch/group/[NODE]) * restful API to show list of nodes (GET /nodes) +* restful API to show list of version for a node (/node/version[NODE]) and diffs [Youtube Video: Oxidized TREX 2014 presentation](http://youtu.be/kBQ_CTUuqeU#t=3h) #### Index 1. [Supported OS Types](#supported-os-types) 2. [Installation](#installation) * [Debian](#debian) * [CentOS, Oracle Linux, Red Hat Linux version 6](#centos-oracle-linux-red-hat-linux-version 6) 3. [Initial Configuration](#configuration) 4. [Installing Ruby 2.1.2 using RVM](#installing-ruby-2.1.2-using-rvm) -5. [Cookbook](#cookbook) +5. [Running with Docker](#running-with-docker) +6. [Cookbook](#cookbook) * [Debugging](#debugging) * [Privileged mode](#privileged-mode) * [Source: CSV](#source-csv) * [Source: SQLite](#source-sqlite) * [Source: HTTP](#source-http) * [Output: GIT](#output-git) * [Output: File](#output-file) + * [Output types](#output-types) * [Advanced Configuration](#advanced-configuration) -6. [Ruby API](#ruby-api) +7. [Ruby API](#ruby-api) * [Input](#input) * [Output](#output) * [Source](#source) * [Model](#model) @@ -65,12 +68,14 @@ * HP ProCurve * Huawei VRP * Juniper JunOS * Juniper ScreenOS (Netscreen) * Mikrotik RouterOS + * MRV Master-OS * Ubiquiti AirOS * Palo Alto PAN-OS + * Zyxel ZyNOS # Installation ## Debian Install all required packages and gems. @@ -157,21 +162,58 @@ source /etc/profile.d/rvm.sh rvm install 2.1.2 rvm use --default 2.1.2 ``` +# Running with Docker +1. clone git repo: +``` + root@bla:~# git clone https://github.com/ytti/oxidized +``` +2. build container locally: +``` + root@bla:~# docker build -q -t oxidized/oxidized:latest oxidized/ +``` +3. create config directory in main system: +``` + root@bla~:# mkdir /etc/oxidized +``` +4. run container the first time: +``` + root@bla:~# docker run -v /etc/oxidized:/root/.config/oxidized -p 8888:8888/tcp -t oxidized/oxidized:latest oxidized +``` +5. add 'router.db' to /etc/oxidized: +``` + root@bla:~# vim /etc/oxidized/router.db + [ ... ] + root@bla:~# +``` +6. run container again: +``` + root@bla:~# docker run -v /etc/oxidized:/root/.config/oxidized -p 8888:8888/tcp -t oxidized/oxidized:latest oxidized + oxidized[1]: Oxidized starting, running as pid 1 + oxidized[1]: Loaded 1 nodes + Puma 2.13.4 starting... + * Min threads: 0, max threads: 16 + * Environment: development + * Listening on tcp://0.0.0.0:8888 + ^C + + root@bla:~# +``` + ## Cookbook ### Debugging In case a model plugin doesn't work correctly (ios, procurve, etc.), you can enable live debugging of SSH/Telnet sessions. Just add a ```debug``` option, specifying a log file destination to the ```input``` section. The following example will log an active ssh session to ```/home/fisakytt/.config/oxidized/log_input-ssh``` and telnet to ```log_input-telnet```. The file will be truncated on each consecutive ssh/telnet session, so you need to put a ```tailf``` or ```tail -f``` on that file! ``` input: default: ssh, telnet - debug: ~/.config/oxidized/log_input + debug: /tmp/oxidized_log_input ssh: secure: false ``` ### Privileged mode @@ -263,10 +305,56 @@ user: Oxidized email: o@example.com repo: "/var/lib/oxidized/devices.git" ``` +### Output types + +If you prefer to have different outputs in different files and/or directories, you can easily do this by modifying the corresponding model. To change the behaviour for IOS, you would edit `lib/oxidized/model/ios.rb`. + +For example, let's say you want to split out `show version` and `show inventory` into separate files in a directory called `nodiff` which your tools will not send automated diffstats for. You can apply a patch along the lines of + +``` +- cmd 'show version' do |cfg| +- comment cfg.lines.first ++ cmd 'show version' do |state| ++ state.type = 'nodiff' ++ state + +- cmd 'show inventory' do |cfg| +- comment cfg ++ cmd 'show inventory' do |state| ++ state.type = 'nodiff' ++ state ++ end + +- cmd 'show running-config' do |cfg| +- cfg = cfg.each_line.to_a[3..-1].join +- cfg.gsub! /^Current configuration : [^\n]*\n/, '' +- cfg.sub! /^(ntp clock-period).*/, '! \1' +- cfg.gsub! /^\ tunnel\ mpls\ traffic-eng\ bandwidth[^\n]*\n*( ++ cmd 'show running-config' do |state| ++ state = state.each_line.to_a[3..-1].join ++ state.gsub! /^Current configuration : [^\n]*\n/, '' ++ state.sub! /^(ntp clock-period).*/, '! \1' ++ state.gsub! /^\ tunnel\ mpls\ traffic-eng\ bandwidth[^\n]*\n*( + (?:\ [^\n]*\n*)* + tunnel\ mpls\ traffic-eng\ auto-bw)/mx, '\1' +- cfg ++ state = Oxidized::String.new state ++ state.type = 'nodiff' ++ state +``` + +which will result in the following layout + +``` +diff/$FQDN--show_running_config +nodiff/$FQDN--show_version +nodiff/$FQDN--show_inventory +``` + ### Advanced Configuration Below is an advanced example configuration. You will be able to (optinally) override options per device. The router.db format used is ```hostname:model:username:password:enable_password```. Hostname and model will be the only required options, all others override the global configuration sections. ``` @@ -311,11 +399,62 @@ model_map: cisco: ios juniper: junos ``` +# Hooks +You can define arbitrary number of hooks that subscribe different events. The hook system is modular and different kind of hook types can be enabled. +## Configuration +Following configuration keys need to be defined for all hooks: + + * `events`: which events to subscribe. Needs to be an array. See below for the list of available events. + * `type`: what hook class to use. See below for the list of available hook types. + +### Events + * `node_success`: triggered when configuration is succesfully pulled from a node and right before storing the configuration. + * `node_fail`: triggered after `retries` amount of failed node pulls. + * `post_store`: triggered after node configuration is stored. + +## Hook type: exec +The `exec` hook type allows users to run an arbitrary shell command or a binary when triggered. + +The command is executed on a separate child process either in synchronous or asynchronous fashion. Non-zero exit values cause errors to be logged. STDOUT and STDERR are currently not collected. + +Command is executed with the following environment: +``` +OX_EVENT +OX_NODE_NAME +OX_NODE_FROM +OX_NODE_MSG +OX_NODE_GROUP +OX_JOB_STATUS +OX_JOB_TIME +``` + +Exec hook recognizes following configuration keys: + + * `timeout`: hard timeout for the command execution. SIGTERM will be sent to the child process after the timeout has elapsed. Default: 60 + * `async`: influences whether main thread will wait for the command execution. Set this true for long running commands so node pull is not blocked. Default: false + * `cmd`: command to run. + + +## Hook configuration example +``` +hooks: + name_for_example_hook1: + type: exec + events: [node_success] + cmd: 'echo "Node success $OX_NODE_NAME" >> /tmp/ox_node_success.log' + name_for_example_hook2: + type: exec + events: [post_store, node_fail] + cmd: 'echo "Doing long running stuff for $OX_NODE_NAME" >> /tmp/ox_node_stuff.log; sleep 60' + async: true + timeout: 120 +``` + # Ruby API The following objects exist in Oxidized. ## Input @@ -343,5 +482,24 @@ * lists commands to gather from given device model * can use 'cmd', 'prompt', 'comment', 'cfg' * cfg is executed in input/output/source context * cmd is executed in instance of model * 'junos', 'ios', 'ironware' and 'powerconnect' implemented + + +# License and Copyright + +Copyright 2013-2015 Saku Ytti <saku@ytti.fi> + 2013-2015 Samer Abdel-Hafez <sam@arahant.net> + + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License.