kumonos 0.10.2 → 0.11.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: f80bafc25db408cb0165a8d5dd67dec8b9719420
4
- data.tar.gz: b007c2291e51524c2188f8d25e0380821f3f1541
2
+ SHA256:
3
+ metadata.gz: 952ff01c0ea52b0ec8b24acf94fc2e58da06ae47d467e349f120c9b7eaff2102
4
+ data.tar.gz: 6ca2a61ce2a1022a7a7cc7bfda0129c15a2a7d145b8afb8f4ed14e7d31db8aa8
5
5
  SHA512:
6
- metadata.gz: aedffb0e21214cc5720532a5edf220b27e7173de44317cadb02d4821d8573c65b6de1937d5cae11dd18ed5eeb20f088c9c153bba7bbf71eafc546db3a7ac307d
7
- data.tar.gz: 92cf7fa7e6341cba6f8d8ec714c45af66ee5fea626f43d3e89a4ccf986f9e71b961aa2a79bd98b2777f1c0ddadcfd5ebb22796a90197126ce56889fa984cb62a
6
+ metadata.gz: 2036f5f8649540ef1e43f4292dfe0b497320046fda0937459778d7b163c5e9073c0102796e854b68da2adff98ae1bd51bc391d07df1fb7d65a22777b7747592c
7
+ data.tar.gz: d65444682fde1eb1b8b7c881a777670c49e4ce68d52e86c1deef573b3da7e59e76dc1351a765c879185a59edae77f444c661c29d192ffb6cee3cb356f7eeed34
@@ -11,7 +11,4 @@ discovery_service:
11
11
  refresh_delay_ms: 30000
12
12
  connect_timeout_ms: 1000
13
13
  statsd:
14
- address: relay:2000
15
- tls: false
16
- type: strict_dns
17
- connect_timeout_ms: 1000
14
+ address: statsd-exporter:9125
data/lib/kumonos/envoy.rb CHANGED
@@ -14,7 +14,7 @@ module Kumonos
14
14
  new(
15
15
  h.fetch('version'),
16
16
  discovery_service,
17
- h['statsd'] ? build_statsd_cluster(h['statsd']) : nil,
17
+ h['statsd'] ? h['statsd'].fetch('address') : nil,
18
18
  Listener.build(h.fetch('listener'), discovery_service),
19
19
  Admin.build(h.fetch('admin'))
20
20
  )
@@ -41,12 +41,41 @@ module Kumonos
41
41
  h.delete(:statsd)
42
42
  h.delete(:listener)
43
43
  h[:admin] = admin.to_h
44
- h[:listeners] = [listener.to_h]
45
- h[:cluster_manager] = { cds: discovery_service.to_h, clusters: [] }
44
+ h[:static_resources] = {
45
+ listeners: [listener.to_h],
46
+ clusters: [discovery_service.cluster.to_h]
47
+ }
48
+ h[:dynamic_resources] = {
49
+ cds_config: {
50
+ api_config_source: {
51
+ cluster_names: [discovery_service.cluster.name],
52
+ refresh_delay: {
53
+ seconds: discovery_service.refresh_delay_ms / 1000.0
54
+ }
55
+ }
56
+ }
57
+ }
46
58
 
47
59
  if statsd
48
- h[:statsd_tcp_cluster_name] = statsd.name
49
- h[:cluster_manager][:clusters] << statsd.to_h
60
+ statsd_address, statsd_port = statsd.split(':')
61
+ h[:stats_sinks] = [
62
+ {
63
+ name: 'envoy.dog_statsd',
64
+ config: {
65
+ address: {
66
+ socket_address: {
67
+ protocol: 'UDP',
68
+ address: statsd_address,
69
+ port_value: Integer(statsd_port)
70
+ }
71
+ }
72
+ }
73
+ }
74
+ ]
75
+ h[:stats_config] = {
76
+ use_all_default_tags: true,
77
+ stats_tags: []
78
+ }
50
79
  end
51
80
 
52
81
  h
@@ -56,7 +85,8 @@ module Kumonos
56
85
  Listener = Struct.new(:address, :access_log_path, :discovery_service) do
57
86
  class << self
58
87
  def build(h, discovery_service)
59
- new(h.fetch('address'), h.fetch('access_log_path'), discovery_service)
88
+ address = AddressParser.call(h.fetch('address'))
89
+ new(address, h.fetch('access_log_path'), discovery_service)
60
90
  end
61
91
  end
62
92
 
@@ -64,21 +94,38 @@ module Kumonos
64
94
  h = super
65
95
  h.delete(:discovery_service)
66
96
  h.delete(:access_log_path)
67
- h[:filters] = [
97
+ h[:name] = 'egress'
98
+ h[:filter_chains] = [
68
99
  {
69
- type: 'read',
70
- name: 'http_connection_manager',
71
- config: {
72
- codec_type: 'auto',
73
- stat_prefix: 'egress_http',
74
- access_log: [{ path: access_log_path }],
75
- rds: {
76
- cluster: discovery_service.cluster.name,
77
- route_config_name: DEFAULT_ROUTE_NAME,
78
- refresh_delay_ms: discovery_service.refresh_delay_ms
79
- },
80
- filters: [{ type: 'decoder', name: 'router', config: {} }]
81
- }
100
+ filters: [
101
+ {
102
+ name: 'envoy.http_connection_manager',
103
+ config: {
104
+ codec_type: 'AUTO',
105
+ stat_prefix: 'egress_http',
106
+ access_log: [
107
+ {
108
+ name: 'envoy.file_access_log',
109
+ config: {
110
+ path: access_log_path
111
+ }
112
+ }
113
+ ],
114
+ rds: {
115
+ config_source: {
116
+ api_config_source: {
117
+ cluster_names: [discovery_service.cluster.name],
118
+ refresh_delay: {
119
+ seconds: discovery_service.refresh_delay_ms / 1000.0
120
+ }
121
+ }
122
+ },
123
+ route_config_name: DEFAULT_ROUTE_NAME
124
+ },
125
+ http_filters: [{ name: 'envoy.router' }]
126
+ }
127
+ }
128
+ ]
82
129
  }
83
130
  ]
84
131
  h
@@ -89,13 +136,14 @@ module Kumonos
89
136
  class << self
90
137
  def build(h)
91
138
  lb = h.fetch('lb')
139
+ host, port = lb.split(':')
92
140
  cluster = Cluster.new(
93
141
  lb.split(':').first,
94
- 'strict_dns',
142
+ 'STRICT_DNS',
95
143
  h.fetch('tls'),
96
144
  h.fetch('connect_timeout_ms'),
97
- 'round_robin',
98
- [{ 'url' => "tcp://#{lb}" }]
145
+ 'ROUND_ROBIN',
146
+ [{ 'socket_address' => { 'address' => host, 'port_value' => Integer(port) } }]
99
147
  )
100
148
  new(h.fetch('refresh_delay_ms'), cluster)
101
149
  end
@@ -117,8 +165,15 @@ module Kumonos
117
165
 
118
166
  def to_h
119
167
  h = super
168
+ h[:type] = type.upcase
169
+ h.delete(:lb_type)
170
+ h[:lb_policy] = lb_type.upcase
120
171
  h.delete(:tls)
121
- h[:ssl_context] = {} if tls
172
+ h[:tls_context] = {} if tls
173
+ h.delete(:connect_timeout_ms)
174
+ h[:connect_timeout] = {
175
+ seconds: connect_timeout_ms / 1000.0
176
+ }
122
177
  h
123
178
  end
124
179
  end
@@ -126,9 +181,24 @@ module Kumonos
126
181
  Admin = Struct.new(:address, :access_log_path) do
127
182
  class << self
128
183
  def build(h)
129
- new(h.fetch('address'), h.fetch('access_log_path'))
184
+ address = AddressParser.call(h.fetch('address'))
185
+ new(address, h.fetch('access_log_path'))
130
186
  end
131
187
  end
132
188
  end
189
+
190
+ # Parse old address string
191
+ module AddressParser
192
+ def self.call(address)
193
+ raise "invalid address given: #{address}" if address !~ %r{tcp://([^:]+):(\d+)}
194
+
195
+ {
196
+ socket_address: {
197
+ address: Regexp.last_match(1),
198
+ port_value: Integer(Regexp.last_match(2))
199
+ }
200
+ }
201
+ end
202
+ end
133
203
  end
134
204
  end
@@ -1,3 +1,3 @@
1
1
  module Kumonos
2
- VERSION = '0.10.2'.freeze
2
+ VERSION = '0.11.0'.freeze
3
3
  end
@@ -85,29 +85,14 @@
85
85
  "statsd": {
86
86
  "type": "object",
87
87
  "id": "/properties/statsd",
88
- "additionalProperties": false,
88
+ "additionalProperties": true,
89
89
  "required": [
90
- "address",
91
- "tls",
92
- "type",
93
- "connect_timeout_ms"
90
+ "address"
94
91
  ],
95
92
  "properties": {
96
93
  "address": {
97
94
  "type": "string",
98
95
  "id": "/properties/statsd/properties/address"
99
- },
100
- "tls": {
101
- "type": "boolean",
102
- "id": "/properties/statsd/properties/tls"
103
- },
104
- "type": {
105
- "type": "string",
106
- "id": "/properties/statsd/properties/type"
107
- },
108
- "connect_timeout_ms": {
109
- "type": "integer",
110
- "id": "/properties/statsd/properties/connect_timeout_ms"
111
96
  }
112
97
  }
113
98
  }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kumonos
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.2
4
+ version: 0.11.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Taiki Ono
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-12-08 00:00:00.000000000 Z
11
+ date: 2018-01-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json-schema
@@ -141,7 +141,6 @@ email:
141
141
  - taiks.4559@gmail.com
142
142
  executables:
143
143
  - kumonos
144
- - kumonos-relay
145
144
  extensions: []
146
145
  extra_rdoc_files: []
147
146
  files:
@@ -162,7 +161,6 @@ files:
162
161
  - example/envoy_config.yml
163
162
  - example/example-with-tls.yml
164
163
  - exe/kumonos
165
- - exe/kumonos-relay
166
164
  - kumonos.gemspec
167
165
  - lib/kumonos.rb
168
166
  - lib/kumonos/clusters.rb
@@ -193,7 +191,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
193
191
  version: '0'
194
192
  requirements: []
195
193
  rubyforge_project:
196
- rubygems_version: 2.6.13
194
+ rubygems_version: 2.7.3
197
195
  signing_key:
198
196
  specification_version: 4
199
197
  summary: A "control plane" for Microservices "service mesh".
data/exe/kumonos-relay DELETED
@@ -1,135 +0,0 @@
1
- #!/usr/bin/env ruby
2
- require 'optparse'
3
- require 'socket'
4
- require 'logger'
5
-
6
- # Convert metric name
7
- class StatConvertor
8
- def initialize(options)
9
- @options = options
10
- end
11
-
12
- def call(line)
13
- convert_status_code(convert_listener(convert_cluster(add_default_tag(line)))) + "\n"
14
- end
15
-
16
- private
17
-
18
- STATS_CODE_PATTERN = /(upstream|downstream)_rq_(\dxx|\d{3})/
19
- def convert_status_code(line)
20
- if line.match(STATS_CODE_PATTERN)
21
- stream = Regexp.last_match(1)
22
- code = Regexp.last_match(2)
23
- [
24
- line.gsub(STATS_CODE_PATTERN, "#{stream}_rq_by_code"),
25
- ",status_code:#{code}"
26
- ].join
27
-
28
- else
29
- line
30
- end
31
- end
32
-
33
- # envoy.cluster.ab-testing.external.upstream_rq_200:1|c
34
- CLUSTER_PATTERN = /\Aenvoy\.cluster\.([^.]+)\./
35
- def convert_cluster(line)
36
- if line.match(CLUSTER_PATTERN)
37
- name = Regexp.last_match(1)
38
- [
39
- line.gsub(CLUSTER_PATTERN, 'envoy.cluster.'),
40
- ",cluster:#{name}"
41
- ].join
42
- else
43
- line
44
- end
45
- end
46
-
47
- # XXX: ipv4 only
48
- # envoy.listener.0.0.0.0_9211.http.egress_http.downstream_rq_5xx:0|c
49
- LISTENER_PATTERN = /\Aenvoy\.listener\.(\d+\.\d+\.\d+.\d+_\d+)./
50
- def convert_listener(line)
51
- if line.match(LISTENER_PATTERN)
52
- listener = Regexp.last_match(1)
53
- [
54
- line.gsub(LISTENER_PATTERN, 'envoy.listener.'),
55
- ",listener:#{listener}"
56
- ].join
57
- else
58
- line
59
- end
60
- end
61
-
62
- def add_default_tag(line)
63
- [
64
- "#{line.chomp}|#",
65
- "service_cluster:#{@options[:service_cluster]},",
66
- "service_node:#{@options[:service_node]},",
67
- "host:#{@options[:host]}"
68
- ].join
69
- end
70
- end
71
-
72
- logger = Logger.new($stderr)
73
- logger.level = ENV['LOG_LEVEL'] || 'info'
74
-
75
- options = {
76
- service_cluster: '',
77
- service_node: '',
78
- host: Socket.gethostname
79
- }
80
- parser = OptionParser.new do |opts|
81
- opts.banner = "Usage: #{__FILE__} [options] bind_address:port remote_address:port"
82
-
83
- opts.on('--service-cluster=VAL (required)') { |v| options[:service_cluster] = v }
84
- opts.on('--service-node=VAL (required)') { |v| options[:service_node] = v }
85
- opts.on('--host=VAL') { |v| options[:host] = v }
86
- end
87
-
88
- argv = parser.parse(ARGV)
89
-
90
- if argv.size != 2
91
- warn parser.help
92
- exit 1
93
- end
94
- if options[:service_cluster].empty? || options[:service_node].empty?
95
- warn '--service-cluster and --service-node are required'
96
- warn parser.help
97
- exit 1
98
- end
99
-
100
- convertor = StatConvertor.new(options)
101
-
102
- bind_option = argv.shift
103
- remote_option = argv.shift
104
-
105
- source_ip, source_port = *bind_option.split(':')
106
- unless source_ip && source_port
107
- warn "Invalid bind option given: #{bind_option}"
108
- exit 1
109
- end
110
-
111
- remote_ip, remote_port = *remote_option.split(':')
112
- unless remote_ip && remote_port
113
- warn "Invalid remote option given: #{remote_option}"
114
- exit 1
115
- end
116
-
117
- Thread.abort_on_exception = true
118
- logger.info("Starting relay: source=#{bind_option} remote=#{remote_option}")
119
- source = TCPServer.open(source_ip, source_port)
120
-
121
- loop do
122
- Thread.start(source.accept) do |s|
123
- while (body = s.gets)
124
- logger.debug("recieved #{body.bytesize} bytes")
125
- logger.debug(body)
126
- next if body.empty?
127
-
128
- b = convertor.call(body)
129
- UDPSocket.new.send(b, Socket::MSG_DONTWAIT, remote_ip, remote_port)
130
- logger.debug("write #{b.bytesize} bytes")
131
- logger.debug(b)
132
- end
133
- s.close
134
- end
135
- end