junos-ez-srx 0.0.8
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
|