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,160 @@
|
|
1
|
+
class Junos::Ez::SRX::Apps::Provider < Junos::Ez::Provider::Parent
|
2
|
+
|
3
|
+
### ---------------------------------------------------------------
|
4
|
+
### XML top placement
|
5
|
+
### ---------------------------------------------------------------
|
6
|
+
|
7
|
+
def xml_at_top
|
8
|
+
Nokogiri::XML::Builder.new{|x| x.configuration{
|
9
|
+
x.applications {
|
10
|
+
x.application {
|
11
|
+
x.name @name
|
12
|
+
return x
|
13
|
+
}
|
14
|
+
}
|
15
|
+
}}
|
16
|
+
end
|
17
|
+
|
18
|
+
### ---------------------------------------------------------------
|
19
|
+
### XML readers
|
20
|
+
### ---------------------------------------------------------------
|
21
|
+
|
22
|
+
def xml_get_has_xml( xml )
|
23
|
+
xml.xpath('//application')[0]
|
24
|
+
end
|
25
|
+
|
26
|
+
def xml_read_parser( as_xml, as_hash )
|
27
|
+
set_has_status( as_xml, as_hash )
|
28
|
+
|
29
|
+
xml_when_item(as_xml.xpath('description')){|i| as_hash[:description] = i.text }
|
30
|
+
xml_when_item(as_xml.xpath('protocol')){|i| as_hash[:proto] = i.text }
|
31
|
+
as_hash[:proto] ||= nil
|
32
|
+
|
33
|
+
xml_when_item(as_xml.xpath('inactivity-timeout')){|i| as_hash[:timeout] = i.text.to_i }
|
34
|
+
|
35
|
+
if as_hash[:proto] == 'icmp'
|
36
|
+
xml_when_item(as_xml.xpath('icmp-type')){|i| as_hash[:icmp_type] = i.text }
|
37
|
+
xml_when_item(as_xml.xpath('icmp-code')){|i| as_hash[:icmp_code] = i.text }
|
38
|
+
return true
|
39
|
+
end
|
40
|
+
|
41
|
+
## check to see if we have a proto. if not, this is a composite application
|
42
|
+
## definition witha collection of terms. return when done.
|
43
|
+
|
44
|
+
if as_hash[:proto] == nil
|
45
|
+
terms = []
|
46
|
+
as_xml.xpath('term').each do |term|
|
47
|
+
term_h = {}
|
48
|
+
term_h[:name] = term.xpath('name').text
|
49
|
+
term_h[:proto] = term.xpath('protocol').text
|
50
|
+
xml_when_item(term.xpath('destination-port')) do |i|
|
51
|
+
term_h[:dst_ports] = _xml_read_parse_destination_port_( i.text )
|
52
|
+
end
|
53
|
+
terms << term_h
|
54
|
+
end
|
55
|
+
as_hash[:terms] = terms
|
56
|
+
|
57
|
+
return #!!! end of excution
|
58
|
+
end
|
59
|
+
|
60
|
+
### rest of this is for non ICMP
|
61
|
+
|
62
|
+
xml_when_item(as_xml.xpath('destination-port')) do |i|
|
63
|
+
text = i.text
|
64
|
+
if (Float(text) != nil rescue false)
|
65
|
+
as_hash[:dst_ports] = text.to_i
|
66
|
+
elsif text =~ /(\d+)-(\d+)/
|
67
|
+
as_hash[:dst_ports] = [ $1.to_i, $2.to_i ]
|
68
|
+
else
|
69
|
+
as_hash[:dst_ports] = text
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
return true
|
74
|
+
end
|
75
|
+
|
76
|
+
def _xml_read_parse_destination_port_( text )
|
77
|
+
if (Float(text) != nil rescue false)
|
78
|
+
text.to_i
|
79
|
+
elsif text =~ /(\d+)-(\d+)/
|
80
|
+
[ $1.to_i, $2.to_i ]
|
81
|
+
else
|
82
|
+
text
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
### ---------------------------------------------------------------
|
87
|
+
### XML property writers
|
88
|
+
### ---------------------------------------------------------------
|
89
|
+
|
90
|
+
def xml_change_proto( xml )
|
91
|
+
xml_set_or_delete( xml, 'protocol', @should[:proto] )
|
92
|
+
end
|
93
|
+
|
94
|
+
def xml_change_dst_ports( xml )
|
95
|
+
e_value =
|
96
|
+
( @should[:dst_ports].kind_of? Array ) ? "#{@should[:dst_ports][0]}-#{@should[:dst_ports][1]}"
|
97
|
+
: @should[:dst_ports]
|
98
|
+
|
99
|
+
xml_set_or_delete( xml, 'destination-port', e_value )
|
100
|
+
end
|
101
|
+
|
102
|
+
def xml_change_timeout( xml )
|
103
|
+
xml_set_or_delete( xml, 'inactivity-timeout', @should[:timeout] )
|
104
|
+
end
|
105
|
+
|
106
|
+
def xml_change_icmp_type( xml )
|
107
|
+
xml_set_or_delete( xml, 'icmp-type', @should[:icmp_type] )
|
108
|
+
end
|
109
|
+
|
110
|
+
def xml_change_icmp_code( xml )
|
111
|
+
xml_set_or_delete( xml, 'icmp-code', @should[:icmp_code] )
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
|
116
|
+
##### ---------------------------------------------------------------
|
117
|
+
##### Provider collection methods
|
118
|
+
##### ---------------------------------------------------------------
|
119
|
+
|
120
|
+
class Junos::Ez::SRX::Apps::Provider
|
121
|
+
|
122
|
+
def build_list
|
123
|
+
@ndev.rpc.get_configuration{|x| x.applications {
|
124
|
+
x.application(:recurse => 'false')
|
125
|
+
}}.xpath('applications/application/name').collect{ |n| n.text }
|
126
|
+
end
|
127
|
+
|
128
|
+
def build_catalog
|
129
|
+
@catalog = {}
|
130
|
+
@ndev.rpc.get_configuration{|x| x.applications {
|
131
|
+
x.application
|
132
|
+
}}.xpath('applications/application').each do |app|
|
133
|
+
name = app.xpath('name').text
|
134
|
+
@catalog[name] = {}
|
135
|
+
xml_read_parser( app, @catalog[name] )
|
136
|
+
end
|
137
|
+
@catalog
|
138
|
+
end
|
139
|
+
|
140
|
+
def list_junos_defaults
|
141
|
+
@ndev.rpc.get_configuration{|x| x.groups { x.name 'junos-defaults'
|
142
|
+
x.applications { x.application(:recurse => 'false')
|
143
|
+
}}}.xpath('//application/name').collect{ |n| n.text }
|
144
|
+
end
|
145
|
+
|
146
|
+
def catalog_junos_defaults
|
147
|
+
j_catalog = {}
|
148
|
+
@ndev.rpc.get_configuration{|x| x.groups { x.name 'junos-defaults'
|
149
|
+
x.applications { x.application
|
150
|
+
}}}.xpath('//applications/application').each do |app|
|
151
|
+
name = app.xpath('name').text
|
152
|
+
j_catalog[name] = {}
|
153
|
+
xml_read_parser( app, j_catalog[name] )
|
154
|
+
end
|
155
|
+
j_catalog
|
156
|
+
end
|
157
|
+
|
158
|
+
end
|
159
|
+
|
160
|
+
|
@@ -0,0 +1,82 @@
|
|
1
|
+
class Junos::Ez::SRX::AppSets::Provider < Junos::Ez::Provider::Parent
|
2
|
+
|
3
|
+
### ---------------------------------------------------------------
|
4
|
+
### XML top placement
|
5
|
+
### ---------------------------------------------------------------
|
6
|
+
|
7
|
+
def xml_at_top
|
8
|
+
Nokogiri::XML::Builder.new{|x| x.configuration{
|
9
|
+
x.applications {
|
10
|
+
x.send(:'application-set') {
|
11
|
+
x.name @name
|
12
|
+
return x
|
13
|
+
}
|
14
|
+
}
|
15
|
+
}}
|
16
|
+
end
|
17
|
+
|
18
|
+
### ---------------------------------------------------------------
|
19
|
+
### XML readers
|
20
|
+
### ---------------------------------------------------------------
|
21
|
+
|
22
|
+
def xml_get_has_xml( xml )
|
23
|
+
xml.xpath('applications/application-set')[0]
|
24
|
+
end
|
25
|
+
|
26
|
+
def xml_read_parser( as_xml, as_hash )
|
27
|
+
set_has_status( as_xml, as_hash )
|
28
|
+
xml_when_item(as_xml.xpath('description')){|i| as_hash[:description] = i.text }
|
29
|
+
as_hash[:app_names] = as_xml.xpath('application/name').collect{|i| i.text }
|
30
|
+
as_hash[:app_sets] = as_xml.xpath('application-set/name').collect{|i| i.text }
|
31
|
+
return true
|
32
|
+
end
|
33
|
+
|
34
|
+
### ---------------------------------------------------------------
|
35
|
+
### XML property writers
|
36
|
+
### ---------------------------------------------------------------
|
37
|
+
|
38
|
+
def xml_change_app_names( xml )
|
39
|
+
add, del = diff_property_array( :app_names )
|
40
|
+
return false if add.empty? and del.empty?
|
41
|
+
|
42
|
+
add.each{ |item| xml.application { xml.name item } }
|
43
|
+
del.each{ |item| xml.application( Netconf::JunosConfig::DELETE ) { xml.name item }}
|
44
|
+
end
|
45
|
+
|
46
|
+
def xml_change_app_sets( xml )
|
47
|
+
add, del = diff_property_array( :app_sets )
|
48
|
+
return false if add.empty? and del.empty?
|
49
|
+
|
50
|
+
add.each{ |item| xml.send(:'applicaiton-set') { xml.name item } }
|
51
|
+
del.each{ |item| xml.send(:'application-set', Netconf::JunosConfig::DELETE ) { xml.name item }}
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
##### ---------------------------------------------------------------
|
57
|
+
##### Provider collection methods
|
58
|
+
##### ---------------------------------------------------------------
|
59
|
+
|
60
|
+
class Junos::Ez::SRX::AppSets::Provider
|
61
|
+
|
62
|
+
def build_list
|
63
|
+
@ndev.rpc.get_configuration{|x| x.applications {
|
64
|
+
x.send(:'application-set', :recurse => 'false' )
|
65
|
+
}}.xpath('applications/application-set/name').collect{ |n| n.text }
|
66
|
+
end
|
67
|
+
|
68
|
+
def build_catalog
|
69
|
+
@catalog = {}
|
70
|
+
@ndev.rpc.get_configuration{|x| x.applications {
|
71
|
+
x.send(:'application-set')
|
72
|
+
}}.xpath('applications/application-set').each do |app|
|
73
|
+
name = app.xpath('name').text
|
74
|
+
@catalog[name] = {}
|
75
|
+
xml_read_parser( app, @catalog[name] )
|
76
|
+
end
|
77
|
+
@catalog
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
|
@@ -0,0 +1,115 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
class Junos::Ez::SRX::Interfaces::Provider < Junos::Ez::Provider::Parent
|
4
|
+
|
5
|
+
### ---------------------------------------------------------------
|
6
|
+
### XML top placement
|
7
|
+
### ---------------------------------------------------------------
|
8
|
+
|
9
|
+
def xml_at_top
|
10
|
+
|
11
|
+
Nokogiri::XML::Builder.new{|x| x.configuration{
|
12
|
+
x.security { x.zones {
|
13
|
+
x.send(:'security-zone') {
|
14
|
+
x.name @parent.name
|
15
|
+
xml_element_top( x, @name )
|
16
|
+
}
|
17
|
+
}}
|
18
|
+
}}
|
19
|
+
end
|
20
|
+
|
21
|
+
def xml_element_top( xml, name )
|
22
|
+
xml.interfaces {
|
23
|
+
xml.name name
|
24
|
+
return xml
|
25
|
+
}
|
26
|
+
end
|
27
|
+
|
28
|
+
### ---------------------------------------------------------------
|
29
|
+
### XML readers
|
30
|
+
### ---------------------------------------------------------------
|
31
|
+
|
32
|
+
def xml_get_has_xml( xml )
|
33
|
+
xml.xpath('//interfaces')[0]
|
34
|
+
end
|
35
|
+
|
36
|
+
def xml_read_parser( as_xml, as_hash )
|
37
|
+
set_has_status( as_xml, as_hash )
|
38
|
+
|
39
|
+
host_ib = as_xml.xpath('host-inbound-traffic')
|
40
|
+
|
41
|
+
as_hash[:host_inbound_services] = host_ib.xpath('system-services').collect do |svc|
|
42
|
+
svc.xpath('name').text.strip
|
43
|
+
end
|
44
|
+
|
45
|
+
as_hash[:host_inbound_protocols] = host_ib.xpath('protocols').collect do |proto|
|
46
|
+
proto.xpath('name').text.strip
|
47
|
+
end
|
48
|
+
|
49
|
+
true
|
50
|
+
end
|
51
|
+
|
52
|
+
### ---------------------------------------------------------------
|
53
|
+
### XML writers
|
54
|
+
### ---------------------------------------------------------------
|
55
|
+
|
56
|
+
def xml_change_host_inbound_services( xml )
|
57
|
+
add, del = diff_property_array( :host_inbound_services )
|
58
|
+
return false if add.empty? and del.empty?
|
59
|
+
|
60
|
+
xml.send( :'host-inbound-traffic' ) {
|
61
|
+
del.each do |i|
|
62
|
+
xml.send(:'system-services', Netconf::JunosConfig::DELETE) {
|
63
|
+
xml.name i
|
64
|
+
}
|
65
|
+
end
|
66
|
+
add.each{|i| xml.send(:'system-services', i) }
|
67
|
+
}
|
68
|
+
end
|
69
|
+
|
70
|
+
def xml_change_host_inbound_protocols( xml )
|
71
|
+
add, del = diff_property_array( :host_inbound_protocols )
|
72
|
+
return false if add.empty? and del.empty?
|
73
|
+
|
74
|
+
xml.send( :'host-inbound-traffic' ) {
|
75
|
+
del.each do |i|
|
76
|
+
xml.protocols( Netconf::JunosConfig::DELETE ) {
|
77
|
+
xml.name i
|
78
|
+
}
|
79
|
+
end
|
80
|
+
add.each{ |i| xml.protocols i }
|
81
|
+
}
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
##### ---------------------------------------------------------------
|
87
|
+
##### Provider collection methods
|
88
|
+
##### ---------------------------------------------------------------
|
89
|
+
|
90
|
+
class Junos::Ez::SRX::Interfaces::Provider
|
91
|
+
|
92
|
+
def build_list
|
93
|
+
args = { :get_zones_named_information => @parent.name }
|
94
|
+
zinfo = @ndev.rpc.get_zones_information( args )
|
95
|
+
zinfo.xpath('//zones-security-interface-name').collect do |zif|
|
96
|
+
zif.text
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def build_catalog
|
101
|
+
@catalog = {}
|
102
|
+
|
103
|
+
xml_get = @parent.xml_at_top
|
104
|
+
xml_get.interfaces
|
105
|
+
xml_cfg = @ndev.rpc.get_configuration( xml_get )
|
106
|
+
xml_cfg.xpath('//interfaces').each do |zif|
|
107
|
+
zif_name = zif.xpath('name').text
|
108
|
+
@catalog[zif_name] = {}
|
109
|
+
xml_read_parser( zif, @catalog[zif_name] )
|
110
|
+
end
|
111
|
+
|
112
|
+
return @catalog
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
@@ -0,0 +1,141 @@
|
|
1
|
+
class Junos::Ez::SRX::Policies::Provider < Junos::Ez::Provider::Parent
|
2
|
+
|
3
|
+
def initialize( p_obj, name = nil, opts = {} )
|
4
|
+
super
|
5
|
+
return unless name
|
6
|
+
|
7
|
+
# bind in the child provider for managing the actual rules
|
8
|
+
Junos::Ez::SRX::PolicyRules::Provider( self, :rules, :parent => self )
|
9
|
+
end
|
10
|
+
|
11
|
+
### ---------------------------------------------------------------
|
12
|
+
### XML top placement
|
13
|
+
### ---------------------------------------------------------------
|
14
|
+
|
15
|
+
def xml_at_top
|
16
|
+
Nokogiri::XML::Builder.new{|x| x.configuration{
|
17
|
+
x.security { x.policies {
|
18
|
+
x.policy {
|
19
|
+
x.send( :'from-zone-name', @name[0] )
|
20
|
+
x.send( :'to-zone-name', @name[1] )
|
21
|
+
return x
|
22
|
+
}
|
23
|
+
}}
|
24
|
+
}}
|
25
|
+
end
|
26
|
+
|
27
|
+
### ---------------------------------------------------------------
|
28
|
+
### XML readers
|
29
|
+
### ---------------------------------------------------------------
|
30
|
+
|
31
|
+
## override the reader to only pull in the policy names, and
|
32
|
+
## not all the details.
|
33
|
+
|
34
|
+
def xml_config_read!
|
35
|
+
xml = xml_at_top
|
36
|
+
xml.policy( :recurse => 'false' )
|
37
|
+
@ndev.rpc.get_configuration( xml )
|
38
|
+
end
|
39
|
+
|
40
|
+
def xml_get_has_xml( xml )
|
41
|
+
xml.xpath('security/policies/policy')[0]
|
42
|
+
end
|
43
|
+
|
44
|
+
def xml_read_parser( as_xml, as_hash )
|
45
|
+
set_has_status( as_xml, as_hash )
|
46
|
+
as_hash[:rules] = as_xml.xpath('policy/name').collect do |pol|
|
47
|
+
pol.text
|
48
|
+
end
|
49
|
+
as_hash[:rules_count] = as_hash[:rules].count
|
50
|
+
return true
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
##### ---------------------------------------------------------------
|
56
|
+
##### Provider collection methods
|
57
|
+
##### ---------------------------------------------------------------
|
58
|
+
|
59
|
+
class Junos::Ez::SRX::Policies::Provider
|
60
|
+
|
61
|
+
def build_list
|
62
|
+
fw = @ndev.rpc.get_firewall_policies( :zone_context => true )
|
63
|
+
fw.xpath('policy-zone-context/policy-zone-context-entry').collect do |pzc|
|
64
|
+
[ pzc.xpath('policy-zone-context-from-zone').text,
|
65
|
+
pzc.xpath('policy-zone-context-to-zone').text ]
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def build_catalog
|
70
|
+
@catalog = {}
|
71
|
+
fw = @ndev.rpc.get_firewall_policies( :zone_context => true )
|
72
|
+
fw.xpath('policy-zone-context/policy-zone-context-entry').collect do |pzc|
|
73
|
+
|
74
|
+
name = [pzc.xpath('policy-zone-context-from-zone').text,
|
75
|
+
pzc.xpath('policy-zone-context-to-zone').text ]
|
76
|
+
|
77
|
+
@catalog[name] = {
|
78
|
+
:rules_count => pzc.xpath('policy-zone-context-policy-count').text.to_i
|
79
|
+
}
|
80
|
+
end
|
81
|
+
return @catalog
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
##### ---------------------------------------------------------------
|
86
|
+
##### Provider EXPANDED methods
|
87
|
+
##### ---------------------------------------------------------------
|
88
|
+
|
89
|
+
class Junos::Ez::SRX::Policies::Provider
|
90
|
+
|
91
|
+
## ----------------------------------------------------------------
|
92
|
+
## create an 'expanded' hash structure
|
93
|
+
## ----------------------------------------------------------------
|
94
|
+
|
95
|
+
def to_h_expanded( opts = {} )
|
96
|
+
{ :name => @name,
|
97
|
+
:rules => rules.catalog!
|
98
|
+
}
|
99
|
+
end
|
100
|
+
|
101
|
+
## ----------------------------------------------------------------
|
102
|
+
## create the XML for a complete policy rules set given a Hash
|
103
|
+
## structure the mimics the provider and properties for the
|
104
|
+
## Policy and associated PolicyRules
|
105
|
+
## ----------------------------------------------------------------
|
106
|
+
|
107
|
+
def xml_from_h_expanded( from_hash, opts = {} )
|
108
|
+
raise ArgumentError, "This is not a provider" unless is_provider?
|
109
|
+
raise ArgumentError, ":name not provided in hash" unless from_hash[:name]
|
110
|
+
|
111
|
+
provd = self.class.new( @ndev, from_hash[:name], @opts )
|
112
|
+
|
113
|
+
# setup the XML for writing the complete configuration
|
114
|
+
|
115
|
+
xml_top = provd.xml_at_top
|
116
|
+
xml_add_here = xml_top.parent
|
117
|
+
|
118
|
+
# iterate through each of the policy rules. @@@ need
|
119
|
+
# to validate that the HASH actually contains this, yo!
|
120
|
+
|
121
|
+
from_hash[:rules].each do |name, hash|
|
122
|
+
Nokogiri::XML::Builder.with( xml_add_here ) do |xml|
|
123
|
+
|
124
|
+
# create the new object so we can generate XML on it
|
125
|
+
rule = Junos::Ez::SRX::PolicyRules::Provider.new( @ndev, name, :parent => provd )
|
126
|
+
|
127
|
+
# generate the object specific XML inside
|
128
|
+
rule.should = hash
|
129
|
+
rule_xml = rule.xml_element_top( xml, rule.name )
|
130
|
+
rule.xml_build_change( rule_xml )
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
xml_top.parent[:replace] = "replace" if opts[:replace]
|
135
|
+
xml_top.doc.root
|
136
|
+
end
|
137
|
+
|
138
|
+
|
139
|
+
end
|
140
|
+
|
141
|
+
|