kumonos 0.1.0 → 0.2.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
2
  SHA1:
3
- metadata.gz: b1c6b3644e754690e6ee2fba82f9a709442eabbb
4
- data.tar.gz: 8dcc5a060d2a29d248e409d8b248b8253611fcc3
3
+ metadata.gz: 981d08ab41459f0b6974d1e9db66bf36298319cd
4
+ data.tar.gz: a8f4fbb16ebb30de0b587a5820a37beb1d6e4da6
5
5
  SHA512:
6
- metadata.gz: '0408e86373950df921c58276ba93b76b3429f0ad9a3dbea2068a104b6cfde44fd59e903a0874c2f6edbdf9efe70e67449356b047a1e2e2b6aeb44b399440df8a'
7
- data.tar.gz: 3fc7fed7add9ff302c6e9ec7931055989d0265cda8af3180e0db955394b5cd683ef15181a9965dd9fb23c573cbeb16d24e2fe9e5543b344a60f549c59e3926da
6
+ metadata.gz: ecec920e45a4165cb2774c3e8b8b5d21990da3da8b0077ae8f18c0158800623faa95570d7f610dc54510444b192c8a93096516bf15ec58da482223a26b4c1496
7
+ data.tar.gz: 4ef6d9a17b3ee7fc7b1307cf0d5b11a2092b7ee75a4468629e6683e4f0ccec664bba8b6b8f3c8bc391a298f9ddbcf705ef1a758de37eb2e615927685dfae9d7f
data/.gitignore CHANGED
@@ -12,3 +12,4 @@
12
12
 
13
13
  Gemfile.lock
14
14
  test/config.json
15
+ test/srv
data/.rubocop.yml ADDED
@@ -0,0 +1,13 @@
1
+ AllCops:
2
+ DisplayCopNames: true
3
+
4
+ Metrics/BlockLength:
5
+ Enabled: false
6
+ Metrics/ClassLength:
7
+ Enabled: false
8
+ Metrics/MethodLength:
9
+ Enabled: false
10
+ Metrics/LineLength:
11
+ Enabled: false
12
+ Metrics/AbcSize:
13
+ Enabled: false
data/.travis.yml CHANGED
@@ -1,5 +1,7 @@
1
- sudo: false
2
1
  language: ruby
2
+ sudo: false
3
3
  rvm:
4
- - 2.3.5
5
- before_install: gem install bundler -v 1.16.0
4
+ - 2.4.1
5
+ before_install:
6
+ - gem update --system # https://github.com/rubygems/rubygems/pull/1819
7
+ - gem install bundler
data/Gemfile CHANGED
@@ -1,6 +1,6 @@
1
- source "https://rubygems.org"
1
+ source 'https://rubygems.org'
2
2
 
3
- git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
3
+ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
4
4
 
5
5
  # Specify your gem's dependencies in kumonos.gemspec
6
6
  gemspec
data/README.md CHANGED
@@ -1,39 +1,23 @@
1
1
  # Kumonos
2
+ [![Build Status](https://travis-ci.org/taiki45/kumonos.svg?branch=master)](https://travis-ci.org/taiki45/kumonos)
3
+ [![Gem Version](https://badge.fury.io/rb/kumonos.svg)](https://badge.fury.io/rb/kumonos)
2
4
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/kumonos`. To experiment with that code, run `bin/console` for an interactive prompt.
4
-
5
- TODO: Delete this and the text above, and describe your gem
5
+ Manage and build a Service Mesh for Microservices.
6
6
 
7
7
  ## Installation
8
8
 
9
- Add this line to your application's Gemfile:
10
-
11
- ```ruby
12
- gem 'kumonos'
13
- ```
14
-
15
- And then execute:
16
-
17
- $ bundle
18
-
19
- Or install it yourself as:
20
-
21
9
  $ gem install kumonos
22
10
 
23
11
  ## Usage
24
-
25
12
  TODO: Write usage instructions here
26
13
 
27
14
  ## Development
28
-
29
15
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30
16
 
31
17
  To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
32
18
 
33
19
  ## Contributing
34
-
35
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/kumonos.
20
+ Bug reports and pull requests are welcome on GitHub at https://github.com/taiki45/kumonos.
36
21
 
37
22
  ## License
38
-
39
23
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile CHANGED
@@ -1,6 +1,6 @@
1
- require "bundler/gem_tasks"
2
- require "rspec/core/rake_task"
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
3
 
4
4
  RSpec::Core::RakeTask.new(:spec)
5
5
 
6
- task :default => :spec
6
+ task default: :spec
data/bin/console CHANGED
@@ -1,14 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require "bundler/setup"
4
- require "kumonos"
3
+ require 'bundler/setup'
4
+ require 'kumonos'
5
5
 
6
- # You can add fixtures and/or initialization code here to make experimenting
7
- # with your gem easier. You can also use a different console, if you like.
8
-
9
- # (If you use this, don't forget to add pry to your Gemfile!)
10
- # require "pry"
11
- # Pry.start
12
-
13
- require "irb"
14
- IRB.start(__FILE__)
6
+ require 'pry'
7
+ Pry.start
data/bump.rb ADDED
@@ -0,0 +1,35 @@
1
+ level = ARGV.first
2
+ if level.nil?
3
+ warn "Example: ruby #{__FILE__} (tiny|minor|major)"
4
+ exit 1
5
+ end
6
+
7
+ path = 'lib/kumonos/version.rb'
8
+ regexp = /VERSION = '(.+)'.freeze$/
9
+ version = File.read(path).scan(regexp)[0][0]
10
+ version_strs = version.split('.')
11
+
12
+ if version_strs.size > 3
13
+ warn "Current version includes a prelease suffix, drop it: #{version}"
14
+ version_strs = version_strs[0..2]
15
+ end
16
+
17
+ case level
18
+ when 'tiny'
19
+ version_strs[2] = version_strs[2].to_i + 1
20
+ when 'minor'
21
+ version_strs[1] = version_strs[1].to_i + 1
22
+ version_strs[2] = 0
23
+ when 'major'
24
+ version_strs[0] = version_strs[0].to_i + 1
25
+ version_strs[1] = 0
26
+ version_strs[2] = 0
27
+ else
28
+ warn "Example: ruby #{__FILE__} (tiny|minor|major)"
29
+ exit 1
30
+ end
31
+
32
+ next_version = version_strs.join('.')
33
+ File.write(path, File.read(path).gsub(regexp, "VERSION = '#{next_version}'.freeze"))
34
+ system('git', 'add', path)
35
+ system('git', 'commit', '-m', "v#{next_version}")
data/example/book.yml CHANGED
@@ -1,4 +1,4 @@
1
- # A configuration for book service.
1
+ # A definition for book service.
2
2
  # The book service uses user service and ab-testing service.
3
3
  version: 1
4
4
  services:
@@ -19,6 +19,10 @@ services:
19
19
  - name: 'ab-testing'
20
20
  lb: 'ab-testing:8080'
21
21
  connect_timeout_ms: 250
22
+ circuit_breaker:
23
+ max_connections: 64
24
+ max_pending_requests: 128
25
+ max_retries: 3
22
26
  routes:
23
27
  - prefix: '/'
24
28
  timeout_ms: 3000
@@ -0,0 +1,37 @@
1
+ {
2
+ "version": 1,
3
+ "ds": {
4
+ "name": "nginx",
5
+ "refresh_delay_ms": 30000,
6
+ "cluster": {
7
+ "name": "nginx",
8
+ "type": "strict_dns",
9
+ "connect_timeout_ms": 250,
10
+ "lb_type": "round_robin",
11
+ "hosts": [
12
+ {
13
+ "url": "tcp://nginx:80"
14
+ }
15
+ ]
16
+ }
17
+ },
18
+ "statsd": {
19
+ "name": "statsd",
20
+ "connect_timeout_ms": 250,
21
+ "type": "strict_dns",
22
+ "lb_type": "round_robin",
23
+ "hosts": [
24
+ {
25
+ "url": "tcp://socat:2000"
26
+ }
27
+ ]
28
+ },
29
+ "listener": {
30
+ "address": "tcp://0.0.0.0:9211",
31
+ "access_log_path": "/dev/stdout"
32
+ },
33
+ "admin": {
34
+ "address": "tcp://0.0.0.0:9901",
35
+ "access_log_path": "/dev/stdout"
36
+ }
37
+ }
data/exe/kumonos CHANGED
@@ -1,9 +1,55 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- $:.unshift(File.expand_path('../lib', __dir__))
4
+ $LOAD_PATH.unshift(File.expand_path('../lib', __dir__))
5
5
  require 'kumonos'
6
6
 
7
- filename = ARGV[0]
8
- config = YAML.load_file(filename)
9
- puts JSON.dump(Kumonos.generate(config))
7
+ require 'pathname'
8
+ require 'thor'
9
+
10
+ # KumonosCli
11
+ class KumonosCli < Thor
12
+ desc 'envoy SERVIVE_NAME', 'Generate envoy configuration'
13
+ method_option :config, aliases: '-c', desc: 'Configuration file for kumonos'
14
+ def envoy(service_name)
15
+ h = JSON.parse(File.read(options[:config]))
16
+ result = Kumonos::Schemas.validate_kumonos_config(h)
17
+ unless result.empty?
18
+ warn("#{options[:config]} has invalid format:")
19
+ warn(result)
20
+ warn("A schema file for kumonos-configuration is #{Kumonos::Schemas::CONFIG_SCHEMA_PATH}")
21
+ exit 1
22
+ end
23
+
24
+ config = Kumonos::Configuration.from_hash(h)
25
+ puts JSON.dump(Kumonos.generate(config, service_name))
26
+ end
27
+
28
+ desc 'clusters FILEPATH OUT', 'Generate clusters configuration'
29
+ def clusters(filepath, output_dir)
30
+ name = File.basename(filepath, '.*')
31
+ definition = YAML.load_file(filepath)
32
+ out = JSON.dump(Kumonos.generate_clusters(definition))
33
+
34
+ output_dir = Pathname.new(output_dir)
35
+ target = output_dir.join('v1', 'clusters', name, name)
36
+ target.parent.mkpath unless target.parent.exist?
37
+ target.write(out)
38
+ puts target
39
+ end
40
+
41
+ desc 'routes FILEPATH OUT', 'Generate routes configuration'
42
+ def routes(filepath, output_dir)
43
+ name = File.basename(filepath, '.*')
44
+ definition = YAML.load_file(filepath)
45
+ out = JSON.dump(Kumonos.generate_routes(definition))
46
+
47
+ output_dir = Pathname.new(output_dir)
48
+ target = output_dir.join('v1', 'routes', name, name, name)
49
+ target.parent.mkpath unless target.parent.exist?
50
+ target.write(out)
51
+ puts target
52
+ end
53
+ end
54
+
55
+ KumonosCli.start(ARGV)
data/kumonos.gemspec CHANGED
@@ -8,7 +8,7 @@ Gem::Specification.new do |spec|
8
8
  spec.authors = ['Taiki Ono']
9
9
  spec.email = ['taiks.4559@gmail.com']
10
10
 
11
- spec.summary = %q{Manage configuration for Service Mesh.}
11
+ spec.summary = 'Manage configuration for Service Mesh.'
12
12
  spec.description = spec.summary
13
13
  spec.homepage = 'https://github.com/taiki45/kumonos'
14
14
  spec.license = 'MIT'
@@ -20,9 +20,11 @@ Gem::Specification.new do |spec|
20
20
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
21
21
  spec.require_paths = ['lib']
22
22
 
23
+ spec.add_dependency 'json-schema'
23
24
  spec.add_development_dependency 'bundler'
24
25
  spec.add_development_dependency 'pry'
25
26
  spec.add_development_dependency 'rake'
26
27
  spec.add_development_dependency 'rspec', '~> 3.0'
27
28
  spec.add_development_dependency 'rspec-json_matcher'
29
+ spec.add_development_dependency 'rubocop', '~> 0.51.0'
28
30
  end
@@ -0,0 +1,27 @@
1
+ module Kumonos
2
+ Configuration = Struct.new(:version, :ds, :statsd, :listener, :admin) do
3
+ class << self
4
+ def from_hash(h)
5
+ new(
6
+ h.fetch('version'),
7
+ symbolize_keys(h.fetch('ds')),
8
+ symbolize_keys(h.fetch('statsd')),
9
+ symbolize_keys(h.fetch('listener')),
10
+ symbolize_keys(h.fetch('admin'))
11
+ )
12
+ end
13
+
14
+ private
15
+
16
+ def symbolize_keys(hash)
17
+ new = hash.map do |k, v|
18
+ [
19
+ k.to_sym,
20
+ v.is_a?(Hash) ? symbolize_keys(v) : v
21
+ ]
22
+ end
23
+ new.to_h
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,23 @@
1
+ require 'pathname'
2
+ require 'json-schema'
3
+
4
+ module Kumonos
5
+ # Schemas
6
+ module Schemas
7
+ ROOT = Pathname.new(File.expand_path('../schemas', __dir__))
8
+ CONFIG_SCHEMA_PATH = ROOT.join('kumonos_config.json')
9
+
10
+ class << self
11
+ def validate_kumonos_config(hash)
12
+ schema = load_schema(CONFIG_SCHEMA_PATH)
13
+ JSON::Validator.fully_validate(schema, hash)
14
+ end
15
+
16
+ private
17
+
18
+ def load_schema(path)
19
+ JSON.parse(File.read(path))
20
+ end
21
+ end
22
+ end
23
+ end
@@ -1,3 +1,3 @@
1
1
  module Kumonos
2
- VERSION = "0.1.0"
2
+ VERSION = '0.2.0'.freeze
3
3
  end
data/lib/kumonos.rb CHANGED
@@ -1,41 +1,64 @@
1
1
  require 'json'
2
2
  require 'yaml'
3
+
3
4
  require 'kumonos/version'
5
+ require 'kumonos/schemas'
6
+ require 'kumonos/configuration'
4
7
 
8
+ # Kumonos
5
9
  module Kumonos
6
10
  class << self
7
- def generate(config)
8
- virtual_hosts = config['services'].map {|s| service_to_vhost(s) }
9
- clusters = config['services'].map {|s| service_to_cluster(s) }
11
+ def generate(config, name)
10
12
  {
11
13
  listeners: [
12
14
  {
13
- address: 'tcp://0.0.0.0:9211',
15
+ address: config.listener.fetch(:address),
14
16
  filters: [
15
17
  type: 'read',
16
18
  name: 'http_connection_manager',
17
19
  config: {
18
20
  codec_type: 'auto',
19
21
  stat_prefix: 'ingress_http',
20
- access_log: [{ path: '/dev/stdout' }],
21
- route_config: {
22
- virtual_hosts: virtual_hosts,
22
+ access_log: [{ path: config.listener.fetch(:access_log_path) }],
23
+ rds: {
24
+ cluster: config.ds.fetch(:name),
25
+ route_config_name: name,
26
+ refresh_delay_ms: config.ds.fetch(:refresh_delay_ms)
23
27
  },
24
- filters: [{ type: 'decoder', name: 'router', config: {} }],
28
+ filters: [{ type: 'decoder', name: 'router', config: {} }]
25
29
  }
26
- ],
30
+ ]
27
31
  }
28
32
  ],
29
33
  admin: {
30
- access_log_path: "/dev/stdout",
31
- address: "tcp://0.0.0.0:9901"
34
+ access_log_path: config.admin.fetch(:access_log_path),
35
+ address: config.admin.fetch(:address)
32
36
  },
37
+ statsd_tcp_cluster_name: config.statsd.fetch(:name),
33
38
  cluster_manager: {
34
- clusters: clusters,
39
+ clusters: [config.statsd],
40
+ cds: {
41
+ cluster: config.ds.fetch(:cluster),
42
+ refresh_delay_ms: config.ds.fetch(:refresh_delay_ms)
43
+ }
35
44
  }
36
45
  }
37
46
  end
38
47
 
48
+ def generate_routes(definition)
49
+ virtual_hosts = definition['services'].map { |s| service_to_vhost(s) }
50
+ {
51
+ validate_clusters: false,
52
+ virtual_hosts: virtual_hosts
53
+ }
54
+ end
55
+
56
+ def generate_clusters(definition)
57
+ {
58
+ clusters: definition['services'].map { |s| service_to_cluster(s) }
59
+ }
60
+ end
61
+
39
62
  private
40
63
 
41
64
  def service_to_vhost(service)
@@ -44,34 +67,35 @@ module Kumonos
44
67
  {
45
68
  name: name,
46
69
  domains: [name],
47
- routes: service['routes'].flat_map {|r| split_route(r, name) }
70
+ routes: service['routes'].flat_map { |r| split_route(r, name) }
48
71
  }
49
72
  end
50
73
 
51
- # Split route config to apply retry config only to GET/HEAD requests.
74
+ # Split route definition to apply retry definition only to GET/HEAD requests.
52
75
  def split_route(route, name)
53
76
  base = {
54
77
  prefix: route['prefix'],
55
78
  timeout_ms: route['timeout_ms'],
56
- cluster: name,
79
+ cluster: name
57
80
  }
58
81
  with_retry = base.merge(
59
82
  retry_policy: route['retry_policy'],
60
- headers: [{ name: ':method', value: '(GET|HEAD)', regex: true }],
83
+ headers: [{ name: ':method', value: '(GET|HEAD)', regex: true }]
61
84
  )
62
85
  [with_retry, base]
63
86
  end
64
87
 
65
88
  def service_to_cluster(service)
66
- out = {
89
+ {
67
90
  name: service['name'],
68
91
  connect_timeout_ms: service['connect_timeout_ms'],
69
- type: 'logical_dns',
92
+ type: 'strict_dns',
70
93
  lb_type: 'round_robin',
71
- hosts: [ { url: "tcp://#{service['lb']}" }],
94
+ hosts: [{ url: "tcp://#{service['lb']}" }],
95
+ circuit_breakers: {
96
+ default: service['circuit_breaker']
97
+ }
72
98
  }
73
- out.merge(circuit_breakers: [default: service['circuit_breaker']]) if service['circuit_breaker']
74
- out
75
99
  end
76
100
  end
77
101
  end
@@ -0,0 +1,174 @@
1
+ {
2
+ "definitions": {},
3
+ "$schema": "http://json-schema.org/draft-04/schema#",
4
+ "type": "object",
5
+ "id": "kumonos-configuration",
6
+ "additionalProperties": false,
7
+ "required": [
8
+ "version",
9
+ "ds",
10
+ "statsd",
11
+ "listener",
12
+ "admin"
13
+ ],
14
+ "properties": {
15
+ "version": {
16
+ "type": "integer",
17
+ "id": "/properties/version"
18
+ },
19
+ "ds": {
20
+ "type": "object",
21
+ "id": "/properties/ds",
22
+ "additionalProperties": false,
23
+ "required": [
24
+ "name",
25
+ "refresh_delay_ms",
26
+ "cluster"
27
+ ],
28
+ "properties": {
29
+ "name": {
30
+ "type": "string",
31
+ "id": "/properties/ds/properties/name"
32
+ },
33
+ "refresh_delay_ms": {
34
+ "type": "integer",
35
+ "id": "/properties/ds/properties/refresh_delay_ms"
36
+ },
37
+ "cluster": {
38
+ "type": "object",
39
+ "id": "/properties/ds/properties/cluster",
40
+ "additionalProperties": false,
41
+ "required": [
42
+ "name",
43
+ "type",
44
+ "connect_timeout_ms",
45
+ "lb_type",
46
+ "hosts"
47
+ ],
48
+ "properties": {
49
+ "name": {
50
+ "type": "string",
51
+ "id": "/properties/ds/properties/cluster/properties/name"
52
+ },
53
+ "type": {
54
+ "type": "string",
55
+ "id": "/properties/ds/properties/cluster/properties/type"
56
+ },
57
+ "connect_timeout_ms": {
58
+ "type": "integer",
59
+ "id": "/properties/ds/properties/cluster/properties/connect_timeout_ms"
60
+ },
61
+ "lb_type": {
62
+ "type": "string",
63
+ "id": "/properties/ds/properties/cluster/properties/lb_type"
64
+ },
65
+ "hosts": {
66
+ "type": "array",
67
+ "id": "/properties/ds/properties/cluster/properties/hosts",
68
+ "items": {
69
+ "type": "object",
70
+ "id": "/properties/ds/properties/cluster/properties/hosts/items",
71
+ "additionalProperties": false,
72
+ "required": [
73
+ "url"
74
+ ],
75
+ "properties": {
76
+ "url": {
77
+ "type": "string",
78
+ "id": "/properties/ds/properties/cluster/properties/hosts/items/properties/url"
79
+ }
80
+ }
81
+ }
82
+ }
83
+ }
84
+ }
85
+ }
86
+ },
87
+ "statsd": {
88
+ "type": "object",
89
+ "id": "/properties/statsd",
90
+ "additionalProperties": false,
91
+ "required": [
92
+ "name",
93
+ "connect_timeout_ms",
94
+ "type",
95
+ "lb_type",
96
+ "hosts"
97
+ ],
98
+ "properties": {
99
+ "name": {
100
+ "type": "string",
101
+ "id": "/properties/statsd/properties/name"
102
+ },
103
+ "connect_timeout_ms": {
104
+ "type": "integer",
105
+ "id": "/properties/statsd/properties/connect_timeout_ms"
106
+ },
107
+ "type": {
108
+ "type": "string",
109
+ "id": "/properties/statsd/properties/type"
110
+ },
111
+ "lb_type": {
112
+ "type": "string",
113
+ "id": "/properties/statsd/properties/lb_type"
114
+ },
115
+ "hosts": {
116
+ "type": "array",
117
+ "id": "/properties/statsd/properties/hosts",
118
+ "items": {
119
+ "type": "object",
120
+ "id": "/properties/statsd/properties/hosts/items",
121
+ "additionalProperties": false,
122
+ "required": [
123
+ "url"
124
+ ],
125
+ "properties": {
126
+ "url": {
127
+ "type": "string",
128
+ "id": "/properties/statsd/properties/hosts/items/properties/url"
129
+ }
130
+ }
131
+ }
132
+ }
133
+ }
134
+ },
135
+ "listener": {
136
+ "type": "object",
137
+ "id": "/properties/listener",
138
+ "additionalProperties": false,
139
+ "required": [
140
+ "address",
141
+ "access_log_path"
142
+ ],
143
+ "properties": {
144
+ "address": {
145
+ "type": "string",
146
+ "id": "/properties/listener/properties/address"
147
+ },
148
+ "access_log_path": {
149
+ "type": "string",
150
+ "id": "/properties/listener/properties/access_log_path"
151
+ }
152
+ }
153
+ },
154
+ "admin": {
155
+ "type": "object",
156
+ "id": "/properties/admin",
157
+ "additionalProperties": false,
158
+ "required": [
159
+ "address",
160
+ "access_log_path"
161
+ ],
162
+ "properties": {
163
+ "address": {
164
+ "type": "string",
165
+ "id": "/properties/admin/properties/address"
166
+ },
167
+ "access_log_path": {
168
+ "type": "string",
169
+ "id": "/properties/admin/properties/access_log_path"
170
+ }
171
+ }
172
+ }
173
+ }
174
+ }
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kumonos
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.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-11-05 00:00:00.000000000 Z
11
+ date: 2017-11-06 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: json-schema
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: bundler
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -80,6 +94,20 @@ dependencies:
80
94
  - - ">="
81
95
  - !ruby/object:Gem::Version
82
96
  version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rubocop
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 0.51.0
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 0.51.0
83
111
  description: Manage configuration for Service Mesh.
84
112
  email:
85
113
  - taiks.4559@gmail.com
@@ -90,6 +118,7 @@ extra_rdoc_files: []
90
118
  files:
91
119
  - ".gitignore"
92
120
  - ".rspec"
121
+ - ".rubocop.yml"
93
122
  - ".travis.yml"
94
123
  - Gemfile
95
124
  - LICENSE.txt
@@ -97,11 +126,16 @@ files:
97
126
  - Rakefile
98
127
  - bin/console
99
128
  - bin/setup
129
+ - bump.rb
100
130
  - example/book.yml
131
+ - example/kumonos.json
101
132
  - exe/kumonos
102
133
  - kumonos.gemspec
103
134
  - lib/kumonos.rb
135
+ - lib/kumonos/configuration.rb
136
+ - lib/kumonos/schemas.rb
104
137
  - lib/kumonos/version.rb
138
+ - lib/schemas/kumonos_config.json
105
139
  homepage: https://github.com/taiki45/kumonos
106
140
  licenses:
107
141
  - MIT