kumonos 0.10.2 → 0.11.0

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