junoser 0.3.12 → 0.3.13

Sign up to get free protection for your applications and to get access to all the features.
@@ -46,64 +46,96 @@ module Junoser
46
46
 
47
47
  str.gsub! /"groups" \(\s*s\(\s*any\s*\)\s*\)/, 'a("groups", arg, configuration)'
48
48
 
49
- %w[as-number confederation-as metric-value limit-threshold filename filter-name class-name classifier-name link-subscription per-traffic-class-bandwidth template-name].each do |key|
50
- str.gsub! %["#{key}" arg], 'arg'
51
- end
52
-
53
49
  str.gsub! '"equal-literal"', '"="'
54
50
  str.gsub! '"plus-literal"', '"+"'
55
51
  str.gsub! '"minus-literal"', '"-"'
56
52
 
57
- str.gsub!(/\((.*) \| "name"\)/) { "(#$1 | arg)" }
58
- str.gsub! '"vlan" ("all" | "vlan-name")', '"vlan" ("all" | arg)'
59
- str.gsub!(/\((.*) \| "vlan-id"\)/) { "(#$1 | arg)" }
53
+ #
54
+ # Statements can be quoted
55
+ #
60
56
  str.gsub!(/("ssh-\S+") arg/) { "#$1 (quote | arg)" }
57
+ str.gsub! '"message" arg', '"message" (quote | arg)'
61
58
  str.gsub! '"description" arg', '"description" (quote | arg)'
62
59
  str.gsub! '"as-path-prepend" arg', '"as-path-prepend" (quote | arg)'
63
- str.gsub!(/arg \| (".*")/) { "#$1 | arg" }
64
- str.gsub! '"dhcp-service" (', '("dhcp-service" | "dhcp") ('
65
60
 
66
- str.gsub!(/"inet"(.*)"inet6"/) { %["inet6"#$1"inet"] }
67
- str.gsub!(/"icmp"(.*)"icmp6"/) { %["icmp6"#$1"icmp"] }
68
- str.gsub!(/"icmp"(.*)"icmpv6"/) { %["icmpv6"#$1"icmp"] }
69
- str.gsub!(/"http"(.*)"https"/) { %["https"#$1"http"] }
70
- str.gsub!(/"snmp"(.*)"snmptrap"/) { %["snmptrap"#$1"snmp"] }
71
- %w[ccc ethernet-over-atm tcc vpls bridge].each do |encap|
72
- str.gsub!(/"ethernet"(.*)"ethernet-#{encap}"/) { %["ethernet-#{encap}"#$1"ethernet"] }
61
+ str.gsub!(/^(\s*)"as-path" arg \(\s*c\(\s*arg/) do
62
+ format(['"as-path" arg (',
63
+ ' c(',
64
+ ' quote | arg'], $1)
73
65
  end
74
- str.gsub! '"icmp6" |', '"icmp6" | "icmpv6" |'
75
- str.gsub!(/"cspf"(.*)"cspf-link"/) { %["cspf-link"#$1"cspf"] }
76
- str.gsub!(/"route-filter" (\(\s*control_route_filter_type\s*\))/) { %["route-filter" arg #{$1}.as(:oneline)] }
77
- str.gsub!(/"source-address-filter" (\(\s*control_source_address_filter_type\s*\))/) { %["source-adress-filter" arg #{$1}.as(:oneline)] }
78
66
 
79
- %w[teardown hold-time stub].each do |key|
80
- str.gsub!(/^(\s*"#{key}" \(\s*)c\(/) { "#{$1}sc(" }
67
+ str.gsub!(/^rule\(:regular_expression\) do\s*((?!end).)*\s*end/) do
68
+ <<~EOS
69
+ rule(:regular_expression) do
70
+ (quote | arg).as(:arg)
71
+ end
72
+ EOS
81
73
  end
82
- %w[file confederation].each do |key|
83
- str.gsub!(/^(\s*"#{key}" \(\s*)c\(\s*arg,/) { "#{$1}sca(" }
74
+
75
+ str.gsub!(/^rule\(:login_user_object\) do\s*arg\.as\(:arg\) \(\s*c\(\s*"full-name" arg,/) do
76
+ <<~EOS
77
+ rule(:login_user_object) do
78
+ arg.as(:arg) (
79
+ sc(
80
+ "full-name" (quote | arg),
81
+ EOS
84
82
  end
85
- %w[exact longer orlonger].each do |key|
86
- str.gsub!(/^(\s*"#{key}") arg/) { "#{$1}" }
83
+
84
+ str.gsub!(/^(\s*)"location" arg,\s*"contact" arg,/) do
85
+ format(['"location" (quote | arg),',
86
+ '"contact" (quote | arg),'], $1)
87
87
  end
88
88
 
89
+ str.gsub!(/^(\s*)"as-path" \(\s*c\(\s*"path" arg/) do
90
+ format(['"as-path" (',
91
+ ' c(',
92
+ ' "path" (quote | arg)'], $1)
93
+ end
89
94
 
90
- str.gsub!(/^(\s*)"ieee-802.3ad" \(\s*c\(\s*"lacp" \(\s*c\(/) do
91
- format(['"802.3ad" (',
92
- ' ca(',
93
- ' "lacp" (',
94
- ' c(',
95
- ' "force-up",'], $1)
95
+ str.gsub!(/^(\s*)prefix_list_items,\s*"apply-path" arg/) do
96
+ format(['"apply-path" (quote | arg),',
97
+ 'prefix_list_items'], $1)
96
98
  end
97
- str.gsub!(/^(\s*)"as-path" arg \(\s*c\(\s*arg/) do
98
- format(['"as-path" arg (',
99
- ' c(',
100
- ' quote | arg'], $1)
99
+
100
+ #
101
+ # "arg" matches anything so move to the end
102
+ #
103
+ str.gsub!(/arg \| (".*")/) { "#$1 | arg" }
104
+ str.gsub!(/^(\s*)c\(\s*arg,$/) { "#{$1}ca(" }
105
+ str.gsub!(/(rule\(:control_route_filter_type\) do\s*)s\(\s*arg,/) { "#{$1}b(" }
106
+ str.gsub!(/(rule\(:control_source_address_filter_type\) do\s*)s\(\s*arg,/) { "#{$1}b(" }
107
+ str.gsub!(/^(rule\(:trace_file_type\) do\s*)ca\(/) { "#{$1}sca(" }
108
+
109
+ str.gsub!(/^(rule\(:archive_object\) do\s*)c\(/) { "#{$1}sc(" }
110
+ str.gsub!(/^(rule\(:server_group_type\) do\s*)c\(\s*c\(\s*arg\s*\)\s*\)/) { "#{$1}s(arg, arg)" }
111
+
112
+ str.gsub!(/^(rule\(:rib_group_inet_type\) do)\s*c\(\s*arg/) do
113
+ format([$1,
114
+ ' ca(',
115
+ ' a(arg, arg)'], '')
101
116
  end
102
- str.gsub!(/^(\s*)"priority" \(\s*c\(\s*arg,\s*arg\s*\)/) do
117
+
118
+ # Fix overkill
119
+ str.gsub!(/^(\s*)"priority" \(\s*ca\(\s*arg\s*\)/) do
103
120
  format(['"priority" (',
104
121
  ' a(arg, arg)', $1])
105
122
  end
106
- str.gsub!(/^(\s*)"path" arg \(\s*c\(\s*c\(\s*"abstract",\s*c\(\s*"loose",\s*"loose-link",\s*"strict"\s*\)\s*\)\.as\(:oneline\)/) do
123
+
124
+ #
125
+ # Longer pattern first
126
+ #
127
+ str.gsub!(/"cspf"(.*)"cspf-link"/) { %["cspf-link"#$1"cspf"] }
128
+ str.gsub!(/"http"(.*)"https"/) { %["https"#$1"http"] }
129
+ str.gsub!(/"inet"(.*)"inet6"/) { %["inet6"#$1"inet"] }
130
+ str.gsub!(/"icmp"(.*)"icmp6"/) { %["icmp6"#$1"icmp"] }
131
+ str.gsub!(/"icmp"(.*)"icmpv6"/) { %["icmpv6"#$1"icmp"] }
132
+ str.gsub!(/"snmp"(.*)"snmptrap"/) { %["snmptrap"#$1"snmp"] }
133
+
134
+ %w[ccc ethernet-over-atm tcc vpls bridge].each do |encap|
135
+ str.gsub!(/"ethernet"(.*)"ethernet-#{encap}"/) { %["ethernet-#{encap}"#$1"ethernet"] }
136
+ end
137
+
138
+ str.gsub!(/^(\s*)"path" arg \(\s*c\(\s*sc\(\s*"abstract",\s*c\(\s*"loose",\s*"loose-link",\s*"strict"\s*\)\s*\)\.as\(:oneline\)/) do
107
139
  format(['"path" arg (',
108
140
  ' c(',
109
141
  ' b(',
@@ -119,48 +151,51 @@ module Junoser
119
151
  ' )', $1])
120
152
  end
121
153
 
122
- str.gsub!(/^(\s*)c\(\s*\("default"\)\s*\)/) do
123
- format(['c(',
124
- ' ("default" | arg)',
125
- ')'], $1)
126
- end
154
+ #
155
+ # Fix .xsd: Elements without "nokeyword" flag
156
+ #
157
+ str.gsub!(/\((.*) \| "name"\)/) { "(#$1 | arg)" }
158
+ str.gsub! '"vlan" ("all" | "vlan-name")', '"vlan" ("all" | arg)'
159
+ str.gsub!(/\((.*) \| "vlan-id"\)/) { "(#$1 | arg)" }
127
160
 
128
- str.gsub!(/^rule\(:regular_expression\) do\s*((?!end).)*\s*end/) do
129
- format(['rule(:regular_expression) do',
130
- ' (quote | arg).as(:arg)',
131
- 'end'])
132
- end
133
- str.gsub!(/^rule\(:login_user_object\) do\s*arg\.as\(:arg\) \(\s*c\(\s*"full-name" arg,/) do
134
- format(['rule(:login_user_object) do',
135
- ' arg.as(:arg) (',
136
- ' sc(',
137
- ' "full-name" (quote | arg),'])
161
+ %w[filename].each do |key|
162
+ str.gsub! %["#{key}" arg], 'arg'
138
163
  end
139
164
 
140
- str.gsub!(/(rule\(:control_route_filter_type\) do\s*)s\(\s*arg,/) { "#{$1}b(" }
141
- str.gsub!(/(rule\(:control_source_address_filter_type\) do\s*)s\(\s*arg,/) { "#{$1}b(" }
142
- str.gsub!(/^(rule\(:trace_file_type\) do\s*)c\(\s*arg,/) { "#{$1}sca(" }
143
- str.gsub!(/^(rule\(:archive_object\) do\s*)c\(/) { "#{$1}sc(" }
144
- str.gsub!(/^(rule\(:server_group_type\) do\s*)c\(\s*c\(\s*arg\s*\)\s*\)/) { "#{$1}s(arg, arg)" }
145
- str.gsub!(/^(rule\(:rib_group_inet_type\) do)\s*c\(\s*arg/) do
146
- format([$1,
147
- ' ca(',
148
- ' a(arg, arg)'], '')
149
- end
165
+ # "filename" fix above leaves "arg". Move to the end
166
+ str.gsub!(/^(rule\(:esp_trace_file_type\) do\s*)c\(\s*arg,/) { "#{$1}ca(" }
150
167
 
151
- str.gsub!(/^(\s*)c\(\s*arg,$/) { "#{$1}ca(" }
168
+ # Fix .xsd: system processes dhcp is valid on some platforms
169
+ str.gsub! '"dhcp-service" (', '("dhcp-service" | "dhcp") ('
152
170
 
153
- str.gsub!(/^(\s*)"location" arg,\s*"contact" arg,/) do
154
- format(['"location" (quote | arg),',
155
- '"contact" (quote | arg),'], $1)
171
+ # Fix .xsd: "icmpv6" is also acceptable
172
+ str.gsub! '"icmp6" |', '"icmp6" | "icmpv6" |'
173
+
174
+ #
175
+ # Fix .xsd: "arg" is missing
176
+ #
177
+ str.gsub!(/"route-filter" (\(\s*control_route_filter_type\s*\))/) { %["route-filter" arg #{$1}.as(:oneline)] }
178
+ str.gsub!(/"source-address-filter" (\(\s*control_source_address_filter_type\s*\))/) { %["source-adress-filter" arg #{$1}.as(:oneline)] }
179
+ %w[file].each do |key|
180
+ str.gsub!(/^(\s*"#{key}" \(\s*)c\(\s*arg,/) { "#{$1}sca(" }
156
181
  end
157
182
 
158
- str.gsub!(/^(\s*)"as-path" \(\s*c\(\s*"path" arg/) do
159
- format(['"as-path" (',
160
- ' c(',
161
- ' "path" (quote | arg)'], $1)
183
+ # Fix .xsd: Unnecessary "arg" is added
184
+ %w[exact longer orlonger].each do |key|
185
+ str.gsub!(/^(\s*"#{key}") arg/) { "#{$1}" }
186
+ end
187
+
188
+ # Fix .xsd: "ieee-802.3ad" is invalid
189
+ str.gsub! '"ieee-802.3ad"', '"802.3ad"'
190
+
191
+ # Fix .xsd: "class-of-service interfaces all unit * classifiers exp foo"
192
+ str.gsub!(/^(\s*)sc\(\s*\("default"\)\s*\)/) do
193
+ format(['c(',
194
+ ' ("default" | arg)',
195
+ ')'], $1)
162
196
  end
163
197
 
198
+ # Fix .xsd: "from-zone" arg is also required
164
199
  str.gsub!(/^(\s*)"policy" \(\s*s\(\s*arg,\s*"to-zone-name" arg,\s*c\(\s*"policy" \(\s*policy_type\s*\)\s*\)/) do
165
200
  format(['b(s("from-zone", arg, "to-zone", arg),',
166
201
  ' b("policy", policy_type',
@@ -1,3 +1,3 @@
1
1
  module Junoser
2
- VERSION = "0.3.12"
2
+ VERSION = "0.3.13"
3
3
  end
@@ -1,13 +1,14 @@
1
1
  module Junoser
2
2
  module Xsd
3
3
  module Base
4
- attr_reader :xml
4
+ attr_reader :xml, :parent
5
5
 
6
6
  OFFSET = ' '
7
7
 
8
8
  def initialize(xml, options={})
9
9
  @xml = xml
10
10
  @depth = options[:depth] || 0
11
+ @parent = options[:parent]
11
12
  end
12
13
 
13
14
  def config
@@ -32,13 +33,13 @@ module Junoser
32
33
  ']>'].join("\n#{OFFSET*(@depth+1)}")
33
34
  end
34
35
 
35
-
36
- private
37
-
38
36
  def oneliner?
39
37
  @oneliner ||= !xml.xpath('./xsd:annotation/xsd:appinfo/flag[text()="oneliner"]').empty?
40
38
  end
41
39
 
40
+
41
+ private
42
+
42
43
  def nokeyword?
43
44
  @nokeyword ||= !xml.xpath('./xsd:annotation/xsd:appinfo/flag[text()="nokeyword"]').empty?
44
45
  end
@@ -10,9 +10,9 @@ module Junoser
10
10
  @config ||= children.map {|child|
11
11
  case child.name
12
12
  when 'element'
13
- Junoser::Xsd::Element.new(child, depth: @depth+1)
13
+ Junoser::Xsd::Element.new(child, depth: @depth+1, parent: self)
14
14
  when 'choice'
15
- Junoser::Xsd::Choice.new(child, depth: @depth+1)
15
+ Junoser::Xsd::Choice.new(child, depth: @depth+1, parent: self)
16
16
  else
17
17
  raise "ERROR: unknown element: #{child.name}"
18
18
  end
@@ -29,6 +29,10 @@ module Junoser
29
29
  format('c(', config.map(&:to_s).join(",\n"), ')')
30
30
  end
31
31
  end
32
+
33
+ def unbounded?
34
+ xml['maxOccurs'] == 'unbounded'
35
+ end
32
36
  end
33
37
  end
34
38
  end
@@ -18,9 +18,9 @@ module Junoser
18
18
  @config ||= children.map {|child|
19
19
  case child.name
20
20
  when 'sequence'
21
- Junoser::Xsd::Sequence.new(child, depth: @depth+1)
21
+ Junoser::Xsd::Sequence.new(child, depth: @depth+1, parent: self)
22
22
  when 'simpleContent'
23
- Junoser::Xsd::SimpleContent.new(child, depth: @depth+1)
23
+ Junoser::Xsd::SimpleContent.new(child, depth: @depth+1, parent: self)
24
24
  when 'attribute'
25
25
  'arg'
26
26
  else
@@ -52,7 +52,7 @@ module Junoser
52
52
  def argument
53
53
  return unless @argument
54
54
 
55
- arg = Junoser::Xsd::Element.new(@argument, depth: @depth+1).config
55
+ arg = Junoser::Xsd::Element.new(@argument, depth: @depth+1, parent: self).config
56
56
  raise "ERROR: argument shouldn't consist of multiple elements" if arg.size > 1
57
57
 
58
58
  if root?
@@ -16,9 +16,9 @@ module Junoser
16
16
  @config ||= children.map {|child|
17
17
  case child.name
18
18
  when 'complexType'
19
- Junoser::Xsd::ComplexType.new(child, depth: @depth+1)
19
+ Junoser::Xsd::ComplexType.new(child, depth: @depth+1, parent: self)
20
20
  when 'simpleType'
21
- Junoser::Xsd::SimpleType.new(child, depth: @depth+1)
21
+ Junoser::Xsd::SimpleType.new(child, depth: @depth+1, parent: self)
22
22
  else
23
23
  raise "ERROR: unknown element: #{child.name}"
24
24
  end
@@ -70,7 +70,7 @@ module Junoser
70
70
  when @argument.name == 'simpleType'
71
71
  'arg'
72
72
  else
73
- arg = Junoser::Xsd::Element.new(@argument, depth: @depth+1).config
73
+ arg = Junoser::Xsd::Element.new(@argument, depth: @depth+1, parent: self).config
74
74
  raise "ERROR: argument shouldn't consist of multiple elements" if arg.size > 1
75
75
  arg.first.to_s.strip
76
76
  end
@@ -97,6 +97,10 @@ module Junoser
97
97
 
98
98
  def documentation
99
99
  @documentation ||= xml.xpath('./xsd:annotation/xsd:documentation').text
100
+
101
+ # Translate multiline documentation into a single line to make it parsable in further processes
102
+ @documentation.gsub! /\n\s*/, ' '
103
+
100
104
  @documentation.empty? ? nil : @documentation
101
105
  end
102
106
  end
@@ -17,9 +17,9 @@ module Junoser
17
17
  @config ||= children.map {|child|
18
18
  case child.name
19
19
  when 'enumeration'
20
- Junoser::Xsd::Enumeration.new(child, depth: @depth+1)
20
+ Junoser::Xsd::Enumeration.new(child, depth: @depth+1, parent: self)
21
21
  when 'simpleType'
22
- Junoser::Xsd::SimpleType.new(child, depth: @depth+1)
22
+ Junoser::Xsd::SimpleType.new(child, depth: @depth+1, parent: self)
23
23
  when 'attribute'
24
24
  else
25
25
  raise "ERROR: unknown element: #{child.name}"
@@ -11,9 +11,9 @@ module Junoser
11
11
  @config ||= children.map {|child|
12
12
  case child.name
13
13
  when 'choice'
14
- Junoser::Xsd::Choice.new(child, depth: @depth+1)
14
+ Junoser::Xsd::Choice.new(child, depth: @depth+1, parent: self)
15
15
  when 'element'
16
- Junoser::Xsd::Element.new(child, depth: @depth+1)
16
+ Junoser::Xsd::Element.new(child, depth: @depth+1, parent: self)
17
17
  when 'any'
18
18
  'any'
19
19
  else
@@ -28,7 +28,15 @@ module Junoser
28
28
  when has_single_child_of?(Junoser::Xsd::Choice)
29
29
  child = config.first
30
30
  str = child.config.map(&:to_s).reject(&:empty?).join(",\n")
31
- format('c(', str, ')') unless str.empty?
31
+
32
+ return if str.empty?
33
+
34
+ # Assuming that <xsd:sequence> always has <xsd:complexType> as the parent
35
+ if parent.parent&.oneliner? && config.first.unbounded?
36
+ format('sc(', str, ')')
37
+ else
38
+ format('c(', str, ')')
39
+ end
32
40
  else
33
41
  str = config.map {|c| c.is_a?(String) ? format(OFFSET + c) : c.to_s }.reject(&:empty?).join(",\n")
34
42
  format('s(', str, ')')
@@ -10,7 +10,7 @@ module Junoser
10
10
  @config ||= children.map {|child|
11
11
  case child.name
12
12
  when 'restriction'
13
- Junoser::Xsd::Restriction.new(child, depth: @depth+1)
13
+ Junoser::Xsd::Restriction.new(child, depth: @depth+1, parent: self)
14
14
  when 'extension'
15
15
  'arg'
16
16
  else
@@ -11,9 +11,9 @@ module Junoser
11
11
  @config ||= children.map {|child|
12
12
  case child.name
13
13
  when 'restriction'
14
- Junoser::Xsd::Restriction.new(child, depth: @depth+1)
14
+ Junoser::Xsd::Restriction.new(child, depth: @depth+1, parent: self)
15
15
  when 'union'
16
- Junoser::Xsd::Union.new(child, depth: @depth+1)
16
+ Junoser::Xsd::Union.new(child, depth: @depth+1, parent: self)
17
17
  else
18
18
  raise "ERROR: unknown element: #{child.name}"
19
19
  end
@@ -9,7 +9,7 @@ module Junoser
9
9
  @config ||= children.map {|child|
10
10
  case child.name
11
11
  when 'simpleType'
12
- Junoser::Xsd::SimpleType.new(child, depth: @depth+1)
12
+ Junoser::Xsd::SimpleType.new(child, depth: @depth+1, parent: self)
13
13
  else
14
14
  raise "ERROR: unknown element: #{child.name}"
15
15
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: junoser
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.12
4
+ version: 0.3.13
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shintaro Kojima
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-02-06 00:00:00.000000000 Z
11
+ date: 2020-05-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: parslet
@@ -44,14 +44,14 @@ dependencies:
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '10.0'
47
+ version: '13.0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '10.0'
54
+ version: '13.0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: nokogiri
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -99,6 +99,8 @@ files:
99
99
  - Rakefile
100
100
  - bin/console
101
101
  - bin/setup
102
+ - example/get-schema.xml
103
+ - example/junos-18.1R3-S9.rb
102
104
  - example/vmx-17.2R1.13.rb
103
105
  - example/vsrx-12.1.x47.rb
104
106
  - example/vsrx-18.3R1.9.rb