cisco_acl_intp 0.0.1
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.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.rspec +2 -0
- data/.rubocop.yml +13 -0
- data/.travis.yml +3 -0
- data/.yardopts +4 -0
- data/Gemfile +19 -0
- data/LICENSE.txt +22 -0
- data/README.md +132 -0
- data/Rakefile +78 -0
- data/acl_examples/err-acl.txt +49 -0
- data/acl_examples/named-ext-acl.txt +12 -0
- data/acl_examples/named-std-acl.txt +6 -0
- data/acl_examples/numd-acl.txt +21 -0
- data/cisco_acl_intp.gemspec +31 -0
- data/lib/cisco_acl_intp/ace.rb +432 -0
- data/lib/cisco_acl_intp/ace_ip.rb +136 -0
- data/lib/cisco_acl_intp/ace_other_qualifiers.rb +102 -0
- data/lib/cisco_acl_intp/ace_port.rb +146 -0
- data/lib/cisco_acl_intp/ace_proto.rb +319 -0
- data/lib/cisco_acl_intp/ace_srcdst.rb +114 -0
- data/lib/cisco_acl_intp/ace_tcp_flags.rb +65 -0
- data/lib/cisco_acl_intp/acl.rb +272 -0
- data/lib/cisco_acl_intp/acl_base.rb +111 -0
- data/lib/cisco_acl_intp/parser.rb +3509 -0
- data/lib/cisco_acl_intp/parser.ry +1397 -0
- data/lib/cisco_acl_intp/scanner.rb +176 -0
- data/lib/cisco_acl_intp/scanner_special_token_handler.rb +66 -0
- data/lib/cisco_acl_intp/version.rb +5 -0
- data/lib/cisco_acl_intp.rb +9 -0
- data/spec/cisco_acl_intp/ace_ip_spec.rb +111 -0
- data/spec/cisco_acl_intp/ace_other_qualifier_spec.rb +63 -0
- data/spec/cisco_acl_intp/ace_port_spec.rb +214 -0
- data/spec/cisco_acl_intp/ace_proto_spec.rb +200 -0
- data/spec/cisco_acl_intp/ace_spec.rb +605 -0
- data/spec/cisco_acl_intp/ace_srcdst_spec.rb +296 -0
- data/spec/cisco_acl_intp/ace_tcp_flags_spec.rb +38 -0
- data/spec/cisco_acl_intp/acl_spec.rb +523 -0
- data/spec/cisco_acl_intp/cisco_acl_intp_spec.rb +7 -0
- data/spec/cisco_acl_intp/parser_spec.rb +53 -0
- data/spec/cisco_acl_intp/scanner_spec.rb +122 -0
- data/spec/conf/extacl_objgrp_token_seq.yml +36 -0
- data/spec/conf/extacl_token_seq.yml +88 -0
- data/spec/conf/extended_acl.yml +226 -0
- data/spec/conf/scanner_spec_data.yml +120 -0
- data/spec/conf/single_tokens.yml +235 -0
- data/spec/conf/stdacl_token_seq.yml +8 -0
- data/spec/conf/tokens1.yml +158 -0
- data/spec/conf/tokens2.yml +206 -0
- data/spec/parser_fullfill_patterns.rb +145 -0
- data/spec/spec_helper.rb +54 -0
- data/tools/check_acl.rb +48 -0
- metadata +159 -0
@@ -0,0 +1,158 @@
|
|
1
|
+
:acl:
|
2
|
+
- :data: 'access-list'
|
3
|
+
:valid: true
|
4
|
+
- :data: 'access-lsit'
|
5
|
+
:msg: "typo <access-list>"
|
6
|
+
:valid: false
|
7
|
+
:stdacl_num:
|
8
|
+
- :data: "0"
|
9
|
+
:msg: "area1 lower out of range"
|
10
|
+
:valid: false
|
11
|
+
- :data: "1"
|
12
|
+
:msg: "area1 lower-bound"
|
13
|
+
:valid: true
|
14
|
+
- :data: "99"
|
15
|
+
:msg: "area1 upper-bound"
|
16
|
+
:valid: true
|
17
|
+
- :data: "1299"
|
18
|
+
:msg: "area2 lower out of range"
|
19
|
+
:valid: false
|
20
|
+
- :data: "1300"
|
21
|
+
:msg: "area2 lower-bound"
|
22
|
+
:valid: true
|
23
|
+
- :data: "1999"
|
24
|
+
:msg: "area2 upper-bound"
|
25
|
+
:valid: true
|
26
|
+
:extacl_num:
|
27
|
+
- :data: "100"
|
28
|
+
:valid: true
|
29
|
+
:msg: "area1 lower-bound"
|
30
|
+
- :data: "199"
|
31
|
+
:valid: true
|
32
|
+
:msg: "area1 upper-bound"
|
33
|
+
# - :data: "99"
|
34
|
+
# :valid: false
|
35
|
+
- :data: "200"
|
36
|
+
:valid: false
|
37
|
+
:msg: "area1 upper out of range"
|
38
|
+
- :data: "2000"
|
39
|
+
:valid: true
|
40
|
+
:msg: "area2 lower-bound"
|
41
|
+
- :data: "2699"
|
42
|
+
:valid: true
|
43
|
+
:msg: "area2 upper-bound"
|
44
|
+
# - :data: "1999"
|
45
|
+
# :valid: false
|
46
|
+
- :data: "2700"
|
47
|
+
:valid: false
|
48
|
+
:msg: "area2 upper out of range"
|
49
|
+
:dynamic_spec:
|
50
|
+
- :data: ''
|
51
|
+
:valid: true
|
52
|
+
- :data: 'dynamic dynamicname'
|
53
|
+
:valid: true
|
54
|
+
- :data: 'dynamic dynamicname timeout 3'
|
55
|
+
:valid: true
|
56
|
+
- :data: 'dynamic dynamicname timeout'
|
57
|
+
:valid: false
|
58
|
+
:msg: "missing timeout <min>"
|
59
|
+
- :data: 'dnamic dynamicname'
|
60
|
+
:valid: false
|
61
|
+
:msg: "typo <dynamic>"
|
62
|
+
:action:
|
63
|
+
- :data: ''
|
64
|
+
:msg: 'missing <action>'
|
65
|
+
:valid: false
|
66
|
+
- :data: 'permit'
|
67
|
+
:valid: true
|
68
|
+
- :data: 'deny'
|
69
|
+
:valid: true
|
70
|
+
- :data: 'drop'
|
71
|
+
:msg: "unknown action or typo"
|
72
|
+
:valid: false
|
73
|
+
:ip_proto:
|
74
|
+
- :data: ''
|
75
|
+
:msg: 'missing <protocol>'
|
76
|
+
:valid: false
|
77
|
+
- :data: 'ip'
|
78
|
+
:valid: true
|
79
|
+
- :data: 'ahp'
|
80
|
+
:valid: true
|
81
|
+
- :data: '0'
|
82
|
+
:msg: 'lower bound'
|
83
|
+
:valid: true
|
84
|
+
- :data: '255'
|
85
|
+
:msg: 'upper bound'
|
86
|
+
:valid: true
|
87
|
+
- :data: '256'
|
88
|
+
:msg: 'out of range'
|
89
|
+
:valid: false
|
90
|
+
:ip_spec1:
|
91
|
+
- :data: 'any'
|
92
|
+
:valid: true
|
93
|
+
- :data: 'host 192.168.0.1'
|
94
|
+
:valid: true
|
95
|
+
- :data: '192.168.0.0 0.0.0.128'
|
96
|
+
:valid: true
|
97
|
+
- :data: '192.168.0.2'
|
98
|
+
:valid: false
|
99
|
+
:msg: 'missing <host>'
|
100
|
+
- :data: '1921.68.0.2'
|
101
|
+
:valid: false
|
102
|
+
:msg: 'ip: out of range'
|
103
|
+
:ip_spec2:
|
104
|
+
- :data: 'any'
|
105
|
+
:valid: true
|
106
|
+
- :data: 'host 10.1.0.1'
|
107
|
+
:valid: true
|
108
|
+
- :data: '10.1.0.0 0.0.128.255'
|
109
|
+
:valid: true
|
110
|
+
- :data: '10.1.0.2'
|
111
|
+
:valid: false
|
112
|
+
:msg: 'missing <host>'
|
113
|
+
- :data: '10.1.0.256'
|
114
|
+
:valid: false
|
115
|
+
:msg: 'ip: out of range'
|
116
|
+
:icmp_proto:
|
117
|
+
- :data: ""
|
118
|
+
:valid: false
|
119
|
+
:msg: 'missing <icmp>'
|
120
|
+
- :data: "icmp"
|
121
|
+
:valid: true
|
122
|
+
:icmp_qualifier:
|
123
|
+
- :data: ""
|
124
|
+
:valid: true
|
125
|
+
- :data: 'administratively-prohibited'
|
126
|
+
:valid: true
|
127
|
+
- :data: '0'
|
128
|
+
:valid: true
|
129
|
+
:msg: "icmp type num only"
|
130
|
+
- :data: '0 255'
|
131
|
+
:valid: true
|
132
|
+
:msg: "icmp type/code num"
|
133
|
+
# - :data: "256 0"
|
134
|
+
# :valid: false
|
135
|
+
# # "type num: out of range"
|
136
|
+
# todo : "not implemented: icmp_qualifier type num check"
|
137
|
+
# - :data: "0 256"
|
138
|
+
# :valid: false
|
139
|
+
# # code num: out of range
|
140
|
+
# todo : "not implemented: icmp_qualifier code num check"
|
141
|
+
:std_acl_log_spec:
|
142
|
+
- :data: ""
|
143
|
+
:valid: true
|
144
|
+
- :data: "log"
|
145
|
+
:valid: true
|
146
|
+
- :data: "log logcookie"
|
147
|
+
:valid: true
|
148
|
+
:ext_acl_log_spec:
|
149
|
+
- :data: ""
|
150
|
+
:valid: true
|
151
|
+
- :data: "log"
|
152
|
+
:valid: true
|
153
|
+
- :data: "log logcookie"
|
154
|
+
:valid: true
|
155
|
+
- :data: "log-input"
|
156
|
+
:valid: true
|
157
|
+
- :data: "log-input logcookie"
|
158
|
+
:valid: true
|
@@ -0,0 +1,206 @@
|
|
1
|
+
:acl:
|
2
|
+
- :data: 'access-list'
|
3
|
+
:valid: true
|
4
|
+
:stdacl_num:
|
5
|
+
- :data: "1"
|
6
|
+
:valid: true
|
7
|
+
:msg: "area1 lower-bound"
|
8
|
+
:extacl_num:
|
9
|
+
- :data: "100"
|
10
|
+
:valid: true
|
11
|
+
:msg: "area1 lower-bound"
|
12
|
+
:dynamic_spec:
|
13
|
+
- :data: ''
|
14
|
+
:valid: true
|
15
|
+
- :data: 'dynamic dynamicname'
|
16
|
+
:valid: true
|
17
|
+
- :data: 'dynamic dynamicname timeout 3'
|
18
|
+
:valid: true
|
19
|
+
- :data: 'dynamic dynamicname timeout'
|
20
|
+
:valid: false
|
21
|
+
:msg: "missing timeout <min>"
|
22
|
+
- :data: 'dnamic dynamicname'
|
23
|
+
:valid: false
|
24
|
+
:msg: "typo <dynamic>"
|
25
|
+
:action:
|
26
|
+
- :data: 'permit'
|
27
|
+
:valid: true
|
28
|
+
- :data: 'deny'
|
29
|
+
:valid: true
|
30
|
+
:tcp_proto:
|
31
|
+
- :data: 'tcp'
|
32
|
+
:valid: true
|
33
|
+
:udp_proto:
|
34
|
+
- :data: 'udp'
|
35
|
+
:valid: true
|
36
|
+
:tcpudp_proto:
|
37
|
+
- :data: 'tcp'
|
38
|
+
:valid: true
|
39
|
+
- :data: 'udp'
|
40
|
+
:valid: true
|
41
|
+
- :data: 'object-group svgrp'
|
42
|
+
:valid: true
|
43
|
+
:ip_spec1:
|
44
|
+
- :data: 'any'
|
45
|
+
:valid: true
|
46
|
+
- :data: 'host 192.168.0.1'
|
47
|
+
:valid: true
|
48
|
+
- :data: '192.168.0.0 0.0.0.128'
|
49
|
+
:valid: true
|
50
|
+
- :data: '192.168.0.2'
|
51
|
+
:valid: false
|
52
|
+
:msg: 'missing <host>'
|
53
|
+
- :data: '1921.68.0.2'
|
54
|
+
:valid: false
|
55
|
+
:msg: 'ip: out of range'
|
56
|
+
:ip_spec2:
|
57
|
+
- :data: 'any'
|
58
|
+
:valid: true
|
59
|
+
- :data: 'host 10.1.0.1'
|
60
|
+
:valid: true
|
61
|
+
- :data: '10.1.0.0 0.0.128.255'
|
62
|
+
:valid: true
|
63
|
+
- :data: '10.1.0.2'
|
64
|
+
:valid: false
|
65
|
+
:msg: 'missing <host>'
|
66
|
+
- :data: '10.1.0.256'
|
67
|
+
:valid: false
|
68
|
+
:msg: 'ip: out of range'
|
69
|
+
:ip_spec_objgrp1:
|
70
|
+
- :data: 'any'
|
71
|
+
:valid: true
|
72
|
+
- :data: 'host 192.168.0.1'
|
73
|
+
:valid: true
|
74
|
+
- :data: '192.168.0.0 0.0.0.128'
|
75
|
+
:valid: true
|
76
|
+
- :data: 'object-group nwgrp1'
|
77
|
+
:valid: true
|
78
|
+
:ip_spec_objgrp2:
|
79
|
+
- :data: 'any'
|
80
|
+
:valid: true
|
81
|
+
- :data: 'host 10.1.0.1'
|
82
|
+
:valid: true
|
83
|
+
- :data: '10.1.0.0 0.0.128.255'
|
84
|
+
:valid: true
|
85
|
+
- :data: 'object-group nwgrp2'
|
86
|
+
:valid: true
|
87
|
+
:null_port:
|
88
|
+
- :data: ""
|
89
|
+
:valid: true
|
90
|
+
:tcp_port_spec1:
|
91
|
+
- :data: ""
|
92
|
+
:valid: true
|
93
|
+
- :data: "eq 80"
|
94
|
+
:valid: true
|
95
|
+
- :data: "eq any"
|
96
|
+
:valid: false
|
97
|
+
:msg: "unknown port-prot-name"
|
98
|
+
- :data: "lt ftp"
|
99
|
+
:valid: true
|
100
|
+
- :data: "gt telnet"
|
101
|
+
:valid: true
|
102
|
+
- :data: "range 53 443"
|
103
|
+
:valid: true
|
104
|
+
:tcp_port_spec2:
|
105
|
+
- :data: ""
|
106
|
+
:valid: true
|
107
|
+
- :data: "eq www"
|
108
|
+
:valid: true
|
109
|
+
- :data: "lt domain"
|
110
|
+
:valid: true
|
111
|
+
- :data: "gt 4000"
|
112
|
+
:valid: true
|
113
|
+
- :data: "range 2000 3333"
|
114
|
+
:valid: true
|
115
|
+
- :data: "eq isakmp"
|
116
|
+
:valid: false
|
117
|
+
:msg: "udp port-proto-name"
|
118
|
+
:udp_port_spec1:
|
119
|
+
- :data: ""
|
120
|
+
:valid: true
|
121
|
+
- :data: "eq 80"
|
122
|
+
:valid: true
|
123
|
+
- :data: "eq any"
|
124
|
+
:valid: false
|
125
|
+
:msg: "unknown port-prot-name"
|
126
|
+
- :data: "lt isakmp"
|
127
|
+
:valid: true
|
128
|
+
- :data: "gt ntp"
|
129
|
+
:valid: true
|
130
|
+
- :data: "range 53 443"
|
131
|
+
:valid: true
|
132
|
+
:udp_port_spec2:
|
133
|
+
- :data: ""
|
134
|
+
:valid: true
|
135
|
+
- :data: "eq 500"
|
136
|
+
:valid: true
|
137
|
+
- :data: "lt domain"
|
138
|
+
:valid: true
|
139
|
+
- :data: "gt 4000"
|
140
|
+
:valid: true
|
141
|
+
- :data: "range 2000 3333"
|
142
|
+
:valid: true
|
143
|
+
- :data: "eq pop3"
|
144
|
+
:valid: false
|
145
|
+
:msg: "tcp port-proto-name"
|
146
|
+
:ext_acl_log_spec:
|
147
|
+
- :data: ""
|
148
|
+
:valid: true
|
149
|
+
- :data: "log"
|
150
|
+
:valid: true
|
151
|
+
- :data: "log logcookie"
|
152
|
+
:valid: true
|
153
|
+
- :data: "log-input"
|
154
|
+
:valid: true
|
155
|
+
- :data: "log-input logcookie"
|
156
|
+
:valid: true
|
157
|
+
:tcp_flags:
|
158
|
+
- :data: ''
|
159
|
+
:valid: true
|
160
|
+
- :data: 'established'
|
161
|
+
:valid: true
|
162
|
+
- :data: 'syn fin ack'
|
163
|
+
:valid: true
|
164
|
+
- :data: 'acck established'
|
165
|
+
:valid: false
|
166
|
+
:tcp_flags2:
|
167
|
+
- :data: 'established'
|
168
|
+
:valid: true
|
169
|
+
- :data: 'established match-all +fin'
|
170
|
+
:valid: false
|
171
|
+
- :data: 'match-all +syn -fin -urg'
|
172
|
+
:valid: true
|
173
|
+
- :data: 'match-any -syn +fin +urg'
|
174
|
+
:valid: true
|
175
|
+
- :data: 'fin match-all +urg'
|
176
|
+
:valid: false
|
177
|
+
- :data: 'match-any -syn match-all -fin -urg'
|
178
|
+
:valid: false
|
179
|
+
- :data: 'match-any syn +fin'
|
180
|
+
:valid: false
|
181
|
+
:precedence:
|
182
|
+
- :data: ''
|
183
|
+
:valid: true
|
184
|
+
- :data: 'precedence 3'
|
185
|
+
:valid: true
|
186
|
+
- :data: 'precedence network'
|
187
|
+
:valid: true
|
188
|
+
:dscp:
|
189
|
+
- :data: ''
|
190
|
+
:valid: true
|
191
|
+
- :data: 'dscp af11'
|
192
|
+
:valid: true
|
193
|
+
- :data: 'dscp 6'
|
194
|
+
:valid: true
|
195
|
+
:tos:
|
196
|
+
- :data: ''
|
197
|
+
:valid: true
|
198
|
+
- :data: 'tos 10'
|
199
|
+
:valid: true
|
200
|
+
- :data: 'tos min-delay'
|
201
|
+
:valid: true
|
202
|
+
:time_range:
|
203
|
+
- :data: ''
|
204
|
+
:valid: true
|
205
|
+
- :data: 'time-range range_hoge'
|
206
|
+
:valid: true
|
@@ -0,0 +1,145 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'yaml'
|
3
|
+
require 'erb'
|
4
|
+
|
5
|
+
# data files
|
6
|
+
TOKEN_SEQ_FILE_LIST = [
|
7
|
+
'stdacl_token_seq.yml',
|
8
|
+
'extacl_token_seq.yml',
|
9
|
+
# 'extacl_objgrp_token_seq.yml'
|
10
|
+
]
|
11
|
+
|
12
|
+
# return spec conf dir
|
13
|
+
def _spec_conf_dir(file)
|
14
|
+
specdir = Dir.new('./spec/conf/')
|
15
|
+
File.join(specdir.path, file)
|
16
|
+
end
|
17
|
+
|
18
|
+
# return spec data dir
|
19
|
+
def _spec_data_dir(file)
|
20
|
+
datadir = Dir.new('./spec/data/')
|
21
|
+
File.join(datadir.path, file)
|
22
|
+
end
|
23
|
+
|
24
|
+
def gen_testcase(tokens, fields)
|
25
|
+
if fields.empty?
|
26
|
+
[{ data: '', msg: '', valid: true }]
|
27
|
+
else
|
28
|
+
field = fields.shift
|
29
|
+
field_patterns = tokens[field.intern]
|
30
|
+
# generate testpatterns recursively.
|
31
|
+
leftover_results = gen_testcase(tokens, fields)
|
32
|
+
create_data(field_patterns, leftover_results)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def create_data(field_patterns, leftover_results)
|
37
|
+
field_patterns.reduce([]) do |curr_results, each|
|
38
|
+
leftover_results.each do |each_res|
|
39
|
+
## do not add pattern that has multiple 'false'
|
40
|
+
## add single fault pattern.
|
41
|
+
if each[:valid] || each_res[:valid]
|
42
|
+
curr_results.push(single_data(each, each_res))
|
43
|
+
end
|
44
|
+
end
|
45
|
+
curr_results
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def single_data(curr, leftover)
|
50
|
+
{
|
51
|
+
data: [curr[:data], leftover[:data]].join(' '),
|
52
|
+
# used only single fail case,
|
53
|
+
# (1) curr AND leftover are VALID case
|
54
|
+
# (2) one of curr OR leftover is FALSE case
|
55
|
+
msg: curr[:msg] || leftover[:msg],
|
56
|
+
valid: curr[:valid] && leftover[:valid]
|
57
|
+
}
|
58
|
+
end
|
59
|
+
|
60
|
+
def each_test
|
61
|
+
TOKEN_SEQ_FILE_LIST.each do |each_file|
|
62
|
+
token_seq_data = YAML.load_file(_spec_conf_dir(each_file))
|
63
|
+
token_seq_data.each do |each|
|
64
|
+
puts "Test Name: #{each[:testname]}"
|
65
|
+
puts "Test Case File: #{each[:casedata]}"
|
66
|
+
yield(each)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
##############################
|
72
|
+
# generate test case data file
|
73
|
+
|
74
|
+
puts '## generate test case data file'
|
75
|
+
each_test do |each|
|
76
|
+
# read tokens pattern data
|
77
|
+
tokens = YAML.load_file(_spec_conf_dir(each[:casedata]))
|
78
|
+
# generate test case data
|
79
|
+
testcase_list = gen_testcase(tokens, each[:fieldseq])
|
80
|
+
|
81
|
+
# write datafile
|
82
|
+
case_file_base = [each[:testname], '.yml'].join
|
83
|
+
puts "Test Case Data: #{case_file_base}"
|
84
|
+
case_file = _spec_data_dir(case_file_base)
|
85
|
+
File.open(case_file, 'w') do |file|
|
86
|
+
file.puts YAML.dump(testcase_list.flatten)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
##############################
|
91
|
+
# run test per test case file
|
92
|
+
|
93
|
+
code_data = DATA.read
|
94
|
+
puts '## generate spec code'
|
95
|
+
each_test do |each|
|
96
|
+
spec_file_base = each[:testname] + '.rb'
|
97
|
+
puts "Spec code Data: #{spec_file_base}"
|
98
|
+
File.open(_spec_data_dir(spec_file_base), 'w') do |file|
|
99
|
+
code_erb = ERB.new(code_data, nil, '-')
|
100
|
+
file.puts code_erb.result(binding)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
__END__
|
105
|
+
# -*- coding: utf-8 -*-
|
106
|
+
require 'spec_helper'
|
107
|
+
require 'stringio'
|
108
|
+
|
109
|
+
describe 'Parser' do
|
110
|
+
describe '#parse_file' do
|
111
|
+
before do
|
112
|
+
@parser = CiscoAclIntp::Parser.new(color: false, silent: true)
|
113
|
+
end
|
114
|
+
|
115
|
+
<%-
|
116
|
+
tests = YAML.load_file(_spec_data_dir(each[:testname] + '.yml'))
|
117
|
+
test_total = tests.length
|
118
|
+
test_curr = 1
|
119
|
+
|
120
|
+
tests.each do |t|
|
121
|
+
now = sprintf(
|
122
|
+
"%d/%.1f\%", test_curr, (100.0 * test_curr / test_total)
|
123
|
+
)
|
124
|
+
if t[:valid]
|
125
|
+
-%>
|
126
|
+
it 'should be parsed acl [<%= now %>]: <%= t[:data] %>' do
|
127
|
+
datastr = StringIO.new('<%= t[:data] %>', 'r')
|
128
|
+
@parser.parse_file(datastr)
|
129
|
+
@parser.contains_error?.should be_false
|
130
|
+
end
|
131
|
+
<%-
|
132
|
+
else
|
133
|
+
-%>
|
134
|
+
it 'should not be parsed acl [<%= now %>]: <%= t[:data] %>' do
|
135
|
+
datastr = StringIO.new('<%= t[:data] %>', 'r')
|
136
|
+
@parser.parse_file(datastr)
|
137
|
+
@parser.contains_error?.should be_true
|
138
|
+
end
|
139
|
+
<%-
|
140
|
+
end
|
141
|
+
test_curr = test_curr + 1
|
142
|
+
end
|
143
|
+
-%>
|
144
|
+
end # describe parse_file
|
145
|
+
end # describe Parser
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
3
|
+
|
4
|
+
require 'simplecov'
|
5
|
+
SimpleCov.start do
|
6
|
+
add_group 'Models', 'lib/'
|
7
|
+
end
|
8
|
+
|
9
|
+
require 'cisco_acl_intp'
|
10
|
+
|
11
|
+
include CiscoAclIntp
|
12
|
+
AclContainerBase.disable_color
|
13
|
+
|
14
|
+
RSpec::Matchers.define :be_aclstr do | expected_str |
|
15
|
+
match do | actual_str |
|
16
|
+
a = actual_str.strip
|
17
|
+
b = expected_str.strip
|
18
|
+
a.split(/\s+/) == b.split(/[\s\r\n]+/)
|
19
|
+
## by this method, whitespaces are skipped.
|
20
|
+
## because, it cannot handle correctly like 'remark foo -- bar'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# hash to hash-code-string
|
25
|
+
def _pph(hash)
|
26
|
+
kv = []
|
27
|
+
hash.each do | k, v |
|
28
|
+
case v
|
29
|
+
when String
|
30
|
+
kv.push %Q{:#{k.to_s}=>"#{v.to_s}"}
|
31
|
+
else
|
32
|
+
kv.push %Q{:#{k.to_s}=>#{v.to_s}}
|
33
|
+
end
|
34
|
+
end
|
35
|
+
kv.join(',')
|
36
|
+
end
|
37
|
+
|
38
|
+
# return specdir
|
39
|
+
def _spec_dir(file)
|
40
|
+
specdir = Dir.new('./spec/cisco_acl_intp/')
|
41
|
+
File.join(specdir.path, file)
|
42
|
+
end
|
43
|
+
|
44
|
+
# return test config/data dir
|
45
|
+
def _spec_conf_dir(file)
|
46
|
+
specdir = Dir.new('./spec/conf/')
|
47
|
+
File.join(specdir.path, file)
|
48
|
+
end
|
49
|
+
|
50
|
+
# return spec_data dir
|
51
|
+
def _spec_data_dir(file)
|
52
|
+
datadir = Dir.new('./spec/data/')
|
53
|
+
File.join(datadir.path, file)
|
54
|
+
end
|
data/tools/check_acl.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
2
|
+
|
3
|
+
require 'optparse'
|
4
|
+
require 'cisco_acl_intp'
|
5
|
+
|
6
|
+
opts = {}
|
7
|
+
OptionParser.new do | each |
|
8
|
+
each.banner = "ruby #{$PROGRAM_NAME} [options] [args]"
|
9
|
+
each.on('-c', '--color', 'enable coloring') do |x|
|
10
|
+
opts[:color] = x
|
11
|
+
end
|
12
|
+
each.on('-d', '--debug', 'enable debug print') do |x|
|
13
|
+
opts[:debug] = x
|
14
|
+
end
|
15
|
+
each.on('--yydebug', 'enable yydebug') do |x|
|
16
|
+
opts[:yydebug] = x
|
17
|
+
end
|
18
|
+
each.on('-f FILE', '--file', 'acl file') do |x|
|
19
|
+
opts[:file] = x
|
20
|
+
end
|
21
|
+
begin
|
22
|
+
each.parse!
|
23
|
+
rescue
|
24
|
+
puts 'invalid option.'
|
25
|
+
puts each
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
popts = {}
|
30
|
+
popts[:color] = opts[:color] || false
|
31
|
+
popts[:debug] = opts[:debug] || false
|
32
|
+
popts[:yydebug] = opts[:yydebug] || false
|
33
|
+
|
34
|
+
parser = CiscoAclIntp::Parser.new(popts)
|
35
|
+
|
36
|
+
# read acl from file or STDIN
|
37
|
+
if opts[:file]
|
38
|
+
parser.parse_file opts[:file]
|
39
|
+
else
|
40
|
+
parser.parse_file $stdin
|
41
|
+
end
|
42
|
+
|
43
|
+
# print acl data
|
44
|
+
aclt = parser.acl_table
|
45
|
+
aclt.each do |name, acl|
|
46
|
+
puts "acl name : #{name}"
|
47
|
+
puts acl.to_s
|
48
|
+
end
|