junos-ez-srx 0.0.8
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.
- data/LICENSE +26 -0
- data/README.md +83 -0
- data/examples/app_sets.rb +25 -0
- data/examples/apps.rb +20 -0
- data/examples/catalog_expanded.rb +31 -0
- data/examples/find_route.rb +20 -0
- data/examples/junos_srx_test.rb +78 -0
- data/examples/sample-change.rb +97 -0
- data/examples/simple.rb +22 -0
- data/examples/srx_dump_yaml.rb +48 -0
- data/examples/srx_load_yaml.rb +55 -0
- data/junos-ez-srx.gemspec +20 -0
- data/lib/junos-ez/srx.rb +150 -0
- data/lib/junos-ez/srx/abooke.rb +194 -0
- data/lib/junos-ez/srx/abooks.rb +164 -0
- data/lib/junos-ez/srx/apps.rb +160 -0
- data/lib/junos-ez/srx/appsets.rb +82 -0
- data/lib/junos-ez/srx/interfaces.rb +115 -0
- data/lib/junos-ez/srx/policies.rb +141 -0
- data/lib/junos-ez/srx/policyrules.rb +239 -0
- data/lib/junos-ez/srx/zones.rb +275 -0
- metadata +113 -0
@@ -0,0 +1,239 @@
|
|
1
|
+
class Junos::Ez::SRX::PolicyRules::Provider < Junos::Ez::Provider::Parent
|
2
|
+
|
3
|
+
### ---------------------------------------------------------------
|
4
|
+
### XML top placement
|
5
|
+
### ---------------------------------------------------------------
|
6
|
+
|
7
|
+
def xml_at_top
|
8
|
+
xml = @parent.xml_at_top
|
9
|
+
xml_element_top( xml, @name )
|
10
|
+
end
|
11
|
+
|
12
|
+
def xml_element_top( xml, name )
|
13
|
+
xml.policy {
|
14
|
+
xml.name name
|
15
|
+
return xml
|
16
|
+
}
|
17
|
+
end
|
18
|
+
|
19
|
+
### ---------------------------------------------------------------
|
20
|
+
### XML readers
|
21
|
+
### ---------------------------------------------------------------
|
22
|
+
|
23
|
+
def xml_get_has_xml( xml )
|
24
|
+
xml.xpath('security/policies/policy/policy')[0]
|
25
|
+
end
|
26
|
+
|
27
|
+
def xml_read_parser( as_xml, as_hash )
|
28
|
+
|
29
|
+
set_has_status( as_xml, as_hash )
|
30
|
+
|
31
|
+
r_match = as_xml.xpath('match')
|
32
|
+
r_then = as_xml.xpath('then')
|
33
|
+
|
34
|
+
descr = as_xml.xpath('description').text
|
35
|
+
as_hash[:description] = descr unless descr.empty?
|
36
|
+
|
37
|
+
## --------------------------------
|
38
|
+
## "match" criteria
|
39
|
+
## --------------------------------
|
40
|
+
|
41
|
+
as_hash[:match_srcs] = r_match.xpath('source-address').collect do |src|
|
42
|
+
src.text
|
43
|
+
end
|
44
|
+
as_hash[:match_dsts] = r_match.xpath('destination-address').collect do |dst|
|
45
|
+
dst.text
|
46
|
+
end
|
47
|
+
as_hash[:match_apps] = r_match.xpath('application').collect do |dst|
|
48
|
+
dst.text
|
49
|
+
end
|
50
|
+
|
51
|
+
## --------------------------------
|
52
|
+
## "then" criteria
|
53
|
+
## --------------------------------
|
54
|
+
|
55
|
+
action = r_then.xpath('permit | reject | deny')[0]
|
56
|
+
as_hash[:action] = action.name.to_sym
|
57
|
+
|
58
|
+
xml_when_item( r_then.xpath('count' )){ as_hash[:count] = true }
|
59
|
+
xml_when_item( r_then.xpath('log/session-init')){ as_hash[:log_init] = true }
|
60
|
+
xml_when_item( r_then.xpath('log/session-close')){ as_hash[:log_close] = true }
|
61
|
+
|
62
|
+
return true
|
63
|
+
end
|
64
|
+
|
65
|
+
### ---------------------------------------------------------------
|
66
|
+
### XML property writers
|
67
|
+
### ---------------------------------------------------------------
|
68
|
+
|
69
|
+
def xml_change_match_srcs( xml )
|
70
|
+
add, del = diff_property_array( :match_srcs )
|
71
|
+
return false if add.empty? and del.empty?
|
72
|
+
|
73
|
+
ele = :'source-address'
|
74
|
+
xml.match {
|
75
|
+
add.each{ |a| xml.send(ele, a) }
|
76
|
+
del.each{ |a| xml.send(ele, a, Netconf::JunosConfig::DELETE ) }
|
77
|
+
}
|
78
|
+
end
|
79
|
+
|
80
|
+
def xml_change_match_dsts( xml )
|
81
|
+
add, del = diff_property_array( :match_dsts )
|
82
|
+
return false if add.empty? and del.empty?
|
83
|
+
|
84
|
+
ele = :'destination-address'
|
85
|
+
xml.match {
|
86
|
+
add.each{ |a| xml.send(ele, a) }
|
87
|
+
del.each{ |a| xml.send(ele, a, Netconf::JunosConfig::DELETE ) }
|
88
|
+
}
|
89
|
+
end
|
90
|
+
|
91
|
+
def xml_change_match_apps( xml )
|
92
|
+
add, del = diff_property_array( :match_apps )
|
93
|
+
return false if add.empty? and del.empty?
|
94
|
+
|
95
|
+
xml.match {
|
96
|
+
add.each{ |a| xml.application a }
|
97
|
+
del.each{ |a| xml.application a, Netconf::JunosConfig::DELETE }
|
98
|
+
}
|
99
|
+
end
|
100
|
+
|
101
|
+
def xml_change_action( xml )
|
102
|
+
xml.then { xml.send( @should[:action] ) }
|
103
|
+
end
|
104
|
+
|
105
|
+
def xml_change_count( xml )
|
106
|
+
xml.then {
|
107
|
+
xml_set_or_delete_element( xml, 'count', @should[:count] )
|
108
|
+
}
|
109
|
+
end
|
110
|
+
|
111
|
+
def xml_change_log_init( xml )
|
112
|
+
xml.then { xml.log {
|
113
|
+
xml_set_or_delete_element( xml, 'session-init', @should[:log_init] )
|
114
|
+
}}
|
115
|
+
end
|
116
|
+
|
117
|
+
def xml_change_log_close( xml )
|
118
|
+
xml.then { xml.log {
|
119
|
+
xml_set_or_delete_element( xml, 'session-close', @should[:log_close] )
|
120
|
+
}}
|
121
|
+
end
|
122
|
+
|
123
|
+
end
|
124
|
+
|
125
|
+
##### ---------------------------------------------------------------
|
126
|
+
##### Provider collection methods
|
127
|
+
##### ---------------------------------------------------------------
|
128
|
+
|
129
|
+
class Junos::Ez::SRX::PolicyRules::Provider
|
130
|
+
|
131
|
+
def build_list
|
132
|
+
xml_get = @parent.xml_at_top
|
133
|
+
xml_get.policy( :recurse => 'false' )
|
134
|
+
xml_got = @ndev.rpc.get_configuration( xml_get )
|
135
|
+
xml_got.xpath('//name').collect{|n| n.text }
|
136
|
+
end
|
137
|
+
|
138
|
+
def build_catalog
|
139
|
+
@catalog = {}
|
140
|
+
xml_got = @ndev.rpc.get_configuration( @parent.xml_at_top )
|
141
|
+
pols = xml_got.xpath('security/policies/policy')
|
142
|
+
pols.xpath('policy').each do |pol|
|
143
|
+
name = pol.xpath('name').text
|
144
|
+
@catalog[name] = {}
|
145
|
+
xml_read_parser( pol, @catalog[name] )
|
146
|
+
end
|
147
|
+
return @catalog
|
148
|
+
end
|
149
|
+
|
150
|
+
end
|
151
|
+
|
152
|
+
##### ---------------------------------------------------------------
|
153
|
+
##### Provider Misc. operational methods
|
154
|
+
##### ---------------------------------------------------------------
|
155
|
+
|
156
|
+
class Junos::Ez::SRX::PolicyRules::Provider
|
157
|
+
|
158
|
+
## 'catalog_expanded' does the equivalent of the show w/detail option
|
159
|
+
## this expands the security object names into their exact values.
|
160
|
+
## note that this processing could take some time given the size of
|
161
|
+
## the address-books and application database involved. yo!
|
162
|
+
|
163
|
+
def catalog_expanded( policy_name = nil, opts = {} )
|
164
|
+
|
165
|
+
context = @parent.name
|
166
|
+
|
167
|
+
catalog_h = { :name => context }
|
168
|
+
catalog_h[:rules] = []
|
169
|
+
|
170
|
+
args = { :detail => true, :from_zone => context[0], :to_zone => context[1] }
|
171
|
+
args[:policy_name] = policy_name if policy_name
|
172
|
+
got = @ndev.rpc.get_firewall_policies( args )
|
173
|
+
|
174
|
+
got.xpath('security-context/policies/policy-information').each do |pi|
|
175
|
+
catalog_h[:rules] << _pi_to_h_( pi )
|
176
|
+
end
|
177
|
+
|
178
|
+
return catalog_h
|
179
|
+
end
|
180
|
+
|
181
|
+
### ---------------------------------------------------------------
|
182
|
+
### !!! PRIVATE METHODS
|
183
|
+
### ---------------------------------------------------------------
|
184
|
+
|
185
|
+
private
|
186
|
+
|
187
|
+
def _pi_to_h_( xml )
|
188
|
+
|
189
|
+
name = xml.xpath('policy-name').text
|
190
|
+
action = xml.xpath('policy-action/action-type').text.to_sym
|
191
|
+
|
192
|
+
srcs = xml.xpath('source-addresses/source-address').collect do |i|
|
193
|
+
[ i.xpath('address-name').text, i.xpath('prefixes/address-prefix').text ]
|
194
|
+
end
|
195
|
+
|
196
|
+
dsts = xml.xpath('destination-addresses/destination-address').collect do |i|
|
197
|
+
[ i.xpath('address-name').text, i.xpath('prefixes/address-prefix').text ]
|
198
|
+
end
|
199
|
+
|
200
|
+
apps = {}
|
201
|
+
xml.xpath('applications/application').each do |i|
|
202
|
+
app_name = i.xpath('application-name').text
|
203
|
+
app_terms_xml = i.xpath('application-term')
|
204
|
+
app_terms_a = []
|
205
|
+
app_terms_xml.each do |app_term|
|
206
|
+
app_term_h = {}
|
207
|
+
app_term_h[:proto] = app_term.xpath('protocol').text
|
208
|
+
app_term_h[:timeout] = app_term.xpath('inactivity-timeout').text.to_i
|
209
|
+
if app_term_h[:proto] == 'icmp'
|
210
|
+
app_term_h[:icmp_type] = app_term.xpath('icmp-info/icmp-type').text
|
211
|
+
app_term_h[:icmp_code] = app_term.xpath('icmp-info/icmp-code').text
|
212
|
+
else
|
213
|
+
app_sports = [ app_term.xpath('source-port-range/low').text.to_i,
|
214
|
+
app_term.xpath('source-port-range/high').text.to_i ]
|
215
|
+
app_dports = [ app_term.xpath('destination-port-range/low').text.to_i,
|
216
|
+
app_term.xpath('destination-port-range/high').text.to_i ]
|
217
|
+
app_term_h[:src_ports] = app_sports
|
218
|
+
app_term_h[:dst_ports] = app_dports
|
219
|
+
end
|
220
|
+
app_terms_a << app_term_h
|
221
|
+
end
|
222
|
+
apps[app_name] = app_terms_a
|
223
|
+
end
|
224
|
+
|
225
|
+
to_h = {}
|
226
|
+
to_h[:name] = name
|
227
|
+
to_h[:action] = action
|
228
|
+
to_h[:match_srcs] = Hash[srcs]
|
229
|
+
to_h[:match_dsts] = Hash[dsts]
|
230
|
+
to_h[:match_apps] = apps
|
231
|
+
|
232
|
+
return to_h
|
233
|
+
end
|
234
|
+
|
235
|
+
end
|
236
|
+
|
237
|
+
|
238
|
+
|
239
|
+
|
@@ -0,0 +1,275 @@
|
|
1
|
+
class Junos::Ez::SRX::Zones::Provider < Junos::Ez::Provider::Parent
|
2
|
+
|
3
|
+
def initialize( p_obj, name = nil, opts = {} )
|
4
|
+
super
|
5
|
+
|
6
|
+
## binding child providers ...
|
7
|
+
## 'interfaces' for zone-interfaces
|
8
|
+
## 'addrs' for address-book address entries
|
9
|
+
## 'sets' for address-book address sets
|
10
|
+
|
11
|
+
Junos::Ez::SRX::Interfaces::Provider( self, :interfaces, :parent => self )
|
12
|
+
Junos::Ez::SRX::AddressBookEntries::Provider( self, :addrs, :parent => self )
|
13
|
+
Junos::Ez::SRX::AddressBookSets::Provider( self, :sets, :parent => self )
|
14
|
+
end
|
15
|
+
|
16
|
+
### ---------------------------------------------------------------
|
17
|
+
### XML top placement
|
18
|
+
### ---------------------------------------------------------------
|
19
|
+
|
20
|
+
def xml_at_top
|
21
|
+
Nokogiri::XML::Builder.new{|x| x.configuration{
|
22
|
+
x.security { x.zones {
|
23
|
+
x.send(:'security-zone') {
|
24
|
+
x.name @name
|
25
|
+
return x
|
26
|
+
}
|
27
|
+
}}
|
28
|
+
}}
|
29
|
+
end
|
30
|
+
|
31
|
+
## for this provider, we only want to retrieve the
|
32
|
+
## configuration for the 'host-inbound-traffic' section
|
33
|
+
|
34
|
+
def xml_config_read!
|
35
|
+
xml = xml_at_top
|
36
|
+
xml.description
|
37
|
+
xml.send(:'host-inbound-traffic')
|
38
|
+
xml.interfaces
|
39
|
+
@ndev.rpc.get_configuration( xml )
|
40
|
+
end
|
41
|
+
|
42
|
+
### ---------------------------------------------------------------
|
43
|
+
### XML readers
|
44
|
+
### ---------------------------------------------------------------
|
45
|
+
|
46
|
+
def xml_get_has_xml( xml )
|
47
|
+
zone_xml = xml.xpath('//security-zone')[0]
|
48
|
+
return zone_xml if zone_xml
|
49
|
+
|
50
|
+
# so there is a corner case if the zone exists, but doesn't
|
51
|
+
# have any interfaces or host-inbound-services. this is probably
|
52
|
+
# a highly unlikely case, since a zone needs at least one inteface
|
53
|
+
# to be useful. but just in case, let's check.
|
54
|
+
sh_zone = @ndev.rpc.get_zones_information(:get_zones_named_information => @name)
|
55
|
+
if sh_zone.xpath('zones-security')[0]
|
56
|
+
@has[:_exist] = true
|
57
|
+
@has[:_active] = true
|
58
|
+
@has[:host_inbound_services] = []
|
59
|
+
@has[:host_inbound_protocols] = []
|
60
|
+
@has[:interfaces] = []
|
61
|
+
end
|
62
|
+
nil
|
63
|
+
end
|
64
|
+
|
65
|
+
def xml_read_parser( as_xml, as_hash )
|
66
|
+
set_has_status( as_xml, as_hash )
|
67
|
+
|
68
|
+
xml_when_item( as_xml.xpath('description')){|item| as_hash[:description] = item.text }
|
69
|
+
|
70
|
+
host_ib = as_xml.xpath('host-inbound-traffic')
|
71
|
+
as_hash[:host_inbound_services] = host_ib.xpath('system-services').collect do |svc|
|
72
|
+
svc.xpath('name').text.strip
|
73
|
+
end
|
74
|
+
as_hash[:host_inbound_protocols] = host_ib.xpath('protocols').collect do |proto|
|
75
|
+
proto.xpath('name').text.strip
|
76
|
+
end
|
77
|
+
|
78
|
+
as_hash[:interfaces] = as_xml.xpath('interfaces/name').collect do |zif|
|
79
|
+
zif.text.strip
|
80
|
+
end
|
81
|
+
|
82
|
+
return true
|
83
|
+
end
|
84
|
+
|
85
|
+
### ---------------------------------------------------------------
|
86
|
+
### XML property writers
|
87
|
+
### ---------------------------------------------------------------
|
88
|
+
|
89
|
+
def xml_change_host_inbound_services( xml )
|
90
|
+
add, del = diff_property_array( :host_inbound_services )
|
91
|
+
return false if add.empty? and del.empty?
|
92
|
+
|
93
|
+
xml.send( :'host-inbound-traffic' ) {
|
94
|
+
del.each do |i|
|
95
|
+
xml.send(:'system-services', Netconf::JunosConfig::DELETE) {
|
96
|
+
xml.name i
|
97
|
+
}
|
98
|
+
end
|
99
|
+
add.each{|i| xml.send(:'system-services', i ) }
|
100
|
+
}
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
def xml_change_host_inbound_protocols( xml )
|
105
|
+
add, del = diff_property_array( :host_inbound_protocols )
|
106
|
+
return false if add.empty? and del.empty?
|
107
|
+
|
108
|
+
xml.send( :'host-inbound-traffic' ) {
|
109
|
+
del.each do |i|
|
110
|
+
xml.protocols( Netconf::JunosConfig::DELETE ) {
|
111
|
+
xml.name i
|
112
|
+
}
|
113
|
+
end
|
114
|
+
add.each{ |i| xml.protocols i }
|
115
|
+
}
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|
119
|
+
|
120
|
+
##### ---------------------------------------------------------------
|
121
|
+
##### Provider collection methods
|
122
|
+
##### ---------------------------------------------------------------
|
123
|
+
|
124
|
+
class Junos::Ez::SRX::Zones::Provider
|
125
|
+
|
126
|
+
def build_list
|
127
|
+
zones = @ndev.rpc.get_zones_information
|
128
|
+
zones.xpath('zones-security/zones-security-zonename').collect do |zone|
|
129
|
+
zone.text.strip
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def build_catalog
|
134
|
+
@catalog = {}
|
135
|
+
|
136
|
+
zlist = list!
|
137
|
+
xml_cfg = @ndev.rpc.get_configuration{|x|
|
138
|
+
x.security { x.zones {
|
139
|
+
zlist.each do |zone_name|
|
140
|
+
@catalog[zone_name] = {}
|
141
|
+
x.send(:'security-zone') {
|
142
|
+
x.name zone_name
|
143
|
+
x.description
|
144
|
+
x.send(:'host-inbound-traffic')
|
145
|
+
x.interfaces
|
146
|
+
}
|
147
|
+
end
|
148
|
+
}}
|
149
|
+
}
|
150
|
+
|
151
|
+
xml_cfg.xpath('//security-zone').each do |zone|
|
152
|
+
zn_name = zone.xpath('name').text.strip
|
153
|
+
@catalog[zn_name] = {}
|
154
|
+
xml_read_parser( zone, @catalog[zn_name] )
|
155
|
+
end
|
156
|
+
|
157
|
+
return @catalog
|
158
|
+
end
|
159
|
+
|
160
|
+
end
|
161
|
+
|
162
|
+
##### ---------------------------------------------------------------
|
163
|
+
##### Provider YAML/Hash methods
|
164
|
+
##### ---------------------------------------------------------------
|
165
|
+
|
166
|
+
class Junos::Ez::SRX::Zones::Provider
|
167
|
+
|
168
|
+
## ----------------------------------------------------------------
|
169
|
+
## create an 'expanded' hash structure
|
170
|
+
## ----------------------------------------------------------------
|
171
|
+
|
172
|
+
def to_h_expanded( opts = {} )
|
173
|
+
{ :name => @name,
|
174
|
+
:_exist => @has[:_exist],
|
175
|
+
:_active => @has[:_active],
|
176
|
+
:host_inbound_services => @has[:host_inbound_services],
|
177
|
+
:host_inbound_protocols => @has[:host_inbound_protocols],
|
178
|
+
:interfaces => interfaces.catalog
|
179
|
+
}
|
180
|
+
end
|
181
|
+
|
182
|
+
def xml_from_h_expanded( from_hash, opts = {} )
|
183
|
+
raise ArgumentError, "This is not a provider" unless is_provider?
|
184
|
+
raise ArgumentError, ":name not provided in hash" unless from_hash[:name]
|
185
|
+
|
186
|
+
provd = self.class.new( @ndev, from_hash[:name], @opts )
|
187
|
+
provd.properties = Junos::Ez::Provider::PROPERTIES + Junos::Ez::SRX::Zones::PROPERTIES
|
188
|
+
provd[:host_inbound_services] = from_hash[:host_inbound_services] || []
|
189
|
+
provd[:host_inbound_protocols] = from_hash[:host_inbound_protocols] || []
|
190
|
+
provd[:_exist] = from_hash[:_exist] || true
|
191
|
+
provd[:_active] = from_hash[:_active] || true
|
192
|
+
|
193
|
+
# setup the XML for writing the complete configuration
|
194
|
+
|
195
|
+
xml_top = provd.xml_at_top
|
196
|
+
xml_add_here = xml_top.parent
|
197
|
+
|
198
|
+
Nokogiri::XML::Builder.with( xml_add_here ) do |xml|
|
199
|
+
provd.xml_build_change( xml )
|
200
|
+
end
|
201
|
+
|
202
|
+
# iterate through each of the policy rules. @@@ need
|
203
|
+
# to validate that the HASH actually contains this, yo!
|
204
|
+
|
205
|
+
from_hash[:interfaces].each do |name, hash|
|
206
|
+
Nokogiri::XML::Builder.with( xml_add_here ) do |xml|
|
207
|
+
|
208
|
+
# create the new object so we can generate XML on it
|
209
|
+
obj = Junos::Ez::SRX::Interfaces::Provider.new( @ndev, name, :parent => provd )
|
210
|
+
|
211
|
+
# generate the object specific XML inside
|
212
|
+
obj.should = hash || {}
|
213
|
+
obj_xml = obj.xml_element_top( xml, name )
|
214
|
+
obj.xml_build_change( obj_xml )
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
xml_top.parent[:replace] = "replace" if opts[:replace]
|
219
|
+
xml_top.doc.root
|
220
|
+
end
|
221
|
+
|
222
|
+
end
|
223
|
+
|
224
|
+
|
225
|
+
##### ---------------------------------------------------------------
|
226
|
+
##### Provider Misc. methods
|
227
|
+
##### ---------------------------------------------------------------
|
228
|
+
|
229
|
+
class Junos::Ez::SRX::Zones::Provider
|
230
|
+
|
231
|
+
def find_route( ip_prefix = nil, opts = {} )
|
232
|
+
raise ArgumentError, "ip_prefix required" unless ip_prefix
|
233
|
+
|
234
|
+
## do a standard route lookup to find the specific interface
|
235
|
+
## providing a route for the provided ip_prefix
|
236
|
+
|
237
|
+
got = @ndev.rpc.get_route_information( :destination => ip_prefix, :best => true )
|
238
|
+
return nil unless rt = got.xpath('route-table/rt')[0]
|
239
|
+
rt_ent = rt.xpath('rt-entry')[0]
|
240
|
+
|
241
|
+
found = {}
|
242
|
+
found[:find] = ip_prefix
|
243
|
+
found[:found] = rt.xpath('rt-destination').text
|
244
|
+
found[:proto] = rt_ent.xpath('protocol-name').text
|
245
|
+
found[:pref] = rt_ent.xpath('preference').text.to_i
|
246
|
+
found[:via] = rt_ent.xpath('nh/via | nh/nh-local-interface').text
|
247
|
+
|
248
|
+
## now find a zone based on the interface (via)
|
249
|
+
|
250
|
+
ifs = @ndev.rpc.get_interface_information( :interface_name => found[:via] )
|
251
|
+
found[:zone] = ifs.xpath('logical-interface/logical-interface-zone-name').text.strip
|
252
|
+
|
253
|
+
## if the calling object is a resource, then see if the zone
|
254
|
+
## matches on the lookup, and mark accordingly.
|
255
|
+
|
256
|
+
if @name; found[:zone_match] = (found[:zone] == @name) end
|
257
|
+
|
258
|
+
## if opts[:addrs] is set to true, then search through the zone address book
|
259
|
+
## to see what matches. first nab the zone provider depending if the calling
|
260
|
+
## object is a provider or zone resource. If it's a zone resource then we
|
261
|
+
## also need to make sure that the route lookup landed in this zone
|
262
|
+
|
263
|
+
if opts[:addrs]
|
264
|
+
if is_provider?
|
265
|
+
found[:addrs] = self[found[:zone]].addrs.find( ip_prefix )
|
266
|
+
else
|
267
|
+
found[:addrs] = (found[:zone_match] == true) ? self.addrs.find(ip_prefix) : nil
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
271
|
+
return found
|
272
|
+
end
|
273
|
+
|
274
|
+
end
|
275
|
+
|