oxidized-script 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 69f616aaf84a8c98cde89b1ca52104e3f810c4d7
4
- data.tar.gz: fe960f7e73823e8edd1924c80de37b3728389aee
3
+ metadata.gz: 1a38be515ce13472269675c5686f022207c5f394
4
+ data.tar.gz: 8a08ffbdbe0aa0326d32aaa9c9b59435ca4af3a1
5
5
  SHA512:
6
- metadata.gz: e68f12a94f56a3ad29ba5739696641bd31f1986929b680ff066121bc8cc9346edea4e1dfee878a84b385507dd547e6a0df41debc4d9cfc624d86343730608ba0
7
- data.tar.gz: 8d2a39122c5a1003478e7cf10a544867cae6c130029e9b59b413f83e848aa109486a6844f85fc94a9d5cc0841572bf3d60df9c71c9e5b0e852ef361b27567ef0
6
+ metadata.gz: 8e0d9f0226991efd74bfb9a4896ed7b896f8f2b5ad86736047aa780c041dae5f77d343506720e975cac80e455fd22a7adf3aa6d7376dd18e64e057f53146c481
7
+ data.tar.gz: dff10d69c6fc2e601f8c030465541dff60a086fcd354a7054ea3570981d893abc7b9c667ba4af43f14373ba0b1441d89b20ca3ca97ead77599c8163eaf2633ff
data/.gitignore CHANGED
@@ -1,2 +1,3 @@
1
1
  Gemfile.lock
2
2
  gems
3
+ *.swp
@@ -1,3 +1,9 @@
1
+ # 0.3.0
2
+ - FEATURE on --regex to run commands on hosts matching a regex (by @nertwork)
3
+ - FEATURE on -g to run commands on entire group (by @nertwork)
4
+ - FEATURE on -r to thread commands run on entire group (by @nertwork)
5
+ - BUGFIX: fix for replacing escaped newlines in config files (by @nertwork)
6
+
1
7
  # 0.2.0
2
8
  - FEATURE on -x disable ssh exec mode (by @nickhilliard)
3
9
 
data/README.md CHANGED
@@ -27,17 +27,36 @@ Default gateway is 62.236.123.198
27
27
  Host Gateway Last Use Total Uses Interface
28
28
  ICMP redirect cache is empty
29
29
  %IPv4 CEF not running
30
+
31
+ [nertwork@lan-login2 ~]% oxs --verbose --group ios --threads 4 --regex ^test 'show vrf'
32
+ running list for hosts in group: ios and matching: ^test
33
+ ## HOST - test-node-1
34
+ ## OXS - show vrf
35
+ Name Default RD Protocols Interfaces
36
+ mgmtVRF <not set> ipv4,ipv6 Fa1
37
+
30
38
  [fisakytt@lan-login1 ~]% oxs --help
31
39
  Usage: oxs [options] hostname [command]
32
- -m, --model host model (ios, junos, etc), otherwise discovered from Oxidized source
33
- -x, --commands commands file to be sent
34
- -u, --username username to use
35
- -p, --password password to use
36
- -t, --timeout timeout value to use
37
- -e, --enable enable password to use
38
- -d, --debug turn on debugging
39
- -h, --help Display this help message.
40
+ -m, --model host model (ios, junos, etc), otherwise discovered from Oxidized source
41
+ -x, --commands commands file to be sent
42
+ -u, --username username to use
43
+ -p, --password password to use
44
+ -t, --timeout timeout value to use
45
+ -e, --enable enable password to use
46
+ -c, --community snmp community to use for discovery
47
+ -g, --group group to run commands on (ios, junos, etc), specified in oxidized db
48
+ -r, --threads specify ammount of threads to use for running group (default: 1)
49
+ --regex run on all hosts that match the regexp
50
+ --protocols protocols to use, default "ssh, telnet"
51
+ -v, --verbose verbose output, e.g. show commands sent
52
+ -d, --debug turn on debugging
53
+ --terse display clean output
54
+ --list-models list supported models
55
+ --list-nodes list nodes in oxidized source
56
+ -h, --help Display this help message.
40
57
  [fisakytt@lan-login1 ~]%
58
+
59
+
41
60
  ```
42
61
 
43
62
  ### Library
data/bin/oxs CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  begin
4
4
  require 'oxidized/script/cli'
5
- puts Oxidized::Script::CLI.new.run
5
+ Oxidized::Script::CLI.new.run
6
6
  rescue => error
7
7
  warn "#{error}"
8
8
  raise if Oxidized.config.debug
@@ -1,6 +1,7 @@
1
1
  module Oxidized
2
2
  require_relative 'script'
3
3
  require 'slop'
4
+ require 'thread'
4
5
 
5
6
  class Script
6
7
  class CLI
@@ -9,11 +10,38 @@ module Oxidized
9
10
  class NothingToDo < ScriptError; end
10
11
 
11
12
  def run
12
- connect
13
- if @opts[:commands]
14
- run_file @opts[:commands]
15
- elsif @cmd
16
- @oxs.cmd @cmd
13
+ if @group or @regex
14
+ nodes = get_hosts
15
+ work_q = Queue.new
16
+ nodes.each{|node| work_q.push node}
17
+ workers = (0...@threads.to_i).map do
18
+ Thread.new do
19
+ begin
20
+ while node = work_q.pop(true)
21
+ begin
22
+ @host = node
23
+ connect
24
+ if @opts[:commands]
25
+ puts run_file @opts[:commands]
26
+ elsif @cmd
27
+ puts @oxs.cmd @cmd
28
+ end
29
+ rescue
30
+ puts "Couldn't connect to: " + node
31
+ end
32
+ end
33
+ rescue ThreadError
34
+ end
35
+ end
36
+ end
37
+ workers.map(&:join)
38
+ else
39
+ connect
40
+ if @opts[:commands]
41
+ puts run_file @opts[:commands]
42
+ elsif @cmd
43
+ puts @oxs.cmd @cmd
44
+ end
17
45
  end
18
46
  end
19
47
 
@@ -33,10 +61,14 @@ module Oxidized
33
61
  @cmd_class.run :args=>@args, :opts=>@opts, :host=>@host, :cmd=>@cmd
34
62
  exit 0
35
63
  else
36
- @host = @args.shift
37
- @cmd = @args.shift if @args
64
+ if @group or @regex
65
+ @cmd = @args.shift
66
+ else
67
+ @host = @args.shift
68
+ @cmd = @args.shift if @args
69
+ end
38
70
  @oxs = nil
39
- raise NothingToDo, 'no host given' if not @host
71
+ raise NothingToDo, 'no host given' if not @host and not @group and not @regex
40
72
  raise NothingToDo, 'nothing to do, give command or -x' if not @cmd and not @opts[:commands]
41
73
  end
42
74
  end
@@ -51,6 +83,9 @@ module Oxidized
51
83
  slop.on 't=', '--timeout', 'timeout value to use'
52
84
  slop.on 'e=', '--enable', 'enable password to use'
53
85
  slop.on 'c=', '--community', 'snmp community to use for discovery'
86
+ slop.on 'g=', '--group', 'group to run commands on (ios, junos, etc), specified in oxidized db'
87
+ slop.on 'r=', '--threads', 'specify ammount of threads to use for running group', default: '1'
88
+ slop.on '--regex=', 'run on all hosts that match the regexp'
54
89
  slop.on '--protocols=','protocols to use, default "ssh, telnet"'
55
90
  slop.on 'v', '--verbose', 'verbose output, e.g. show commands sent'
56
91
  slop.on 'd', '--debug', 'turn on debugging'
@@ -65,6 +100,10 @@ module Oxidized
65
100
  end
66
101
  end
67
102
  slop.parse
103
+ @group = slop[:group]
104
+ @threads = slop[:threads]
105
+ @verbose = slop[:verbose]
106
+ @regex = slop[:regex]
68
107
  [slop.parse!, slop]
69
108
  end
70
109
 
@@ -82,7 +121,7 @@ module Oxidized
82
121
  file = file == '-' ? $stdin : File.read(file)
83
122
  file.each_line do |line|
84
123
  line.chomp!
85
- line.sub!(/\\n/, "\n") # tread escaped newline as newline
124
+ # line.sub!(/\\n/, "\n") # treat escaped newline as newline
86
125
  out += @oxs.cmd line
87
126
  end
88
127
  out
@@ -104,6 +143,41 @@ module Oxidized
104
143
  cmds
105
144
  end
106
145
 
146
+ def get_hosts
147
+ if @group and @regex
148
+ puts "running list for hosts in group: #{@group} and matching: #{@regex}" if @verbose
149
+ nodes_group = run_group @group
150
+ nodes_regex = run_regex @regex
151
+ return nodes_group & nodes_regex
152
+ elsif @regex
153
+ puts 'running list for hosts matching: ' + @regex if @verbose
154
+ return run_regex @regex
155
+ else
156
+ puts 'running list for hosts in group: ' + @group if @verbose
157
+ return run_group @group
158
+ end
159
+ end
160
+
161
+ def run_group group
162
+ Oxidized.mgr = Manager.new
163
+ out = []
164
+ Nodes.new.each do |node|
165
+ next unless group == node.group
166
+ out << node.name
167
+ end
168
+ out
169
+ end
170
+
171
+ def run_regex regex
172
+ Oxidized.mgr = Manager.new
173
+ out = []
174
+ Nodes.new.each do |node|
175
+ next unless node.name =~ /#{regex}/
176
+ out << node.name
177
+ end
178
+ out
179
+ end
180
+
107
181
  end
108
182
  end
109
183
  end
@@ -18,6 +18,7 @@ module Oxidized
18
18
  # @return [String] output for command
19
19
  def cmd command
20
20
  out = ''
21
+ out += "## HOST - #{@host}\n" if @verbose
21
22
  out += "## OXS - #{command}\n" if @verbose
22
23
  cmd_out = @model.cmd command
23
24
  out += cmd_out if cmd_out
@@ -34,7 +35,7 @@ module Oxidized
34
35
  private
35
36
 
36
37
  # @param [Hash] opts options for Oxidized::Script
37
- # @option opts [String] :host hostname or ip address for Oxidized::Node
38
+ # @option opts [String] :host @hostname or ip address for Oxidized::Node
38
39
  # @option opts [String] :model node model (ios, junos etc) if defined, nodes are not loaded from source
39
40
  # @option opts [Fixnum] :timeout oxidized timeout
40
41
  # @option opts [String] :username username for login
@@ -46,13 +47,14 @@ module Oxidized
46
47
  # @yieldreturn [self] if called in block, returns self and disconnnects session after exiting block
47
48
  # @return [void]
48
49
  def initialize opts, &block
49
- host = opts.delete :host
50
+ @host = opts.delete :host
50
51
  model = opts.delete :model
51
52
  timeout = opts.delete :timeout
52
53
  username = opts.delete :username
53
54
  password = opts.delete :password
54
55
  enable = opts.delete :enable
55
56
  community = opts.delete :community
57
+ group = opts.delete :group
56
58
  @verbose = opts.delete :verbose
57
59
  Oxidized.config.input.default = opts.delete :protocols if opts[:protocols]
58
60
  raise InvalidOption, "#{opts} not recognized" unless opts.empty?
@@ -64,10 +66,10 @@ module Oxidized
64
66
  end
65
67
 
66
68
  @node = if model
67
- Node.new(:name=>host, :model=>model)
68
- else
69
- Nodes.new(:node=>host).first
70
- end
69
+ Node.new(:name=>@host, :model=>model)
70
+ else
71
+ Nodes.new(:node=>@host).first
72
+ end
71
73
  if not @node
72
74
  begin
73
75
  require 'corona'
@@ -75,9 +77,9 @@ module Oxidized
75
77
  rescue LoadError
76
78
  raise NoNode, 'node not found'
77
79
  end
78
- node = Corona.poll :host=>host, :community=>community
80
+ node = Corona.poll :host=>@host, :community=>community
79
81
  raise NoNode, 'node not found' unless node
80
- @node = Node.new :name=>host, :model=>node[:model]
82
+ @node = Node.new :name=>@host, :model=>node[:model]
81
83
  end
82
84
  @node.auth[:username] = username if username
83
85
  @node.auth[:password] = password if password
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'oxidized-script'
3
- s.version = '0.2.0'
3
+ s.version = '0.3.0'
4
4
  s.licenses = %w( Apache-2.0 )
5
5
  s.platform = Gem::Platform::RUBY
6
6
  s.authors = [ 'Saku Ytti' ]
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: oxidized-script
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Saku Ytti
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-07-11 00:00:00.000000000 Z
11
+ date: 2016-08-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: oxidized