shopify-junos-ez-stdlib 1.0.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.
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