junoser 0.3.12 → 0.3.13

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.
@@ -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