shopify-junos-ez-stdlib 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +91 -0
  3. data/LICENSE +26 -0
  4. data/README.md +199 -0
  5. data/docs/Facts.md +192 -0
  6. data/docs/Providers/Group.md +61 -0
  7. data/docs/Providers/IPports.md +61 -0
  8. data/docs/Providers/L1ports.md +29 -0
  9. data/docs/Providers/L2ports.md +43 -0
  10. data/docs/Providers/LAGports.md +57 -0
  11. data/docs/Providers/StaticHosts.md +26 -0
  12. data/docs/Providers/StaticRoutes.md +37 -0
  13. data/docs/Providers/UserAuths.md +32 -0
  14. data/docs/Providers/Users.md +122 -0
  15. data/docs/Providers/Vlans.md +43 -0
  16. data/docs/Providers_Resources.md +353 -0
  17. data/docs/README_FIRST.md +27 -0
  18. data/docs/Utils/Config.md +160 -0
  19. data/docs/Utils/Filesystem.md +360 -0
  20. data/docs/Utils/Routing-Engine.md +379 -0
  21. data/docs/Utils/SCP.md +24 -0
  22. data/examples/config/config_file.rb +72 -0
  23. data/examples/config/config_template_object.rb +81 -0
  24. data/examples/config/config_template_simple.rb +76 -0
  25. data/examples/config/multi_config.rb +60 -0
  26. data/examples/fs_utils.rb +31 -0
  27. data/examples/lag_port.rb +27 -0
  28. data/examples/re_upgrade.rb +99 -0
  29. data/examples/re_utils.rb +33 -0
  30. data/examples/simple.rb +46 -0
  31. data/examples/st_hosts.rb +33 -0
  32. data/examples/user.rb +32 -0
  33. data/examples/vlans.rb +31 -0
  34. data/junos-ez-stdlib.gemspec +15 -0
  35. data/lib/junos-ez/exceptions.rb +3 -0
  36. data/lib/junos-ez/facts.rb +83 -0
  37. data/lib/junos-ez/facts/chassis.rb +51 -0
  38. data/lib/junos-ez/facts/ifd_style.rb +17 -0
  39. data/lib/junos-ez/facts/personality.rb +25 -0
  40. data/lib/junos-ez/facts/switch_style.rb +31 -0
  41. data/lib/junos-ez/facts/version.rb +58 -0
  42. data/lib/junos-ez/group.rb +206 -0
  43. data/lib/junos-ez/ip_ports.rb +30 -0
  44. data/lib/junos-ez/ip_ports/classic.rb +188 -0
  45. data/lib/junos-ez/l1_ports.rb +121 -0
  46. data/lib/junos-ez/l1_ports/classic.rb +87 -0
  47. data/lib/junos-ez/l1_ports/switch.rb +134 -0
  48. data/lib/junos-ez/l2_ports.rb +66 -0
  49. data/lib/junos-ez/l2_ports/bridge_domain.rb +499 -0
  50. data/lib/junos-ez/l2_ports/vlan.rb +433 -0
  51. data/lib/junos-ez/l2_ports/vlan_l2ng.rb +502 -0
  52. data/lib/junos-ez/lag_ports.rb +268 -0
  53. data/lib/junos-ez/provider.rb +619 -0
  54. data/lib/junos-ez/stdlib.rb +18 -0
  55. data/lib/junos-ez/system.rb +48 -0
  56. data/lib/junos-ez/system/st_hosts.rb +92 -0
  57. data/lib/junos-ez/system/st_routes.rb +159 -0
  58. data/lib/junos-ez/system/syscfg.rb +103 -0
  59. data/lib/junos-ez/system/userauths.rb +84 -0
  60. data/lib/junos-ez/system/users.rb +217 -0
  61. data/lib/junos-ez/utils/config.rb +236 -0
  62. data/lib/junos-ez/utils/fs.rb +385 -0
  63. data/lib/junos-ez/utils/re.rb +558 -0
  64. data/lib/junos-ez/version.rb +6 -0
  65. data/lib/junos-ez/vlans.rb +38 -0
  66. data/lib/junos-ez/vlans/bridge_domain.rb +89 -0
  67. data/lib/junos-ez/vlans/vlan.rb +119 -0
  68. data/lib/junos-ez/vlans/vlan_l2ng.rb +126 -0
  69. data/shipit.yml +4 -0
  70. data/tmp +7 -0
  71. metadata +129 -0
@@ -0,0 +1,33 @@
1
+ require 'pry'
2
+ require 'pp'
3
+ require 'net/scp'
4
+ require 'net/netconf/jnpr'
5
+ require 'junos-ez/stdlib'
6
+
7
+ # login information for NETCONF session
8
+ unless ARGV[0]
9
+ puts "You must specify a target"
10
+ exit 1
11
+ end
12
+
13
+ login = { :target => ARGV[0], :username => 'jeremy', :password => 'jeremy1', }
14
+
15
+ ## create a NETCONF object to manage the device and open the connection ...
16
+
17
+ ndev = Netconf::SSH.new( login )
18
+ print "Connecting to device #{login[:target]} ... "
19
+ ndev.open
20
+ puts "OK!"
21
+
22
+ binding.pry
23
+
24
+ ## attach our private & utils that we need ...
25
+
26
+ Junos::Ez::Provider( ndev )
27
+ Junos::Ez::RE::Utils( ndev, :re )
28
+ Junos::Ez::FS::Utils( ndev, :fs )
29
+ Junos::Ez::Config::Utils( ndev, :cu )
30
+
31
+ binding.pry
32
+
33
+ ndev.close
@@ -0,0 +1,46 @@
1
+ require 'pry'
2
+ require 'yaml'
3
+ require 'net/netconf/jnpr'
4
+ require 'junos-ez/stdlib'
5
+
6
+ unless ARGV[0]
7
+ puts "You must specify a target"
8
+ exit 1
9
+ end
10
+
11
+ # login information for NETCONF session
12
+ login = { :target => ARGV[0], :username => 'jeremy', :password => 'jeremy1', }
13
+
14
+ ## create a NETCONF object to manage the device and open the connection ...
15
+
16
+ ndev = Netconf::SSH.new( login )
17
+ $stdout.print "Connecting to device #{login[:target]} ... "
18
+ ndev.open
19
+ $stdout.puts "OK!"
20
+
21
+ ## Now bind providers to the device object.
22
+ ## the 'Junos::Ez::Provider' must be first before all others
23
+ ## this provider will setup the device 'facts'. The other providers
24
+ ## allow you to define the instance variables; so this example
25
+ ## is using 'l1_ports' and 'ip_ports', but you could name them
26
+ ## what you like, yo!
27
+
28
+ Junos::Ez::Provider( ndev )
29
+ Junos::Ez::L1ports::Provider( ndev, :l1_ports )
30
+ Junos::Ez::IPports::Provider( ndev, :ip_ports )
31
+
32
+ ## drop into interactive mode to play around ... let's look
33
+ ## at what the device has for facts ...
34
+
35
+ #-> ndev.facts.list
36
+ #-> ndev.facts.catalog
37
+ #-> ndev.fact :version
38
+
39
+ ## now look at specific providers like the physical (l1) ports ...
40
+
41
+ #-> ndev.l1_ports.list
42
+ #-> ndev.l1_ports.catalog
43
+
44
+ binding.pry
45
+
46
+ ndev.close
@@ -0,0 +1,33 @@
1
+ require 'pry'
2
+ require 'pp'
3
+ require 'yaml'
4
+ require 'net/netconf/jnpr'
5
+ require 'junos-ez/stdlib'
6
+
7
+ # login information for NETCONF session
8
+
9
+ login = { :target => ARGV[0], :username => 'jeremy', :password => 'jeremy1', }
10
+
11
+ ## create a NETCONF object to manage the device and open the connection ...
12
+
13
+ ndev = Netconf::SSH.new( login )
14
+ $stdout.print "Connecting to device #{login[:target]} ... "
15
+ ndev.open
16
+ $stdout.puts "OK!"
17
+
18
+ ## Now bind providers to the device object.
19
+ ## the 'Junos::Ez::Provider' must be first before all others
20
+ ## this provider will setup the device 'facts'. The other providers
21
+ ## allow you to define the instance variables; so this example
22
+ ## is using 'l1_ports' and 'ip_ports', but you could name them
23
+ ## what you like, yo!
24
+
25
+ Junos::Ez::Provider( ndev )
26
+ Junos::Ez::StaticHosts::Provider( ndev, :hosts )
27
+
28
+ pp ndev.hosts.list
29
+ pp ndev.hosts.catalog
30
+
31
+ binding.pry
32
+
33
+ ndev.close
data/examples/user.rb ADDED
@@ -0,0 +1,32 @@
1
+ require 'pry'
2
+ require 'yaml'
3
+ require 'net/netconf/jnpr'
4
+ require 'junos-ez/stdlib'
5
+ require 'junos-ez/srx'
6
+
7
+ unless ARGV[0]
8
+ puts "You must specify a target"
9
+ exit 1
10
+ end
11
+
12
+ # login information for NETCONF session
13
+ login = { :target => ARGV[0], :username => 'jeremy', :password => 'jeremy1', }
14
+
15
+ ## create a NETCONF object to manage the device and open the connection ...
16
+
17
+ ndev = Netconf::SSH.new( login )
18
+ $stdout.print "Connecting to device #{login[:target]} ... "
19
+ ndev.open
20
+ $stdout.puts "OK!"
21
+
22
+ Junos::Ez::Provider( ndev )
23
+ Junos::Ez::Users::Provider( ndev, :users )
24
+ Junos::Ez::UserAuths::Provider( ndev, :sshkeys )
25
+ Junos::Ez::Config::Utils( ndev, :cu )
26
+
27
+ user = ndev.users["jeremy"]
28
+ user.load_ssh_key! :filename=>'/home/jschulman/.ssh/keys/key1.pub'
29
+
30
+ binding.pry
31
+
32
+ ndev.close
data/examples/vlans.rb ADDED
@@ -0,0 +1,31 @@
1
+ require 'net/netconf/jnpr'
2
+ require 'junos-ez/stdlib'
3
+
4
+ unless ARGV[0]
5
+ puts "You must specify a target"
6
+ exit 1
7
+ end
8
+
9
+ # login information for NETCONF session
10
+ login = { :target => ARGV[0], :username => 'jeremy', :password => 'jeremy1', }
11
+
12
+ ## create a NETCONF object to manage the device and open the connection ...
13
+
14
+ ndev = Netconf::SSH.new( login )
15
+ $stdout.print "Connecting to device #{login[:target]} ... "
16
+ ndev.open
17
+ $stdout.puts "OK!"
18
+
19
+ Junos::Ez::Provider( ndev )
20
+ Junos::Ez::Config::Utils( ndev, :cu )
21
+ Junos::Ez::Vlans::Provider( ndev, :vlans )
22
+ #Junos::Ez::L1ports::Provider( ndev, :l1_ports )
23
+ Junos::Ez::L2ports::Provider( ndev, :l2_ports )
24
+ #Junos::Ez::IPports::Provider( ndev, :ip_ports )
25
+
26
+ #pp ndev.vlans.list
27
+ #pp ndev.vlans.catalog
28
+
29
+ binding.pry
30
+
31
+ ndev.close
@@ -0,0 +1,15 @@
1
+ $LOAD_PATH.unshift 'lib'
2
+ require 'rake'
3
+ require 'junos-ez/version'
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = 'shopify-junos-ez-stdlib'
7
+ s.version = Junos::Ez::VERSION
8
+ s.summary = "Junos EZ Framework - Standard Libraries"
9
+ s.description = "Automation Framework for Junos/NETCONF: Facts, Providers, and Utils"
10
+ s.homepage = 'https://github.com/Juniper/ruby-junos-ez-stdlib'
11
+ s.authors = ["Jeremy Schulman", "John Deatherage", "Nitin Kumar", "Priyal Jain", "Ganesh Nalawade"]
12
+ s.email = 'jnpr-community-netdev@juniper.net'
13
+ s.files = FileList[ '*', 'lib/**/*.rb', 'examples/**/*.rb', 'docs/**/*.md' ]
14
+ s.add_dependency('netconf', ">= 0.2.5")
15
+ end
@@ -0,0 +1,3 @@
1
+ module Junos::Ez
2
+ class NoProviderError < StandardError; end
3
+ end
@@ -0,0 +1,83 @@
1
+ require 'junos-ez/provider'
2
+
3
+ ### -----------------------------------------------------------------
4
+ ### Junos::Ez module devices the toplevel Provider and associated
5
+ ### Facts class & methods
6
+ ### -----------------------------------------------------------------
7
+
8
+ module Junos::Ez
9
+
10
+ attr_accessor :providers, :facts
11
+
12
+ def self.Provider( ndev )
13
+ ndev.extend Junos::Ez
14
+ ndev.providers = []
15
+ ndev.facts = Junos::Ez::Facts::Keeper.new( ndev )
16
+ ndev.facts.read!
17
+ true
18
+ end
19
+
20
+ def fact( name ); facts[name] end
21
+ end;
22
+
23
+ module Junos::Ez::Facts
24
+
25
+ class Keeper
26
+ attr_accessor :known
27
+
28
+ def initialize( ndev )
29
+ @ndev = ndev
30
+ @known = Hash.new
31
+ end
32
+
33
+ def clear; @known.clear end
34
+
35
+ def list; @known.keys end
36
+ def list!; read!; list; end
37
+
38
+ def catalog; @known end
39
+ def catalog!; read!; catalog end
40
+
41
+ def uses( *facts )
42
+ values = facts.collect do |f|
43
+ self.send( "fact_read_#{f}", @ndev, @known ) unless @known[f]
44
+ self[f]
45
+ end
46
+ (values.count == 1) ? values[0] : values
47
+ end
48
+
49
+ def self.define( fact, &block )
50
+ define_method( "fact_read_#{fact}".to_sym, block )
51
+ end
52
+
53
+ def []=(key,value)
54
+ @known[key] = value
55
+ end
56
+
57
+ def [](key)
58
+ @known[key]
59
+ end
60
+
61
+ def read!
62
+ @known.clear
63
+ fact_readers = self.methods.grep /^fact_read_/
64
+ fact_readers.each do |getter|
65
+ getter =~ /^fact_read_(\w+)/
66
+ fact = $1.to_sym
67
+ self.send( getter, @ndev, @known ) unless @known[fact]
68
+ end
69
+ end
70
+
71
+ end # class
72
+ end
73
+
74
+ ### -----------------------------------------------------------------
75
+ ### Load all of the fact files
76
+ ### -----------------------------------------------------------------
77
+
78
+ require 'junos-ez/facts/chassis'
79
+ require 'junos-ez/facts/personality'
80
+ require 'junos-ez/facts/version'
81
+ require 'junos-ez/facts/switch_style'
82
+ require 'junos-ez/facts/ifd_style'
83
+
@@ -0,0 +1,51 @@
1
+ Junos::Ez::Facts::Keeper.define( :chassis ) do |ndev, facts|
2
+
3
+ inv_info = ndev.rpc.get_chassis_inventory
4
+ errs = inv_info.xpath('//output')[0]
5
+
6
+ if errs and errs.text.include? "This command can only be used on the master routing engine"
7
+ raise Junos::Ez::NoProviderError, "Chef can only be used on master routing engine !!"
8
+ end
9
+
10
+ chassis = inv_info.xpath('chassis')
11
+
12
+ facts[:hardwaremodel] = chassis.xpath('description').text
13
+ facts[:serialnumber] = chassis.xpath('serial-number').text
14
+
15
+ cfg = ndev.rpc.get_configuration{|xml|
16
+ xml.system {
17
+ xml.send(:'host-name')
18
+ xml.send(:'domain-name')
19
+ }
20
+ }
21
+
22
+ facts[:hostname] = cfg.xpath('//host-name').text
23
+ facts[:domain] = cfg.xpath('//domain-name').text
24
+ facts[:fqdn] = facts[:hostname]
25
+ facts[:fqdn] += ".#{facts[:domain]}" unless facts[:domain].empty?
26
+
27
+ end
28
+
29
+ Junos::Ez::Facts::Keeper.define( :master ) do |ndev, facts|
30
+ uses :routingengines
31
+ end
32
+
33
+ Junos::Ez::Facts::Keeper.define( :routingengines ) do |ndev, facts|
34
+
35
+ re_facts = ['mastership-state','status','model','up-time','last-reboot-reason']
36
+ re_info = ndev.rpc.get_route_engine_information
37
+ re_info.xpath('//route-engine').each do |re|
38
+ slot_id = re.xpath('slot').text || "0"
39
+ slot = ("RE" + slot_id).to_sym
40
+ facts[slot] = Hash[ re_facts.collect{ |ele| [ ele.tr('-','_').to_sym, re.xpath(ele).text ] } ]
41
+ if facts[slot][:mastership_state].empty?
42
+ facts[slot].delete :mastership_state
43
+ else
44
+ facts[:master] = slot_id if facts[slot][:mastership_state] == 'master'
45
+ end
46
+ end
47
+
48
+ end
49
+
50
+
51
+
@@ -0,0 +1,17 @@
1
+ Junos::Ez::Facts::Keeper.define( :ifd_style ) do |ndev, facts|
2
+ persona,sw_style = uses :personality,:switch_style
3
+
4
+ facts[:ifd_style] = case persona
5
+ when :SWITCH
6
+ if sw_style == :VLAN_L2NG
7
+ :CLASSIC
8
+ else
9
+ :SWITCH
10
+ end
11
+ else
12
+ :CLASSIC
13
+ end
14
+
15
+ end
16
+
17
+
@@ -0,0 +1,25 @@
1
+ Junos::Ez::Facts::Keeper.define( :personality ) do |ndev, facts|
2
+
3
+ uses :chassis, :routingengines
4
+ model = facts[:hardwaremodel]
5
+
6
+ examine = ( model != "Virtual Chassis" ) ? model : facts.select {|k,v| k.match(/^RE[0..9]+/) }.values[0][:model]
7
+
8
+ facts[:personality] = case examine
9
+ when /^(EX)|(QFX)|(OCX)/i
10
+ :SWITCH
11
+ when /^MX/i
12
+ :MX
13
+ when /^vMX/i
14
+ facts[:virtual] = true
15
+ :MX
16
+ when /SRX(\d){3}/i
17
+ :SRX_BRANCH
18
+ when /junosv-firefly/i
19
+ facts[:virtual] = true
20
+ :SRX_BRANCH
21
+ when /SRX(\d){4}/i
22
+ :SRX_HIGHEND
23
+ end
24
+
25
+ end
@@ -0,0 +1,31 @@
1
+ Junos::Ez::Facts::Keeper.define( :switch_style ) do |ndev, facts|
2
+ f_persona = uses :personality
3
+
4
+ model = facts[:hardwaremodel]
5
+ examine = ( model != "Virtual Chassis" ) ? model : facts.select {|k,v| k.match(/^RE[0-9]+/) }.values[0][:model]
6
+
7
+ facts[:switch_style] = case f_persona
8
+ when :SWITCH, :SRX_BRANCH
9
+ case examine
10
+ when /junosv-firefly/i
11
+ :NONE
12
+ when /^(ex9)|(ex43)|(ocx)/i
13
+ :VLAN_L2NG
14
+ when /^(qfx)/i
15
+ if facts[:version][0..3].to_f >= 13.2
16
+ :VLAN_L2NG
17
+ else
18
+ :VLAN
19
+ end
20
+ else
21
+ :VLAN
22
+ end
23
+ when :MX, :SRX_HIGHEND
24
+ :BRIDGE_DOMAIN
25
+ else
26
+ :NONE
27
+ end
28
+
29
+ end
30
+
31
+
@@ -0,0 +1,58 @@
1
+ Junos::Ez::Facts::Keeper.define( :version ) do |ndev, facts|
2
+
3
+ f_master, f_persona = uses :master, :personality
4
+
5
+ case f_persona
6
+ when :MX
7
+ begin
8
+ swver = ndev.rpc.command "show version invoke-on all-routing-engines"
9
+ rescue Netconf::RpcError
10
+ swver = ndev.rpc.command "show version"
11
+ end
12
+ when :SWITCH
13
+ ## most EX switches support the virtual-chassis feature, so the 'all-members' option would be valid
14
+ ## in some products, this options is not valid (i.e. not vc-capable. so we're going to try for vc, and if that
15
+ ## throws an exception we'll rever to non-VC
16
+
17
+ begin
18
+ swver = ndev.rpc.command "show version all-members"
19
+ rescue Netconf::RpcError
20
+ facts[:vc_capable] = false
21
+ swver = ndev.rpc.command "show version"
22
+ else
23
+ facts[:vc_capable] = true
24
+ end
25
+ else
26
+ swver = ndev.rpc.command "show version"
27
+ end
28
+
29
+ if swver.name == 'multi-routing-engine-results'
30
+ swver_infos = swver.xpath('//software-information')
31
+ swver_infos.each do |re_sw|
32
+ re_name = re_sw.xpath('preceding-sibling::re-name').text.upcase
33
+ ver_key = ('version_' + re_name).to_sym
34
+
35
+ if re_sw.at_xpath('//junos-version')
36
+ facts[ver_key] = re_sw.xpath('//junos-version').text
37
+ else
38
+ re_sw.xpath('package-information[1]/comment').text =~ /\[(.*)\]/
39
+ facts[ver_key] = $1
40
+ end
41
+ end
42
+ master_id = f_master
43
+ unless master_id.nil?
44
+ facts[:version] =
45
+ facts[("version_" + "RE" + master_id).to_sym] ||
46
+ facts[('version_' + "FPC" + master_id).to_sym]
47
+ end
48
+ else
49
+ if swver.at_xpath('//junos-version')
50
+ facts[:version] = swver.xpath('//junos-version').text
51
+ else
52
+ junos = swver.xpath('//package-information[name = "junos"]/comment').text
53
+ junos =~ /\[(.*)\]/
54
+ facts[:version] = $1
55
+ end
56
+ end
57
+
58
+ end