mkit 0.5.0 → 0.6.1

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
2
  SHA256:
3
- metadata.gz: fc469f170acb4204c99a3c5d5b42d474e68d3541dca30920068b5b7d1c56c526
4
- data.tar.gz: 97bd822d57128df2a7e3ae584af116aa09a250b41fed9f1dd362aa29bd3d49fb
3
+ metadata.gz: 0dab845891b079ffbf0f696676c1c3b6e25e583c02a09570582571976f8ce40d
4
+ data.tar.gz: 59e3174e0e09347c2e40a7f7096cfd3c9f9575a588d210c0d7dd71ccfcadf206
5
5
  SHA512:
6
- metadata.gz: d03fa8ceeb3668ef280fa558ce5e5002110f98cdc8bb30fef4ab299e55b532ed6faee2ddb1203925567bec8657daddcbe7eaa9cc63440350b11aca321b8c3fec
7
- data.tar.gz: 26087de2da9a6c65a3c42c92714a83419f91c7832549b04b39f5900d47d6a574e8cb180d42d62d09e5263b56eba3ea7858e2b8b0fcf6788609be30a7e8e62ddb
6
+ metadata.gz: a447023289277ea09120233ec72cb3b5a2de96077ee012b30fd369e21c338b487a898217d367dba7b8a86499a940944dee60ecdecbced737c00b70358e3141f4
7
+ data.tar.gz: b33b3276ad887b3939d2898b2d09c0a8a807a62856b761969f50e675c2e01fcd2f48abc1a49259dea60e4d12df563b0b73d4d4852880bb0e4abf2e539714074f
data/README.md CHANGED
@@ -2,7 +2,9 @@
2
2
 
3
3
  This is micro kubernetes(tm) on Ruby(tm), a simple tool to deploy containers to mimic a (very) minimalistic k8 cluster with a nice REST API.
4
4
 
5
- It contains an internal DNS and uses HAProxy for routing/balancing/fail-over for Pods access.
5
+ It's also a frontend for `docker`, providing an easier way for your services to be locally available, without the need to care about local `ports` availability.
6
+
7
+ It contains an internal DNS and uses HAProxy as ingress for Pod access.
6
8
  The database is a simple sqlite3 db and the server is a Sinatra based application.
7
9
 
8
10
  A client is also included to access the API, e.g. `mkitc ps`.
@@ -16,91 +18,24 @@ The daemon is responsible for HAProxy pods routing configuration. It also provid
16
18
  * Docker
17
19
  * Linux (iproute2 package)
18
20
 
21
+ **Note:** in order to have **ssl support**, you must install `openssl-dev` package (e.g. `libssl-dev` on Ubuntu) prior to install MKIt gem, due to `eventmachine` gem native extensions.
22
+
19
23
  ## Install
20
24
 
21
- This is a simple ruby gem, so to install run
25
+ This is a simple ruby gem, so to install execute:
22
26
  ```
23
27
  # gem install mkit
24
28
  ```
25
29
 
26
- ## Running
27
-
28
- The `daemon` requires `root` user (due to `ip` and `haproxy`), you can run it directly on the repository root...
29
-
30
- ```
31
- # ./mkitd --help
32
- Usage: mkitd [options]
33
- -c config-dir set the config dir (default is /etc/mkit)
34
- -p port set the port (default is 4567)
35
- -b bind specify bind address (e.g. /tmp/app.sock)
36
- -s server specify rack server/handler
37
- -q turn on quiet mode (default is off)
38
- -x turn on the mutex lock (default is off)
39
- -e env set the environment (default is development)
40
- -o addr set the host (default is (env == 'development' ? 'localhost' : '0.0.0.0'))
41
-
42
- ```
43
-
44
- or after the `gem install mkit-<version>.gem`. The server and client will be installed on host.
45
-
46
- ```
47
- # mkitd
48
- ...
49
- 0.65s info: MKIt is up and running! [ec=0xbe0] [pid=45804] [2023-12-29 15:46:04 +0000]
50
- ```
51
-
52
- There's also samples on the samples dir, for `daemontools` and `systemd`.
53
-
54
- ### Accessing the API
55
-
56
- A client is provided to interact with `mkit server`.
57
-
58
- Run `mkitc help` for a list of current supported commands.
59
-
60
- ```
61
- Usage: mkitc <command> [options]
62
-
63
- Micro k8s on Ruby - a simple tool to mimic a (very) minimalistic k8 cluster
64
-
65
- Commands:
66
-
67
- ps show services status (alias for status)
68
- status show services status
69
- logs prints service logs
70
- start start service
71
- stop stop service
72
- restart restart service
73
- create create new service
74
- update update service
75
- rm remove service
76
- version prints mkit server version
77
- proxy haproxy status and control
78
- profile mkit client configuration profile
79
-
80
- Run 'mkitc help <command>' for specific command information.
81
- ```
82
-
83
- Example:
84
-
85
- ```
86
- $ mkitc ps postgres
87
- +----+----------+---------------+----------+--------------+---------+
88
- | id | name | addr | ports | pods | status |
89
- +----+----------+---------------+----------+--------------+---------+
90
- | 2 | postgres | 10.210.198.10 | tcp/4532 | 49b5e4c8f247 | RUNNING |
91
- +----+----------+---------------+----------+--------------+---------+
92
- ```
93
- The service `postgres` is available on IP `10.210.198.10:5432`
94
-
95
30
  ## Configuration
96
31
 
97
32
  ### Server configuration
98
33
 
99
- On startup, configuration files on `config` directory will be copied to `/etc/mkit`.
34
+ On startup, [the server configuration](config) will be created on `/etc/mkit`.
100
35
 
101
- The server is available by default on `http://localhost:4567` but you can configure server startup parameters on `/etc/mkit/mkitd_config.sh`
36
+ The server will available by default on `https://localhost:4567` but you can configure server startup parameters on `/etc/mkit/mkitd_config.sh`
102
37
 
103
- Please check `samples/systemd` or `samples/daemontools` directories for more details.
38
+ Please check [systemd](samples/systemd) or [daemontools](samples/daemontools) directories for more details.
104
39
 
105
40
  ```
106
41
  # /etc/mkit/mkitd_config.sh
@@ -110,7 +45,7 @@ Please check `samples/systemd` or `samples/daemontools` directories for more det
110
45
  OPTIONS=""
111
46
  # e.g. OPTIONS="-b 0.0.0.0"
112
47
  ```
113
- HAProxy config directory and control commands are defined on `mkit_config.yml`
48
+ HAProxy config directory and control commands are defined on [mkit_config.yml](config/mkit_config.yml)
114
49
 
115
50
  ```
116
51
  # /etc/mkit/mkit_config.yml - mkit server configuration file.
@@ -127,9 +62,13 @@ mkit:
127
62
  status: systemctl status haproxy
128
63
  database:
129
64
  env: development
65
+ clients:
66
+ - id: client_1_id
67
+ - id: client_2_id
68
+ - ...
130
69
  ```
131
70
 
132
- You must configure `haproxy` to use config directory. e.g. on Ubuntu
71
+ You must configure `haproxy` to use config directory. for example on Ubuntu:
133
72
 
134
73
  ```
135
74
  # /etc/default/haproxy
@@ -145,19 +84,40 @@ CONFIG="/etc/haproxy/haproxy.d"
145
84
  # Add extra flags here, see haproxy(1) for a few options
146
85
  #EXTRAOPTS="-de -m 16"
147
86
  ```
87
+
88
+ #### Authorization
89
+
90
+ To access MKIt server API, you must add each client `id` to server configuration:
91
+
92
+ ```
93
+ # /etc/mkit/mkit_config.yml - mkit server configuration file.
94
+ mkit:
95
+ my_network:
96
+ ...
97
+ clients:
98
+ - id: client_1_id
99
+ - id: client_2_id
100
+ - ...
101
+ ```
102
+
148
103
  ### Client configuration
149
104
 
150
105
  On `mkitc` first call, default configuration will be copied to `$HOME/.mkit` with `local`default profile set.
151
106
 
152
- You can add more servers and change active profile with `$mkitc profile set <profile_name>`, e.g. `$mkitc profile set server_2`
107
+ You must call `mkitc init` to initialize client configuration.
108
+
109
+ Client identification key (`my_id`) will be generated, printed out to console and saved to the client's configuration file.
110
+
111
+ You may edit the local configuration file to add more servers and change active profile with `$mkitc profile set <profile_name>`, e.g. `$mkitc profile set server_2`
153
112
 
154
113
  ```
155
114
  # ~/.mkit/mkitc_config.yml
156
115
  mkit:
157
116
  local:
158
- server.uri: http://localhost:4567
117
+ server.uri: https://localhost:4567
159
118
  server_2: # you can add more servers. change the client active profile with mkitc profile command
160
- server.uri: http://192.168.29.232:4567
119
+ server.uri: https://192.168.29.232:4567
120
+ my_id: unique_id # this id is generated running mkitc init
161
121
  ```
162
122
 
163
123
  ### Service
@@ -171,7 +131,12 @@ service:
171
131
  # <external_port>:[internal_port]:<tcp|http>:[round_robin (default)|leastconn]
172
132
  # to define a range on `external_port`, leave `internal_port` blank
173
133
  # - 5000-5100::tcp:round_robin
174
- # range on `internal_port` is not supported
134
+ # range on `internal_port` is not supported
135
+ # ssl suport
136
+ # <external_port>:[internal_port]:<tcp|http>:round_robin|leastconn[:ssl[,<cert.pem>(mkit.pem default)>]]
137
+ # e.g.
138
+ # - 443:80:http:round_robin:ssl # uses mkitd default crt file (mkit.pem)
139
+ # - 443:80:http:round_robin:ssl,/etc/pki/foo.pem # custom crt file full path
175
140
  - 5672:5672:tcp:round_robin
176
141
  - 80:15672:http:round_robin
177
142
  resources:
@@ -186,6 +151,72 @@ service:
186
151
  RABBITMQ_DEFAULT_VHOST: mkit
187
152
  ```
188
153
 
154
+ ## Running
155
+
156
+ The `mkitd server daemon` requires `root` user (due to `ip` and `haproxy`).
157
+ After installing the gem, server and client will be available on host.
158
+ ```
159
+ # mkitd --help
160
+ Usage: mkitd [options]
161
+ -c config-dir set the config dir (default is /etc/mkit)
162
+ -p port set the port (default is 4567)
163
+ -b bind specify bind address (e.g. 0.0.0.0)
164
+ -e env set the environment (default is development)
165
+ -o addr alias for '-b' option
166
+ --no-ssl disable ssl - use http for local server. (default is https)
167
+ --ssl-key-file PATH Path to private key (default mkit internal)
168
+ --ssl-cert-file PATH Path to certificate (default mkit internal)
169
+ ```
170
+
171
+ There's also samples for [systemd](samples/systemd) and [daemontools](samples/daemontools) as well for some miscellaneous [spps](samples/apps).
172
+
173
+ ### Accessing the API
174
+
175
+ A client is provided to interact with MKIt server.
176
+
177
+ Run `mkitc help` for a list of current supported commands.
178
+
179
+ ```
180
+ Usage: mkitc <command> [options]
181
+
182
+ Micro k8s on Ruby - a simple tool to mimic a (very) minimalistic k8 cluster
183
+
184
+ Commands:
185
+
186
+ init init mkit client
187
+ ps show services status (alias for status)
188
+ status show services status
189
+ logs prints service logs
190
+ start start service
191
+ stop stop service
192
+ restart restart service
193
+ create create new service
194
+ update update service
195
+ rm remove service
196
+ version prints mkit server version
197
+ proxy haproxy status and control
198
+ profile mkit client configuration profile
199
+
200
+ Run 'mkitc help <command>' for specific command information.
201
+ ```
202
+
203
+ Example:
204
+
205
+ ```
206
+ $ mkitc ps
207
+ +----+-------+---------------+-------------------+--------------+---------+
208
+ | id | name | addr | ports | pods | status |
209
+ +----+-------+---------------+-------------------+--------------+---------+
210
+ | 1 | mongo | 10.210.198.10 | tcp/27017 | 106e2b59cb11 | RUNNING |
211
+ | 2 | nexus | 10.210.198.11 | http/80,https/443 | 68e239e5102a | RUNNING |
212
+ +----+-------+---------------+-------------------+--------------+---------+
213
+ ```
214
+ The service `mongo` is available on IP `10.210.198.10:27017`
215
+ The service `nexus` is available on IP `10.210.198.11:80` and on port `443` with ssl.
216
+
217
+ **Note:** Don't forget to call `mkitc init` to initialize client configuration and to add the `client-id`
218
+ to the server authorized clients list.
219
+
189
220
  ## Development
190
221
 
191
222
  * build the gem
data/bin/mkitc CHANGED
@@ -27,6 +27,11 @@ class CommandPalette
27
27
  { short: '-v', long: '--verbose', help: 'verbose', mandatory: false, value: nil }
28
28
  ]
29
29
  [
30
+ {
31
+ cmd: 'init',
32
+ help: 'init mkit client',
33
+ request: { }
34
+ },
30
35
  {
31
36
  cmd: 'ps',
32
37
  args: [
@@ -170,6 +175,7 @@ class MKItClient
170
175
  @config_dir = "#{ENV['HOME']}/.mkit"
171
176
  @profile_file = "#{@config_dir}/current"
172
177
  @commands = CommandPalette.new
178
+ @config_file = "#{@config_dir}/mkitc_config.yml"
173
179
  create_default_config
174
180
  end
175
181
 
@@ -178,28 +184,34 @@ class MKItClient
178
184
  puts "Creating config directory on '#{@config_dir}'..."
179
185
  FileUtils.mkdir_p(@config_dir)
180
186
  end
181
- FileUtils.cp("#{@root}/config/mkitc_config.yml", @config_dir) unless File.exist?("#{@config_dir}/mkitc_config.yml")
187
+ FileUtils.cp("#{@root}/config/mkitc_config.yml", @config_dir) unless File.exist?(@config_file)
182
188
  profile({ verb: 'set' }, { profile_name: 'local' }) unless File.exist?(@profile_file)
183
189
  end
184
190
 
185
- def read_configuration
191
+ def read_configuration(init_call = false)
186
192
  current_profile = File.read(@profile_file)
187
193
  if current_profile.nil? || current_profile.empty?
188
194
  # force set default
189
195
  profile({ verb: 'set' }, { profile_name: 'local' })
190
196
  current_profile = 'local'
191
197
  end
192
- cfg = YAML.load_file("#{@config_dir}/mkitc_config.yml")
198
+ cfg = YAML.load_file(@config_file)
193
199
 
194
200
  if cfg['mkit'].nil? || cfg['mkit'][current_profile.lstrip].nil?
195
201
  raise InvalidParametersException, "invalid configuration found on '~/.mkit' or profile not found"
196
202
  end
197
203
 
198
204
  @configuration = cfg['mkit'][current_profile.lstrip]
205
+ if !init_call && cfg['my_id'].nil?
206
+ raise InvalidParametersException.new("Please run 'mkitc init' to initialize mkit client.", find_command('init'))
207
+ end
208
+ @my_id = cfg['my_id']
209
+ cfg
199
210
  end
200
211
 
201
- def client
212
+ def client(req)
202
213
  read_configuration
214
+ req['X-API-KEY'] = @my_id
203
215
  uri = URI(@configuration['server.uri'])
204
216
  case uri.scheme
205
217
  when 'https'
@@ -213,7 +225,7 @@ class MKItClient
213
225
  else
214
226
  raise InvalidParametersException, 'Invalid mkit server uri. Please check configuration'
215
227
  end
216
- @client
228
+ @client.request(req)
217
229
  end
218
230
 
219
231
  def dict
@@ -317,7 +329,7 @@ class MKItClient
317
329
  when :delete
318
330
  req = Net::HTTP::Delete.new(uri)
319
331
  end
320
- client.request(req).body
332
+ client(req).body
321
333
  end
322
334
 
323
335
  def attach(file)
@@ -371,6 +383,18 @@ class MKItClient
371
383
  exit 1
372
384
  end
373
385
 
386
+ def init(request, request_hash = nil)
387
+ cfg = read_configuration(true)
388
+ if cfg['my_id'].nil?
389
+ my_id = SecureRandom.uuid.gsub('-','')
390
+ cfg['my_id'] = my_id
391
+ File.write(@config_file, cfg.to_yaml)
392
+ puts "Please check if your api-key is on mkitd server allowed keys"
393
+ else
394
+ my_id = cfg['my_id']
395
+ end
396
+ puts "Your api-key is #{my_id}"
397
+ end
374
398
  def create(request, request_hash = nil)
375
399
  unless File.file?(request_hash[:file])
376
400
  raise InvalidParametersException.new('File not found.', find_command('create'))
data/bin/mkitd CHANGED
@@ -9,9 +9,7 @@ def up
9
9
  require 'sinatra'
10
10
  require 'sinatra/base'
11
11
  require 'mkit'
12
- # defaults
13
- PARAMS_CONFIG[:bind] ||= 'localhost'
14
- PARAMS_CONFIG[:port] ||= 4567
12
+
15
13
  MKIt.startup(options: PARAMS_CONFIG)
16
14
 
17
15
  use Rack::MethodOverride
@@ -21,26 +19,27 @@ def up
21
19
 
22
20
  # sinatra::base ignores in parameters
23
21
  # set it here or via configure...
24
- Sinatra::Application.run!({ port: PARAMS_CONFIG[:port], bind: PARAMS_CONFIG[:bind] })
25
- # MKIt::Server.run
22
+ # Sinatra::Application.run!({ port: PARAMS_CONFIG[:port], bind: PARAMS_CONFIG[:bind] })
23
+ Sinatra::Application.run! do |server|
24
+ MKIt.options(server)
25
+ end
26
+
26
27
  end
27
28
 
28
29
  if ARGV.any?
29
30
  require 'optparse'
30
31
  parser = OptionParser.new do |op|
31
32
  op.on('-c config-dir', 'set the config dir (default is /etc/mkit)') { |val| PARAMS_CONFIG[:config_dir] = val }
32
- op.on('-p port', 'set the port (default is 4567)') { |val| PARAMS_CONFIG[:port] = Integer(val) }
33
- op.on('-b bind ', 'specify bind address (e.g. /tmp/app.sock)') { |val| PARAMS_CONFIG[:bind] = val }
34
- op.on('-s server', 'specify rack server/handler') { |val| PARAMS_CONFIG[:server] = val }
35
- op.on('-q', 'turn on quiet mode (default is off)') { PARAMS_CONFIG[:quiet] = true }
36
- op.on('-x', 'turn on the mutex lock (default is off)') { PARAMS_CONFIG[:lock] = true }
37
- op.on('-e env', 'set the environment (default is development)') do |val|
33
+ op.on('-p port', 'set the port (default is 4567)') { |val| PARAMS_CONFIG[:port] = Integer(val) }
34
+ op.on('-b bind', 'specify bind address (e.g. 0.0.0.0)') { |val| PARAMS_CONFIG[:bind] = val }
35
+ op.on('-o addr', 'alias for bind option') { |val| PARAMS_CONFIG[:bind] = val }
36
+ op.on('-e env', 'set the environment (default is development)') do |val|
38
37
  ENV['RACK_ENV'] = val
39
38
  PARAMS_CONFIG[:environment] = val.to_sym
40
39
  end
41
- op.on('-o addr', "set the host (default is (env == 'development' ? 'localhost' : '0.0.0.0'))") do |val|
42
- PARAMS_CONFIG[:bind] = val
43
- end
40
+ op.on('--no-ssl', 'disable ssl - use http for local server. (default is https)') { PARAMS_CONFIG[:ssl] = false }
41
+ op.on('--ssl-key-file PATH', 'Path to private key (default mkit internal)') { |val| PARAMS_CONFIG[:private_key_file] = val }
42
+ op.on('--ssl-cert-file PATH', 'Path to certificate (default mkit internal)') { |val| PARAMS_CONFIG[:cert_chain_file] = val }
44
43
  end
45
44
  begin
46
45
  parser.parse!(ARGV.dup)
@@ -1,3 +1,4 @@
1
+ ---
1
2
  mkit:
2
3
  my_network:
3
4
  ip: 10.210.198.1
@@ -12,4 +13,5 @@ mkit:
12
13
  bin: /usr/sbin/haproxy
13
14
  database:
14
15
  env: development
15
-
16
+ clients:
17
+ - add_client_id: add client's id to allow access to this server
@@ -1,3 +1,3 @@
1
1
  mkit:
2
2
  local:
3
- server.uri: http://localhost:4567
3
+ server.uri: https://localhost:4567
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ServicePortsSsl< ActiveRecord::Migration[5.1]
4
+ def up
5
+ add_column :service_ports, :ssl, :string
6
+ add_column :service_ports, :crt, :string
7
+ end
8
+ end
@@ -24,9 +24,28 @@ module MKIt
24
24
  end
25
25
 
26
26
  def build_table_row(data)
27
- ports = data.service_port&.each.map { |p| "#{p.mode}/#{p.external_port}" }.join(',')
27
+ ports = data.service_port&.each.map { |p| build_port(p) }.join(',')
28
28
  pods = data.pod.each.map { |p| p.name.to_s }.join(' ')
29
29
  [data.id, data.name, data.lease&.ip, ports, pods, data.status]
30
30
  end
31
+
32
+ def build_port(p)
33
+ case p.mode
34
+ when 'http'
35
+ if p.ssl?
36
+ "#{p.mode}s/#{p.external_port}"
37
+ else
38
+ "#{p.mode}/#{p.external_port}"
39
+ end
40
+ when 'tcp'
41
+ if p.ssl?
42
+ "s#{p.mode}/#{p.external_port}"
43
+ else
44
+ "#{p.mode}/#{p.external_port}"
45
+ end
46
+ else
47
+ "#{p.mode}/#{p.external_port}"
48
+ end
49
+ end
31
50
  end
32
51
  end
@@ -9,6 +9,14 @@ module MKIt
9
9
  set :show_exceptions, false
10
10
  set :raise_errors, false
11
11
 
12
+ before do
13
+ api_key = request.env['HTTP_X_API_KEY']
14
+ cfg = YAML.load_file(MKIt::Config.config_file)
15
+ if cfg.nil? || cfg['mkit'].nil? || cfg['mkit']['clients'].nil? || !cfg['mkit']['clients'].map{|h| h['id']}.include?(api_key)
16
+ error 401, 'Unauthorized - please add your client-id to authorized clients list'
17
+ end
18
+ end
19
+
12
20
  error MKIt::BaseException do |e|
13
21
  MKItLogger.debug e
14
22
  error e.error_code, e.message
@@ -4,7 +4,7 @@ require 'mkit/exceptions'
4
4
  class ServicePort < ActiveRecord::Base
5
5
  belongs_to :service
6
6
 
7
- CONFIG_EXPRESSION=/^(.*?):(.*?):(tcp|http):(.*?)$/
7
+ CONFIG_EXPRESSION=/^(.*?):(.*?):(tcp|http):(.*?)($|:ssl$|:ssl,(.+))$/
8
8
 
9
9
  def self.create(service:, config:)
10
10
  sp = ServicePort.new(service: service, version: service.version)
@@ -18,22 +18,34 @@ class ServicePort < ActiveRecord::Base
18
18
  # # src:dest:tcp|http:round_robin|leastconn
19
19
  # - 5532:5432:tcp:round_robin
20
20
  # - 5532-6000::tcp:round_robin
21
+ # # ssl support:
22
+ # # src:dest:tcp|http:round_robin|leastconn[:ssl[,<cert.pem>(mkit.pem default)>]]
23
+ # - 443:80:tcp:round_robin:ssl # crt file is mkit.pem
24
+ # - 443:80:tcp:round_robin:ssl,/etc/pki/foo.pem # crt file full path
21
25
  # model:
22
26
  # service_ports:
23
27
  # - external: 5432
24
28
  # internal: 5432
25
29
  # mode: tcp|http
26
30
  # load_bal: round_robin
31
+ # ssl: true|false
32
+ # crt: full path
27
33
  def parse_config(config)
28
34
  ports = config.match(CONFIG_EXPRESSION)
29
35
  raise MKIt::InvalidPortsConfiguration.new("no match with config expression $#{CONFIG_EXPRESSION}") if ports.nil?
30
36
 
37
+ puts ports
31
38
  self.external_port = ports[1]
32
39
  self.internal_port = ports[2]
33
40
  self.mode = ports[3]
34
41
  self.load_bal = ports[4]
42
+ self.ssl = !ports[5].nil? && ports[5].start_with?(':ssl') ? 'true':'false'
43
+ self.crt = ports[7].nil? ? MKIt::Utils.proxy_cert : ports[7]
35
44
  end
36
45
 
46
+ def ssl?
47
+ self.ssl == 'true'
48
+ end
37
49
  def load_balance
38
50
  case self.load_bal
39
51
  when /^round_robin$/
@@ -6,7 +6,7 @@
6
6
  # start <%=name%>-<%=port.external_port%>
7
7
  #
8
8
  frontend <%=name%>-<%=port.external_port%>-front
9
- bind <%=lease.ip%>:<%=port.external_port%>
9
+ bind <%=lease.ip%>:<%=port.external_port%> <%=if port.ssl? then "ssl crt #{port.crt}" end%>
10
10
  mode <%=port.mode%>
11
11
  #
12
12
  use_backend <%=name%>-<%=port.external_port%>-back
@@ -6,13 +6,18 @@ require 'yaml'
6
6
  module MKIt
7
7
  module Config
8
8
  extend self
9
+
9
10
  def load_yml!(path)
11
+ @config_file = path
10
12
  @config = YAML.load(File.new(path).read).to_o
11
13
  end
14
+
15
+ def config_file
16
+ @config_file
17
+ end
12
18
  #
13
19
  def method_missing(name,*args)
14
20
  return @config.send(name,*args)
15
- super.method_missing name
16
21
  end
17
22
  end
18
23
  end
@@ -0,0 +1,28 @@
1
+ require 'openssl'
2
+
3
+ module MKIt
4
+ class EasySSL
5
+ def self.create_self_certificate(cert_dir)
6
+ unless File.exist?("#{cert_dir}/#{MKIt::Utils::MKIT_CRT}")
7
+ key = OpenSSL::PKey::RSA.new 4096
8
+ name = OpenSSL::X509::Name.parse '/CN=MKIt/DC=server'
9
+ cert = OpenSSL::X509::Certificate.new
10
+ cert.version = 2
11
+ cert.serial = 0
12
+ cert.not_before = Time.now
13
+ cert.not_after = Time.now + 20 * 365 * 24 * 60 * 60
14
+ cert.public_key = key.public_key
15
+ cert.subject = name
16
+ cert.issuer = name
17
+ cert.sign key, OpenSSL::Digest.new('SHA256')
18
+ # my cert and key files
19
+ open "#{cert_dir}/#{MKIt::Utils::MKIT_CRT}", 'w' do |io| io.write cert.to_pem end
20
+ open "#{cert_dir}/#{MKIt::Utils::MKIT_KEY}", 'w' do |io| io.write key.to_pem end
21
+ # haproxy default ssl cert
22
+ open "#{cert_dir}/#{MKIt::Utils::MKIT_PEM}", 'w' do |io| io.write cert.to_pem end
23
+ open "#{cert_dir}/#{MKIt::Utils::MKIT_PEM}", 'a' do |io| io.write key.to_pem end
24
+ end
25
+ end
26
+ end
27
+ end
28
+
data/lib/mkit/utils.rb CHANGED
@@ -4,6 +4,10 @@ module MKIt
4
4
  module Utils
5
5
  module_function
6
6
 
7
+ MKIT_CRT = 'mkit.crt'
8
+ MKIT_KEY = 'mkit.key'
9
+ MKIT_PEM = 'mkit.pem'
10
+
7
11
  def me
8
12
  'mkit'
9
13
  end
@@ -24,6 +28,10 @@ module MKIt
24
28
  @config_dir.nil? ? "#{self.root}/config" : @config_dir
25
29
  end
26
30
 
31
+ def proxy_cert
32
+ "#{config_dir}/#{MKIT_PEM}"
33
+ end
34
+
27
35
  def load_db_config(db_config_dir = self.config_dir)
28
36
  self.log.info "loading database configurations from '#{config_dir}'..."
29
37
  YAML::load(ERB.new(IO.read("#{db_config_dir}/database.yml")).result)
data/lib/mkit/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  module MKIt
2
- VERSION = "0.5.0"
2
+ VERSION = "0.6.1"
3
3
  end
4
4
 
data/lib/mkit.rb CHANGED
@@ -29,6 +29,7 @@ require 'mkit/docker_listener'
29
29
  require 'mkit/app/helpers/haproxy'
30
30
  require 'active_record/tasks/database_tasks'
31
31
  require 'mkit/utils'
32
+ require 'mkit/ssl/easy_ssl'
32
33
 
33
34
  MKItLogger = Console.logger
34
35
 
@@ -40,15 +41,24 @@ module MKIt
40
41
 
41
42
  def self.configure(options:)
42
43
  @root = MKIt::Utils.root
44
+ @options = options
43
45
  MKItLogger.debug!
44
46
  #
45
47
  # config dir
46
48
  @config_dir = if ENV['RACK_ENV'] != 'development'
47
- options[:config_dir].nil? ? '/etc/mkit' : options[:config_dir]
49
+ @options[:config_dir].nil? ? '/etc/mkit' : @options[:config_dir]
48
50
  else
49
- options[:config_dir].nil? ? "#{@root}/config" : options[:config_dir]
51
+ @options[:config_dir].nil? ? "#{@root}/config" : @options[:config_dir]
50
52
  end
51
53
  MKIt::Utils.set_config_dir(@config_dir)
54
+ # defaults
55
+ @bind = options[:bind] ||= 'localhost'
56
+ @port = options[:port] ||= 4567
57
+ @ssl = options[:ssl].nil? ? true : options[:ssl] && true
58
+ @verify_peer = options[:verify_peer].nil? ? false : options[:verify_peer] && true
59
+ @cert_chain_file = options[:cert_chain_file] ||= "#{@config_dir}/#{MKIt::Utils::MKIT_CRT}"
60
+ @private_key_file = options[:private_key_file] ||= "#{@config_dir}/#{MKIt::Utils::MKIT_KEY}"
61
+
52
62
  # create dirs
53
63
  if ENV['RACK_ENV'] != 'development' || !options[:config_dir].nil?
54
64
  check_config_files = false
@@ -65,9 +75,11 @@ module MKIt
65
75
  exit
66
76
  end
67
77
  end
68
- #
78
+
69
79
  # load configuration
70
80
  MKIt::Initializers.load_my_configuration
81
+ # cert
82
+ MKIt::EasySSL.create_self_certificate(@config_dir)
71
83
  #
72
84
  # run config based tasks
73
85
  FileUtils.mkdir_p(MKIt::Config.mkit.haproxy.config_dir)
@@ -92,6 +104,20 @@ module MKIt
92
104
  DatabaseTasks.root = @root
93
105
  end
94
106
 
107
+ def self.options(server)
108
+ if @ssl
109
+ ssl_options = {
110
+ private_key_file: @private_key_file,
111
+ cert_chain_file: @cert_chain_file,
112
+ verify_peer: @verify_peer
113
+ }
114
+ server.ssl = true
115
+ server.ssl_options = ssl_options
116
+ end
117
+ server.backend.port = @port
118
+ server.backend.host = @bind
119
+ end
120
+
95
121
  def self.establish_db_connection
96
122
  ActiveRecord::Base.establish_connection(DatabaseTasks.database_configuration[DatabaseTasks.env])
97
123
  ActiveRecord::Base.connection.migration_context.migrations_paths.clear
data/mkit.gemspec CHANGED
@@ -35,4 +35,5 @@ Gem::Specification.new do |s|
35
35
  s.add_runtime_dependency 'sqlite3', '~> 1.5', '>= 1.5.4'
36
36
  s.add_runtime_dependency 'standalone_migrations', '~> 7.1', '>= 7.1.0'
37
37
  s.add_runtime_dependency 'thin', '~> 1.8', '>= 1.8.1'
38
+ s.add_runtime_dependency 'text-table', '~> 1.2', '>= 1.2.4'
38
39
  end
@@ -5,6 +5,7 @@ service:
5
5
  network: bridge
6
6
  ports:
7
7
  - 80:8081:http:round_robin
8
+ - 443:8081:http:round_robin:ssl
8
9
  resources:
9
10
  max_replicas: 1
10
11
  min_replicas: 1
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mkit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vasco Santos
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-02-17 00:00:00.000000000 Z
11
+ date: 2024-02-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: async-dns
@@ -290,6 +290,26 @@ dependencies:
290
290
  - - ">="
291
291
  - !ruby/object:Gem::Version
292
292
  version: 1.8.1
293
+ - !ruby/object:Gem::Dependency
294
+ name: text-table
295
+ requirement: !ruby/object:Gem::Requirement
296
+ requirements:
297
+ - - "~>"
298
+ - !ruby/object:Gem::Version
299
+ version: '1.2'
300
+ - - ">="
301
+ - !ruby/object:Gem::Version
302
+ version: 1.2.4
303
+ type: :runtime
304
+ prerelease: false
305
+ version_requirements: !ruby/object:Gem::Requirement
306
+ requirements:
307
+ - - "~>"
308
+ - !ruby/object:Gem::Version
309
+ version: '1.2'
310
+ - - ">="
311
+ - !ruby/object:Gem::Version
312
+ version: 1.2.4
293
313
  description: Micro k8s on Ruby - a simple tool to deploy containers to mimic a (very)
294
314
  minimalistic k8 cluster with a nice REST API
295
315
  email:
@@ -315,6 +335,7 @@ files:
315
335
  - config/mkitd_config.sh
316
336
  - db/migrate/001_setup.rb
317
337
  - db/migrate/002_mkit_jobs.rb
338
+ - db/migrate/003_service_ports_ssl.rb
318
339
  - db/schema.rb
319
340
  - lib/mkit.rb
320
341
  - lib/mkit/app/controllers/mkit_controller.rb
@@ -350,13 +371,13 @@ files:
350
371
  - lib/mkit/ctypes.rb
351
372
  - lib/mkit/docker_listener.rb
352
373
  - lib/mkit/exceptions.rb
353
- - lib/mkit/haproxy.rb
354
374
  - lib/mkit/job_manager.rb
355
375
  - lib/mkit/mkit_dns.rb
356
376
  - lib/mkit/mkit_interface.rb
357
377
  - lib/mkit/sagas/asaga.rb
358
378
  - lib/mkit/sagas/create_pod_saga.rb
359
379
  - lib/mkit/sagas/saga_manager.rb
380
+ - lib/mkit/ssl/easy_ssl.rb
360
381
  - lib/mkit/status.rb
361
382
  - lib/mkit/utils.rb
362
383
  - lib/mkit/version.rb
data/lib/mkit/haproxy.rb DELETED
@@ -1,48 +0,0 @@
1
- require 'pty'
2
- #
3
- #
4
- #
5
- module MKIt
6
- class HAProxy
7
-
8
- def initialize
9
- # configs
10
- # run standalone | daemon
11
- @running = false
12
- end
13
-
14
- def start
15
- @thread ||= Thread.new {
16
- while (@running) do
17
- cmd = "/usr/sbin/haproxy -f /etc/haproxy/haproxy.d"
18
- %x{#{cmd}}
19
- sleep 1
20
- end
21
- }
22
- @thread.run
23
- puts "haproxy started"
24
- end
25
-
26
- def start
27
- @running = true
28
- @thread ||= Thread.new {
29
- while (@running) do
30
- %{/usr/sbin/haproxy -f /etc/haproxy/haproxy.d/}
31
- sleep(1)
32
- end
33
- }
34
- puts "proxy started"
35
- end
36
-
37
- def stop
38
- puts "proxy stopped"
39
- end
40
-
41
- def status
42
- end
43
-
44
- def reload
45
- end
46
- end
47
- end
48
-