junos-ez-stdlib 0.0.10

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 (52) hide show
  1. data/LICENSE +26 -0
  2. data/README.md +181 -0
  3. data/docs/Config_Utils.md +3 -0
  4. data/docs/Facts.md +106 -0
  5. data/docs/Filesys_Utils.md +3 -0
  6. data/docs/IPports.md +3 -0
  7. data/docs/L1ports.md +3 -0
  8. data/docs/L2ports.md +3 -0
  9. data/docs/Providers_Resources.md +304 -0
  10. data/docs/RE_utils.md +3 -0
  11. data/docs/StaticHosts.md +3 -0
  12. data/docs/StaticRoutes.md +3 -0
  13. data/docs/Vlans.md +3 -0
  14. data/examples/config/config_file.rb +72 -0
  15. data/examples/config/config_template_object.rb +81 -0
  16. data/examples/config/config_template_simple.rb +76 -0
  17. data/examples/config/multi_config.rb +60 -0
  18. data/examples/fs_utils.rb +31 -0
  19. data/examples/re_upgrade.rb +90 -0
  20. data/examples/re_utils.rb +30 -0
  21. data/examples/simple.rb +47 -0
  22. data/examples/st_hosts.rb +33 -0
  23. data/examples/vlans.rb +25 -0
  24. data/junos-ez-stdlib.gemspec +15 -0
  25. data/lib/junos-ez/facts/chassis.rb +45 -0
  26. data/lib/junos-ez/facts/ifd_style.rb +14 -0
  27. data/lib/junos-ez/facts/personality.rb +22 -0
  28. data/lib/junos-ez/facts/switch_style.rb +22 -0
  29. data/lib/junos-ez/facts/version.rb +32 -0
  30. data/lib/junos-ez/facts.rb +85 -0
  31. data/lib/junos-ez/ip_ports/classic.rb +149 -0
  32. data/lib/junos-ez/ip_ports.rb +28 -0
  33. data/lib/junos-ez/l1_ports/classic.rb +87 -0
  34. data/lib/junos-ez/l1_ports/switch.rb +134 -0
  35. data/lib/junos-ez/l1_ports.rb +81 -0
  36. data/lib/junos-ez/l2_ports/bridge_domain.rb +0 -0
  37. data/lib/junos-ez/l2_ports/vlan.rb +317 -0
  38. data/lib/junos-ez/l2_ports/vlan_l2ng.rb +0 -0
  39. data/lib/junos-ez/l2_ports.rb +57 -0
  40. data/lib/junos-ez/provider.rb +608 -0
  41. data/lib/junos-ez/stdlib.rb +16 -0
  42. data/lib/junos-ez/system/st_hosts.rb +74 -0
  43. data/lib/junos-ez/system/st_routes.rb +135 -0
  44. data/lib/junos-ez/system/syscfg.rb +103 -0
  45. data/lib/junos-ez/system.rb +98 -0
  46. data/lib/junos-ez/utils/config.rb +205 -0
  47. data/lib/junos-ez/utils/fs.rb +376 -0
  48. data/lib/junos-ez/utils/re.rb +371 -0
  49. data/lib/junos-ez/vlans/bridge_domain.rb +85 -0
  50. data/lib/junos-ez/vlans/vlan.rb +112 -0
  51. data/lib/junos-ez/vlans.rb +31 -0
  52. metadata +111 -0
@@ -0,0 +1,135 @@
1
+ class Junos::Ez::StaticRoutes::Provider
2
+
3
+ ### ---------------------------------------------------------------
4
+ ### XML top placement
5
+ ### ---------------------------------------------------------------
6
+
7
+ def xml_at_top
8
+ @name = "0.0.0.0/0" if @name == :default
9
+
10
+ Nokogiri::XML::Builder.new {|xml| xml.configuration {
11
+ xml.send('routing-options') {
12
+ xml.static { xml.route {
13
+ xml.name @name
14
+ return xml
15
+ }}
16
+ }
17
+ }}
18
+ end
19
+
20
+ ### ---------------------------------------------------------------
21
+ ### XML property readers
22
+ ### ---------------------------------------------------------------
23
+
24
+ def xml_get_has_xml( xml )
25
+ xml.xpath('routing-options/static/route')[0]
26
+ end
27
+
28
+ def xml_read_parser( as_xml, as_hash )
29
+ set_has_status( as_xml, as_hash )
30
+
31
+ ## :gateway
32
+ unless (next_hop = as_xml.xpath('next-hop')).empty?
33
+ if next_hop.count == 1
34
+ as_hash[:gateway] = next_hop.text
35
+ else
36
+ as_hash[:gateway] = next_hop.collect{|i| i.text }
37
+ end
38
+ end
39
+
40
+ unless (active = as_xml.xpath('active')).empty?
41
+ as_hash[:active] = true
42
+ end
43
+
44
+ unless (action = as_xml.xpath( 'reject | discard | receive' )).empty?
45
+ as_hash[:action] = action[0].name.to_sym
46
+ end
47
+
48
+ unless (metric = as_xml.xpath('metric')).empty?
49
+ as_hash[:metric] = metric.text.to_i
50
+ end
51
+
52
+ xml_read_parse_noele( as_xml, 'retain', as_hash, :retain )
53
+ xml_read_parse_noele( as_xml, 'install', as_hash, :install )
54
+ xml_read_parse_noele( as_xml, 'resolve', as_hash, :resolve )
55
+ xml_read_parse_noele( as_xml, 'readvertise', as_hash, :readvertise )
56
+ end
57
+
58
+
59
+ ### ---------------------------------------------------------------
60
+ ### XML property writers
61
+ ### ---------------------------------------------------------------
62
+
63
+ def xml_change_action( xml )
64
+
65
+ if @should[:action].nil?
66
+ xml.send( @has[:action], Netconf::JunosConfig::DELETE )
67
+ return true
68
+ end
69
+
70
+ xml.send( @should[:action] )
71
+ end
72
+
73
+ def xml_change_active( xml )
74
+ xml_set_or_delete_element( xml, 'active', @should[:active] )
75
+ end
76
+
77
+ def xml_change_gateway( xml )
78
+ # delete existing entries
79
+ ele_nh = :'next-hop'
80
+
81
+ # clear any existing values, and return unless there are any new ones ...
82
+ xml.send(ele_nh, Netconf::JunosConfig::DELETE) if @has[:gateway]
83
+ return true unless @should[:gateway]
84
+
85
+ ## adding back the ones we want now ...
86
+ if @should[:gateway].kind_of? String
87
+ xml.send( ele_nh, @should[:gateway] )
88
+ else
89
+ @should[:gateway].each{ |gw| xml.send( ele_nh, gw ) }
90
+ end
91
+ end
92
+
93
+ def xml_change_retain( xml )
94
+ xml_set_or_delete_noele( xml, 'retain' )
95
+ end
96
+
97
+ def xml_change_install( xml )
98
+ xml_set_or_delete_noele( xml, 'install' )
99
+ end
100
+
101
+ def xml_change_resolve( xml )
102
+ xml_set_or_delete_noele( xml, 'resolve' )
103
+ end
104
+
105
+ def xml_change_readvertise( xml )
106
+ xml_set_or_delete_noele( xml, 'readvertise' )
107
+ end
108
+
109
+ def xml_change_metric( xml )
110
+ xml_set_or_delete( xml, 'metric', @should[:metric] )
111
+ end
112
+
113
+
114
+ end
115
+
116
+ ##### ---------------------------------------------------------------
117
+ ##### Provider collection methods
118
+ ##### ---------------------------------------------------------------
119
+
120
+ class Junos::Ez::StaticRoutes::Provider
121
+
122
+ def build_list
123
+ @ndev.rpc.get_configuration{|xml| xml.send(:'routing-options') {
124
+ xml.static { xml.route }
125
+ }}.xpath('//route/name').collect do |item|
126
+ item.text
127
+ end
128
+ end
129
+
130
+ def build_catalog
131
+ @catalog = {}
132
+ @catalog
133
+ end
134
+
135
+ end
@@ -0,0 +1,103 @@
1
+ class Junos::Ez::SysConfig::Provider
2
+
3
+ ### ---------------------------------------------------------------
4
+ ### XML top placement
5
+ ### ---------------------------------------------------------------
6
+
7
+ def xml_at_top
8
+ xml = Nokogiri::XML::Builder.new {|xml| xml.configuration {
9
+ xml.system {
10
+ return xml
11
+ }
12
+ }}
13
+ end
14
+
15
+ def xml_config_read!
16
+ xml = xml_at_top
17
+ xml.send(:'host-name')
18
+ xml.send(:'domain-name')
19
+ xml.send(:'domain-search')
20
+ xml.send(:'time-zone')
21
+ xml.location
22
+ xml.send(:'name-server')
23
+ xml.ntp
24
+ @ndev.rpc.get_configuration( xml )
25
+ end
26
+
27
+ ### ---------------------------------------------------------------
28
+ ### XML property readers
29
+ ### ---------------------------------------------------------------
30
+
31
+ def xml_get_has_xml( xml )
32
+ xml.xpath('system')[0]
33
+ end
34
+
35
+ def xml_read_parser( as_xml, as_hash )
36
+ set_has_status( as_xml, as_hash )
37
+ as_hash[:host_name] = as_xml.xpath('host-name').text
38
+ unless (data = as_xml.xpath('domain-name')).empty?
39
+ as_hash[:domain_name] = data.text
40
+ end
41
+ unless (data = as_xml.xpath('domain-search')).empty?
42
+ as_hash[:domain_search] = data.collect{|i| i.text}
43
+ end
44
+ unless (data = as_xml.xpath('time-zone')).empty?
45
+ as_hash[:timezone] = data.text
46
+ end
47
+ unless (data = as_xml.xpath('name-server/name')).empty?
48
+ as_hash[:dns_servers] = data.collect{|i| i.text}
49
+ end
50
+ unless (data = as_xml.xpath('ntp/server/name')).empty?
51
+ as_hash[:ntp_servers] = data.collect{|i| i.text}
52
+ end
53
+ unless (location = as_xml.xpath('location')).empty?
54
+ as_hash[:location] = {}
55
+ unless (data = location.xpath('building')).empty?
56
+ as_hash[:location][:building] = data.text
57
+ end
58
+ unless (data = location.xpath('country-code')).empty?
59
+ as_hash[:location][:countrycode] = data.text
60
+ end
61
+ unless (data = location.xpath('floor')).empty?
62
+ as_hash[:location][:floor] = data.text
63
+ end
64
+ unless (data = location.xpath('rack')).empty?
65
+ as_hash[:location][:rack] = data.text
66
+ end
67
+ end
68
+ end
69
+
70
+ ### ---------------------------------------------------------------
71
+ ### XML property writers
72
+ ### ---------------------------------------------------------------
73
+
74
+ def xml_change_host_name( xml )
75
+ xml.send(:'host-name', @should[:host_name] )
76
+ end
77
+
78
+ def xml_change_domain_name( xml )
79
+ xml.send(:'domain-name', @should[:domain_name] )
80
+ end
81
+
82
+ def xml_change_domain_search( xml )
83
+ end
84
+
85
+ def xml_change_timezone( xml )
86
+ xml.send(:'time-zone', @should[:timezone])
87
+ end
88
+
89
+ def xml_change_dns_servers( xml )
90
+ end
91
+
92
+ def xml_change_ntp_servers( xml )
93
+ end
94
+
95
+ def xml_change_date( xml )
96
+ end
97
+
98
+ def xml_change_location( xml )
99
+ end
100
+
101
+ end
102
+
103
+
@@ -0,0 +1,98 @@
1
+
2
+ require "junos-ez/provider"
3
+
4
+ ### -----------------------------------------------------------------
5
+ ### manage static host entries, kinda like "/etc/hosts"
6
+ ### -----------------------------------------------------------------
7
+
8
+ module Junos::Ez::StaticHosts
9
+
10
+ PROPERTIES = [
11
+ :ip, # ipv4 address :String
12
+ :ip6, # ipv6 address :String
13
+ ]
14
+
15
+ def self.Provider( ndev, varsym )
16
+ newbie = Junos::Ez::StaticHosts::Provider.new( ndev )
17
+ newbie.properties = Junos::Ez::Provider::PROPERTIES + PROPERTIES
18
+ Junos::Ez::Provider.attach_instance_variable( ndev, varsym, newbie )
19
+ end
20
+
21
+ class Provider < Junos::Ez::Provider::Parent
22
+ end
23
+
24
+ end
25
+
26
+ require 'junos-ez/system/st_hosts'
27
+
28
+ ### -----------------------------------------------------------------
29
+ ### manage static route entries
30
+ ### -----------------------------------------------------------------
31
+
32
+ module Junos::Ez::StaticRoutes
33
+
34
+ PROPERTIES = [
35
+ :gateway, # next-hop gateway, could be single or Array
36
+ :metric, # number or nil
37
+ :action, # one-of [ :reject, :discard, :receive ]
38
+ :active, # flag [ true, nil | false ]
39
+ :retain, # no-flag [ nil, true, false ]
40
+ :install, # no-flag [ nil, true, false ]
41
+ :readvertise, # no-flag [ nil, true, false ]
42
+ :resolve, # no-flag [ nil, true, false ]
43
+ ]
44
+
45
+ def self.Provider( ndev, varsym )
46
+ newbie = Junos::Ez::StaticRoutes::Provider.new( ndev )
47
+ newbie.properties = Junos::Ez::Provider::PROPERTIES + PROPERTIES
48
+ Junos::Ez::Provider.attach_instance_variable( ndev, varsym, newbie )
49
+ end
50
+
51
+ class Provider < Junos::Ez::Provider::Parent
52
+ end
53
+
54
+ end
55
+
56
+ require 'junos-ez/system/st_routes'
57
+
58
+ ### -----------------------------------------------------------------
59
+ ### the 'syscfg' is a work in progress, do not use ...
60
+ ### -----------------------------------------------------------------
61
+
62
+ module Junos::Ez::SysConfig
63
+
64
+ PROPERTIES = [
65
+ :host_name, # String, host-name
66
+ :domain_name, # domain name, string or array
67
+ :domain_search, # array of dns name suffix values
68
+ :dns_servers, # array of ip-addrs
69
+ :ntp_servers, # array NTP servers HASH of
70
+ # :version
71
+ # :key
72
+ :timezone, # String time-zone
73
+ :date, # String format: YYYYMMDDhhmm.ss
74
+ :location, # location HASH with properties
75
+ # :countrycode
76
+ # :building,
77
+ # :floor,
78
+ # :rack
79
+ ]
80
+
81
+ def self.Provider( ndev, varsym )
82
+ raise ArgumentError "work-in-progress ..."
83
+
84
+ newbie = Junos::Ez::SysConfig::Provider.new( ndev )
85
+ newbie.properties = Junos::Ez::Provider::PROPERTIES + PROPERTIES
86
+ Junos::Ez::Provider.attach_instance_variable( ndev, varsym, newbie )
87
+ end
88
+
89
+ class Provider < Junos::Ez::Provider::Parent
90
+ end
91
+
92
+ end
93
+
94
+ require 'junos-ez/system/syscfg'
95
+
96
+
97
+
98
+
@@ -0,0 +1,205 @@
1
+ =begin
2
+ ---------------------------------------------------------------------
3
+ Config::Utils is a collection of methods used for loading
4
+ configuration files/templates and software images
5
+
6
+ commit! - commit configuration
7
+ commit? - see if a candidate config is OK (commit-check)
8
+ diff? - shows the diff of the candidate config w/current | rolback
9
+ load! - load configuration onto device
10
+ lock! - take exclusive lock on config
11
+ unlock! - release exclusive lock on config
12
+ rollback! - perform a config rollback
13
+
14
+ ---------------------------------------------------------------------
15
+ =end
16
+
17
+ module Junos::Ez::Config
18
+ def self.Utils( ndev, varsym )
19
+ newbie = Junos::Ez::Config::Provider.new( ndev )
20
+ Junos::Ez::Provider.attach_instance_variable( ndev, varsym, newbie )
21
+ end
22
+ end
23
+
24
+ ### -----------------------------------------------------------------
25
+ ### PUBLIC METHODS
26
+ ### -----------------------------------------------------------------
27
+ ### -----------------------------------------------------------------
28
+
29
+ class Junos::Ez::Config::Provider < Junos::Ez::Provider::Parent
30
+
31
+ ### ---------------------------------------------------------------
32
+ ### load! - used to load configuration files / templates. This
33
+ ### does not perform a 'commit', just the equivalent of the
34
+ ### load-configuration RPC
35
+ ###
36
+ ### --- options ---
37
+ ###
38
+ ### :filename => path - indcates the filename of content
39
+ ### note: filename extension will also define format
40
+ ### .{conf,text,txt} <==> :text
41
+ ### .xml <==> :xml
42
+ ### .set <==> :set
43
+ ###
44
+ ### :content => String - string content of data (vs. :filename)
45
+ ###
46
+ ### :format => [:text, :set, :xml], default :text (curly-brace)
47
+ ### this will override any auto-format from the :filename
48
+ ###
49
+ ### :binding - indicates file/content is an ERB
50
+ ### => <object> - will grab the binding from this object
51
+ ### using a bit of meta-programming magic
52
+ ### => <binding> - will use this binding
53
+ ###
54
+ ### :replace! => true - enables the 'replace' option
55
+ ### :overwrite! => true - enables the 'overwrite' optoin
56
+ ###
57
+ ### --- returns ---
58
+ ### true if the configuration is loaded OK
59
+ ### raise Netconf::EditError otherwise
60
+ ### ---------------------------------------------------------------
61
+
62
+ def load!( opts = {} )
63
+ raise ArgumentError unless opts[:content] || opts[:filename]
64
+
65
+ content = opts[:content] || File.read( opts[:filename] )
66
+
67
+ attrs = {}
68
+ attrs[:action] = 'replace' if opts[:replace!]
69
+ attrs[:action] = 'override' if opts[:override!]
70
+
71
+ if opts[:format]
72
+ attrs[:format] = opts[:format].to_s
73
+ elsif opts[:filename]
74
+ case f_ext = File.extname( opts[:filename] )
75
+ when '.conf','.text','.txt'; attrs[:format] = 'text'
76
+ when '.set'; attrs[:format] = 'set'
77
+ when '.xml'; # default is XML
78
+ else
79
+ raise ArgumentError, "unknown format from extension: #{f_ext}"
80
+ end
81
+ else
82
+ raise ArgumentError "unspecified format"
83
+ end
84
+
85
+ if opts[:binding]
86
+ erb = ERB.new( content, nil, '>' )
87
+ case opts[:binding]
88
+ when Binding
89
+ # binding was provided to use
90
+ content = erb.result( opts[:binding] )
91
+ when Object
92
+ obj = opts[:binding]
93
+ def obj.junos_ez_binding; binding end
94
+ content = erb.result( obj.junos_ez_binding )
95
+ class << obj; remove_method :junos_ez_binding end
96
+ end
97
+ end
98
+
99
+ @ndev.rpc.load_configuration( content, attrs )
100
+ true # everthing OK!
101
+ end
102
+
103
+ ### ---------------------------------------------------------------
104
+ ### commit! - commits the configuration to the device
105
+ ###
106
+ ### --- options ---
107
+ ###
108
+ ### :confirm => true | timeout
109
+ ### :comment => commit log comment
110
+ ###
111
+ ### --- returns ---
112
+ ### true if commit completed
113
+ ### raises Netconf::CommitError otherwise
114
+ ### ---------------------------------------------------------------
115
+
116
+ def commit!( opts = {} )
117
+
118
+ args = {}
119
+ args[:log] = opts[:comment] if opts[:comment]
120
+ if opts[:confirm]
121
+ args[:confirmed] = true
122
+ if opts[:confirm] != true
123
+ timeout = Integer( opts[:confirm] ) rescue false
124
+ raise ArgumentError "invalid timeout #{opts[:confirm]}" unless timeout
125
+ args[:confirm_timeout] = timeout
126
+ end
127
+ end
128
+
129
+ @ndev.rpc.commit_configuration( args )
130
+ true
131
+ end
132
+
133
+ ### ---------------------------------------------------------------
134
+ ### commit? - perform commit configuration check
135
+ ###
136
+ ### --- returns ---
137
+ ### true if candidate config is OK to commit
138
+ ### Array of rpc-error data otherwise
139
+ ### ---------------------------------------------------------------
140
+
141
+ def commit?
142
+ begin
143
+ @ndev.rpc.commit_configuration( :check => true )
144
+ rescue => e
145
+ return Junos::Ez::rpc_errors( e.rsp )
146
+ end
147
+ true # commit check OK!
148
+ end
149
+
150
+ ### ---------------------------------------------------------------
151
+ ### rollback! - used to rollback the configuration
152
+ ### ---------------------------------------------------------------
153
+
154
+ def rollback!( rollback_id = 0 )
155
+ raise ArgumentError, "invalid rollback #{rollback_id}" unless ( rollback_id >= 0 and rollback_id <= 50 )
156
+ @ndev.rpc.load_configuration( :compare=>'rollback', :rollback=> rollback_id.to_s )
157
+ true # rollback OK!
158
+ end
159
+
160
+ ### ---------------------------------------------------------------
161
+ ### diff? - displays diff (patch format) between
162
+ ### current candidate configuration loaded and the rollback_id
163
+ ###
164
+ ### --- returns ---
165
+ ### false if no diff
166
+ ### String of diff output otherwise
167
+ ### ---------------------------------------------------------------
168
+
169
+ def diff?( rollback_id = 0 )
170
+ raise ArgumentError, "invalid rollback #{rollback_id}" unless ( rollback_id >= 0 and rollback_id <= 50 )
171
+ got = ndev.rpc.get_configuration( :compare=>'rollback', :rollback=> rollback_id.to_s )
172
+ diff = got.xpath('configuration-output').text
173
+ return false if diff == "\n"
174
+ diff
175
+ end
176
+
177
+ ### ---------------------------------------------------------------
178
+ ### lock! - takes an exclusive lock on the candidate config
179
+ ###
180
+ ### --- returns ---
181
+ ### true if lock acquired
182
+ ### raise Netconf::LockError otherwise
183
+ ### ---------------------------------------------------------------
184
+
185
+ def lock!
186
+ @ndev.rpc.lock_configuration
187
+ true
188
+ end
189
+
190
+ ### ---------------------------------------------------------------
191
+ ### unlock! - releases exclusive lock on candidate config
192
+ ###
193
+ ### --- returns ---
194
+ ### true if lock release
195
+ ### raise Netconf::RpcError otherwise
196
+ ### ---------------------------------------------------------------
197
+
198
+ def unlock!
199
+ @ndev.rpc.unlock_configuration
200
+ true
201
+ end
202
+
203
+ end # class Provider
204
+
205
+