fluent-plugin-telemetry-iosxe 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 62be67bb9c7c1ef02a5bf9e260b571ddfe3abfe0
4
- data.tar.gz: 8548dd316fd7999eac791f7ab5cdd02bda013f13
3
+ metadata.gz: c069a9e9a4437641954f364633f3b247c8cadcd6
4
+ data.tar.gz: 4f30e86445e81c7c5d644522d1ba07763bdc3e11
5
5
  SHA512:
6
- metadata.gz: 1e8d6d34402473d30097a88f190ec4e956eccf0cfe2c766cfd7124e6986d4dd65e588e063421113f6f5be1371628ce8e6b7e17e4492fc135d9ac32845c4cd722
7
- data.tar.gz: f3d64da56e125b5282f794195a4e9cc48ea3504fdb5331de7e6138bb9373effdfbb9c8aa50edd5a3ceba41d6822eff8dc3510d0f1ed178d0034c3ce266d5a31d
6
+ metadata.gz: 18533bfd476b6056e937abb63f0532bb7051884e747ebf193671677eca6fd810db6facf551f2b6349be13f2a1d69e1398fc224665d8f9854193f5345a11921af
7
+ data.tar.gz: 86833af049566697d894f064b9c2d6db1718d08c416925c96dd4f2e3c8d3c39ced6d765567f578033cfad952b180e3d3eeebf1dabb10823d0084c9a0b6d5546c
data/Gemfile CHANGED
File without changes
@@ -1,58 +1,58 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- fluent-plugin-telemetry-iosxe (0.0.2)
4
+ fluent-plugin-telemetry-iosxe (0.0.3)
5
5
  fluentd (>= 0.14.10, < 2)
6
- net-ssh (~> 4.2.0)
7
- nokogiri (~> 1.8.1)
6
+ net-ssh (~> 5.1.0)
7
+ nokogiri (~> 1.10.0)
8
8
  nori (~> 2.6.0)
9
9
 
10
10
  GEM
11
11
  remote: https://rubygems.org/
12
12
  specs:
13
13
  cool.io (1.5.3)
14
- fluentd (1.0.1)
14
+ dig_rb (1.0.1)
15
+ fluentd (1.3.3)
15
16
  cool.io (>= 1.4.5, < 2.0.0)
17
+ dig_rb (~> 1.0.0)
16
18
  http_parser.rb (>= 0.5.1, < 0.7.0)
17
19
  msgpack (>= 0.7.0, < 2.0.0)
18
- ruby_dig (~> 0.0.2)
19
20
  serverengine (>= 2.0.4, < 3.0.0)
20
21
  sigdump (~> 0.2.2)
21
- strptime (~> 0.1)
22
+ strptime (>= 0.2.2, < 1.0.0)
22
23
  tzinfo (~> 1.0)
23
24
  tzinfo-data (~> 1.0)
24
25
  yajl-ruby (~> 1.0)
25
26
  http_parser.rb (0.6.0)
26
- mini_portile2 (2.3.0)
27
- msgpack (1.2.0)
28
- net-ssh (4.2.0)
29
- nokogiri (1.8.1)
30
- mini_portile2 (~> 2.3.0)
27
+ mini_portile2 (2.4.0)
28
+ msgpack (1.2.6)
29
+ net-ssh (5.1.0)
30
+ nokogiri (1.10.0)
31
+ mini_portile2 (~> 2.4.0)
31
32
  nori (2.6.0)
32
33
  power_assert (1.1.1)
33
34
  rake (12.3.0)
34
- ruby_dig (0.0.2)
35
- serverengine (2.0.5)
35
+ serverengine (2.1.0)
36
36
  sigdump (~> 0.2.2)
37
37
  sigdump (0.2.4)
38
- strptime (0.1.9)
38
+ strptime (0.2.3)
39
39
  test-unit (3.2.6)
40
40
  power_assert
41
41
  thread_safe (0.3.6)
42
- tzinfo (1.2.4)
42
+ tzinfo (1.2.5)
43
43
  thread_safe (~> 0.1)
44
- tzinfo-data (1.2017.3)
44
+ tzinfo-data (1.2018.9)
45
45
  tzinfo (>= 1.0.0)
46
- yajl-ruby (1.3.1)
46
+ yajl-ruby (1.4.1)
47
47
 
48
48
  PLATFORMS
49
49
  ruby
50
50
 
51
51
  DEPENDENCIES
52
- bundler (~> 1.14)
52
+ bundler (~> 2.0.1)
53
53
  fluent-plugin-telemetry-iosxe!
54
54
  rake (~> 12.0)
55
55
  test-unit (~> 3.0)
56
56
 
57
57
  BUNDLED WITH
58
- 1.16.0
58
+ 2.0.1
data/LICENSE CHANGED
File without changes
data/README.md CHANGED
@@ -42,7 +42,7 @@ Collect telemetry input and then output to stdout.
42
42
  port 830
43
43
  user admin
44
44
  password admin
45
- xpath_filter /ios-emul-oper-db:ios-emul-oper-db/cpu-usage/five-seconds
45
+ xpath_filters /process-cpu-ios-xe-oper:cpu-usage/cpu-utilization/five-seconds
46
46
  tag cpu-usage-five-seconds
47
47
  period 500
48
48
  @label @telemetry
@@ -54,6 +54,15 @@ Collect telemetry input and then output to stdout.
54
54
  </label>
55
55
  ```
56
56
 
57
+ The output is as below.
58
+
59
+ ```
60
+ 2018-12-14 03:30:54.000000000 +0000 cpu-usage-five-seconds: {"cpu_usage":{"cpu_utilization":{"five_seconds":1}}}
61
+ 2018-12-14 03:30:59.000000000 +0000 cpu-usage-five-seconds: {"cpu_usage":{"cpu_utilization":{"five_seconds":2}}}
62
+ 2018-12-14 03:31:04.000000000 +0000 cpu-usage-five-seconds: {"cpu_usage":{"cpu_utilization":{"five_seconds":1}}}
63
+ ...
64
+ ```
65
+
57
66
  ### Configuration Example 2
58
67
 
59
68
  Collect telemetry input and then output to InfluxDB with flattening input.
@@ -63,7 +72,7 @@ Collect telemetry input and then output to InfluxDB with flattening input.
63
72
  @type telemetry_iosxe
64
73
  server 192.0.2.1
65
74
  port 830
66
- xpath_filter /ios-emul-oper-db:ios-emul-oper-db/cpu-usage/five-seconds
75
+ xpath_filters /process-cpu-ios-xe-oper:cpu-usage/cpu-utilization/five-seconds
67
76
  user admin
68
77
  password admin
69
78
  tag cpu-usage-five-seconds
@@ -87,6 +96,19 @@ Collect telemetry input and then output to InfluxDB with flattening input.
87
96
  </match>
88
97
  </label>
89
98
  ```
99
+ The inserted date on InfluxDB is as below.
100
+
101
+ ```
102
+ > select * from "cpu-usage-five-seconds" limit 5
103
+ name: cpu-usage-five-seconds
104
+ time cpu_usage.cpu_utilization.five_seconds
105
+ ---- --------------------------------------
106
+ 1544759262000000000 1
107
+ 1544759267000000000 2
108
+ 1544759272000000000 1
109
+ 1544759277000000000 2
110
+ 1544759282000000000 1
111
+ ```
90
112
 
91
113
  **server**
92
114
 
@@ -99,7 +121,11 @@ TCP port number to subscribe to Telemetry publisher.
99
121
 
100
122
  **xpath_filter**
101
123
 
102
- XPath filter to specify the information element to subscribe to.
124
+ This parameter is deprecated. Use 'xpath_filters' instead.
125
+
126
+ **xpath_filters**
127
+
128
+ XPath filters to specify the information element to subscribe to.
103
129
 
104
130
  **user**
105
131
 
data/Rakefile CHANGED
File without changes
@@ -3,7 +3,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
3
 
4
4
  Gem::Specification.new do |spec|
5
5
  spec.name = "fluent-plugin-telemetry-iosxe"
6
- spec.version = "0.0.2"
6
+ spec.version = "0.0.3"
7
7
  spec.authors = ["Tetsuhiro Sato"]
8
8
  spec.email = ["tetsusat@cisco.com"]
9
9
 
@@ -20,11 +20,11 @@ Gem::Specification.new do |spec|
20
20
  spec.test_files = test_files
21
21
  spec.require_paths = ["lib"]
22
22
 
23
- spec.add_development_dependency "bundler", "~> 1.14"
23
+ spec.add_development_dependency "bundler", "~> 2.0.1"
24
24
  spec.add_development_dependency "rake", "~> 12.0"
25
25
  spec.add_development_dependency "test-unit", "~> 3.0"
26
26
  spec.add_runtime_dependency "fluentd", [">= 0.14.10", "< 2"]
27
- spec.add_runtime_dependency "net-ssh", ["~> 4.2.0"]
28
- spec.add_runtime_dependency "nokogiri", ["~> 1.8.1"]
27
+ spec.add_runtime_dependency "net-ssh", ["~> 5.1.0"]
28
+ spec.add_runtime_dependency "nokogiri", ["~> 1.10.0"]
29
29
  spec.add_runtime_dependency "nori", ["~> 2.6.0"]
30
30
  end
@@ -21,7 +21,8 @@ module Fluent
21
21
  config_param :user, :string, default: "admin"
22
22
  config_param :password, :string, default: "admin", secret: true
23
23
  config_param :parser, :enum,list: [:rexml, :nokogiri], default: :nokogiri
24
- config_param :xpath_filter, :string
24
+ config_param :xpath_filter, :string, default: nil, deprecated: "Use 'xpath_filters' instead"
25
+ config_param :xpath_filters, :array, value_type: :string
25
26
  config_param :tag, :string
26
27
  config_param :period, :integer
27
28
  config_param :strip_namespaces, :bool, default: true
@@ -40,6 +41,8 @@ module Fluent
40
41
  @sigint = true
41
42
  end
42
43
  @hello_done = false
44
+ @subscription_index = 0
45
+ @subscription_ids = []
43
46
  @buffer = ""
44
47
  @parser = Nori.new(:parser => @parser, :advanced_typecasting => false)
45
48
  hello = <<-EOS
@@ -47,21 +50,11 @@ module Fluent
47
50
  <hello xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
48
51
  <capabilities>
49
52
  <capability>urn:ietf:params:netconf:base:1.0</capability>
53
+ <capability>urn:ietf:params:netconf:base:1.1</capability>
50
54
  </capabilities>
51
55
  </hello>]]>]]>
52
56
  EOS
53
57
 
54
- subscription = <<-EOS
55
- <?xml version="1.0" encoding="utf-8"?>
56
- <rpc message-id="101" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
57
- <establish-subscription xmlns="urn:ietf:params:xml:ns:yang:ietf-event-notifications" xmlns:yp="urn:ietf:params:xml:ns:yang:ietf-yang-push">
58
- <stream>yp:yang-push</stream>
59
- <yp:xpath-filter>#{@xpath_filter}</yp:xpath-filter>
60
- <yp:period>#{@period}</yp:period>
61
- </establish-subscription>
62
- </rpc>
63
- EOS
64
-
65
58
  @ssh = Net::SSH.start(@server, @user, :port => @port, :password => @password, :timeout => 10)
66
59
  @channel = @ssh.open_channel do |channel|
67
60
  channel.subsystem("netconf") do |ch, success|
@@ -79,91 +72,157 @@ module Fluent
79
72
  end
80
73
  log.info "send hello"
81
74
  ch.send_data(hello)
82
- log.info "send subscription"
83
- ch.send_data(subscription)
84
75
  end
85
76
  end
86
- @ssh.loop(1) { not @sigint } # if we get sigint, we need to end loop
77
+ @ssh.loop(1) { not @sigint } # if we get sigint, we need to end loop
87
78
  end
88
79
 
89
- def shutdown
90
- log.info "shutdown ..."
80
+ protected
81
+ def receive_data(data)
82
+ log.debug "receive data ..."
83
+ if @hello_done # Chunked Framing
84
+ if data.include?('##')
85
+ if data == '##'
86
+ parse()
87
+ else
88
+ data.each_line do |line|
89
+ if not line =~ /^(#\d+|##)/
90
+ @buffer << line
91
+ end
92
+ end
93
+ parse()
94
+ end
95
+ else
96
+ data.each_line do |line|
97
+ if not line =~ /^#\d+/
98
+ @buffer << line
99
+ end
100
+ end
101
+ end
102
+ else # End-of-Message Framing
103
+ if data.include?(']]>]]>')
104
+ if data == ']]>]]>'
105
+ parse()
106
+ else
107
+ data.each_line do |line|
108
+ if line != ']]>]]>'
109
+ @buffer << line
110
+ end
111
+ end
112
+ parse()
113
+ end
114
+ else
115
+ @buffer << data
116
+ end
117
+ end
118
+ end
119
+
120
+ def parse
121
+ log.debug "parse!"
122
+ log.debug @buffer
123
+ d = @parser.parse(@buffer)
124
+ if d['hello']
125
+ handle_hello(d)
126
+ @hello_done = true
127
+ subscribe()
128
+ elsif d['notification']
129
+ handle_notification(d)
130
+ elsif d["rpc_reply"]
131
+ if d["rpc_reply"]["subscription_id"]
132
+ handle_subscription_reply(d)
133
+ if @subscription_index < @xpath_filters.size
134
+ subscribe()
135
+ end
136
+ else
137
+ log.fatal d["rpc_reply"]["subscription_result"]
138
+ end
139
+ else
140
+ log.warn "got other messages"
141
+ log.debug d
142
+ end
143
+ @buffer = ''
144
+ end
145
+
146
+ def handle_hello(data)
147
+ log.info "got hello session_id=#{data["hello"]["session_id"]}"
148
+ log.debug data
149
+ @session_id = data["hello"]["session_id"]
150
+ end
151
+
152
+ def subscribe
153
+ subscription = <<-EOS
154
+ <?xml version="1.0" encoding="utf-8"?>
155
+ <rpc message-id="#{@subscription_index+1}" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
156
+ <establish-subscription xmlns="urn:ietf:params:xml:ns:yang:ietf-event-notifications" xmlns:yp="urn:ietf:params:xml:ns:yang:ietf-yang-push">
157
+ <stream>yp:yang-push</stream>
158
+ <yp:xpath-filter>#{@xpath_filters[@subscription_index]}</yp:xpath-filter>
159
+ <yp:period>#{@period}</yp:period>
160
+ </establish-subscription>
161
+ </rpc>
162
+ EOS
163
+ log.info "subscribe [#{@subscription_index+1}] #{@xpath_filters[@subscription_index]}"
164
+ log.debug chunk_frame(subscription.chomp)
165
+ @channel.send_data(chunk_frame(subscription.chomp))
166
+ @channel.send_data("\n##\n")
167
+ @subscription_index += 1
168
+ end
169
+
170
+ def unsubscribe(id)
91
171
  delete_subscription = <<-EOS
92
172
  <?xml version="1.0" encoding="utf-8"?>
93
173
  <rpc message-id="101" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
94
174
  <delete-subscription xmlns="urn:ietf:params:xml:ns:yang:ietf-event-notifications" xmlns:netconf="urn:ietf:params:xml:ns:netconf:base:1.0">
95
- <subscription-id>#{@subscription_id}</subscription-id>
175
+ <subscription-id>#{id}</subscription-id>
96
176
  </delete-subscription>
97
- </rpc>]]>]]>
177
+ </rpc>
98
178
  EOS
179
+ log.info "unubscribe subscription_id=#{id}"
180
+ log.debug chunk_frame(delete_subscription.chomp)
181
+ @channel.send_data(chunk_frame(delete_subscription.chomp))
182
+ @channel.send_data("\n##\n")
183
+ end
184
+
185
+ def shutdown
186
+ log.info "shutdown ..."
187
+ for id in @subscription_ids
188
+ unsubscribe(id)
189
+ end
99
190
  close_session = <<-EOS
100
191
  <?xml version="1.0" encoding="utf-8"?>
101
192
  <rpc message-id="101" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
102
193
  <close-session/>
103
- </rpc>]]>]]>
194
+ </rpc>
104
195
  EOS
105
- @channel.send_data(delete_subscription)
106
- @channel.send_data(close_session)
196
+ @channel.send_data(chunk_frame(close_session.chomp))
197
+ @channel.send_data("\n##\n")
107
198
  @ssh.close
108
199
  super
109
200
  end
110
201
 
111
- protected
112
- def receive_data(data)
113
- log.info "receive data ..."
114
- if data.include?("]]>]]>")
115
- msg = data.split("]]>]]>")
116
- if msg.empty? # this could happen when data is exactly "]]>]]>"
117
- if @hello_done
118
- parse_msg()
119
- else
120
- parse_hello()
121
- @hello_done = true
122
- end
123
- else
124
- for m in msg
125
- @buffer << m
126
- if @hello_done
127
- parse_msg()
128
- else
129
- parse_hello()
130
- @hello_done = true
131
- end
132
- end
133
- end
134
- else
135
- @buffer << data
136
- end
137
- end
138
-
139
- def parse_hello
140
- hello = @parser.parse(@buffer)
141
- log.debug hello
142
- @session_id = hello["hello"]["session_id"]
143
- log.info "Session ID is #{@session_id}"
144
- @buffer = ""
202
+ def chunk_frame(msg)
203
+ "\n##{msg.length}\n" << msg
145
204
  end
146
205
 
147
- def parse_msg
148
- h = @parser.parse(@buffer)
149
- log.debug h
150
- if h["notification"]
151
- iso8601_time = h["notification"]["eventTime"]
152
- unix_time = Time.iso8601(iso8601_time).to_i
153
- content = h["notification"]["push_update"]["datastore_contents_xml"]
154
- traverse(content) do |node, key, parent|
155
- if @typecast_integer && node.is_i?
156
- parent[key] = node.to_i unless parent.nil?
157
- elsif @typecast_float && node.is_f?
158
- parent[key] = node.to_f unless parent.nil?
159
- end
206
+ def handle_notification(data)
207
+ log.info "got notification"
208
+ log.debug data
209
+ iso8601_time = data["notification"]["eventTime"]
210
+ unix_time = Time.iso8601(iso8601_time).to_i
211
+ content = data["notification"]["push_update"]["datastore_contents_xml"]
212
+ traverse(content) do |node, key, parent|
213
+ if @typecast_integer && node.is_i?
214
+ parent[key] = node.to_i unless parent.nil?
215
+ elsif @typecast_float && node.is_f?
216
+ parent[key] = node.to_f unless parent.nil?
160
217
  end
161
- router.emit(@tag, unix_time, content)
162
- elsif h["rpc_reply"] && h["rpc_reply"]["subscription_id"]
163
- @subscription_id = h["rpc_reply"]["subscription_id"]
164
- log.info "Subscription ID is #{@subscription_id}"
165
218
  end
166
- @buffer = ""
219
+ router.emit(@tag, unix_time, content)
220
+ end
221
+
222
+ def handle_subscription_reply(data)
223
+ log.info "got subscription reply subscription_id=#{data['rpc_reply']['subscription_id']}"
224
+ log.debug data
225
+ @subscription_ids << data["rpc_reply"]["subscription_id"]
167
226
  end
168
227
 
169
228
  def traverse(obj, key=nil, parent=nil, &blk)
File without changes
File without changes
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluent-plugin-telemetry-iosxe
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tetsuhiro Sato
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-12-20 00:00:00.000000000 Z
11
+ date: 2019-01-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.14'
19
+ version: 2.0.1
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.14'
26
+ version: 2.0.1
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -78,28 +78,28 @@ dependencies:
78
78
  requirements:
79
79
  - - "~>"
80
80
  - !ruby/object:Gem::Version
81
- version: 4.2.0
81
+ version: 5.1.0
82
82
  type: :runtime
83
83
  prerelease: false
84
84
  version_requirements: !ruby/object:Gem::Requirement
85
85
  requirements:
86
86
  - - "~>"
87
87
  - !ruby/object:Gem::Version
88
- version: 4.2.0
88
+ version: 5.1.0
89
89
  - !ruby/object:Gem::Dependency
90
90
  name: nokogiri
91
91
  requirement: !ruby/object:Gem::Requirement
92
92
  requirements:
93
93
  - - "~>"
94
94
  - !ruby/object:Gem::Version
95
- version: 1.8.1
95
+ version: 1.10.0
96
96
  type: :runtime
97
97
  prerelease: false
98
98
  version_requirements: !ruby/object:Gem::Requirement
99
99
  requirements:
100
100
  - - "~>"
101
101
  - !ruby/object:Gem::Version
102
- version: 1.8.1
102
+ version: 1.10.0
103
103
  - !ruby/object:Gem::Dependency
104
104
  name: nori
105
105
  requirement: !ruby/object:Gem::Requirement
@@ -150,7 +150,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
150
150
  version: '0'
151
151
  requirements: []
152
152
  rubyforge_project:
153
- rubygems_version: 2.5.2.1
153
+ rubygems_version: 2.6.14.3
154
154
  signing_key:
155
155
  specification_version: 4
156
156
  summary: Fluentd input plugin to collect IOS-XE telemetry.