mkit 0.5.0 → 0.6.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
  SHA256:
3
- metadata.gz: fc469f170acb4204c99a3c5d5b42d474e68d3541dca30920068b5b7d1c56c526
4
- data.tar.gz: 97bd822d57128df2a7e3ae584af116aa09a250b41fed9f1dd362aa29bd3d49fb
3
+ metadata.gz: ca554f25f295a7403d5f0d654663d466430a361c8aa2629961f1710579e62506
4
+ data.tar.gz: d670fcc4523810439d73244276766a8e5ff70f2b8a052b292941014a11e7ca3b
5
5
  SHA512:
6
- metadata.gz: d03fa8ceeb3668ef280fa558ce5e5002110f98cdc8bb30fef4ab299e55b532ed6faee2ddb1203925567bec8657daddcbe7eaa9cc63440350b11aca321b8c3fec
7
- data.tar.gz: 26087de2da9a6c65a3c42c92714a83419f91c7832549b04b39f5900d47d6a574e8cb180d42d62d09e5263b56eba3ea7858e2b8b0fcf6788609be30a7e8e62ddb
6
+ metadata.gz: 825f5736fe72ce3bec3aab11f5edfa75b286a6e08ff4e6dc44be37c6d11a034e84a0910fca6ce78cb05ead4483ec228c368a749a301793396ddfc55043fc5bf9
7
+ data.tar.gz: 5b0c25f145e1c5ec19d8242d8e613c6746fc3ea25f4f1df0f39dc434ee43e56d480b399075230154d547abad466555f884077f1a1fff08590005645a762b3279
data/README.md CHANGED
@@ -2,6 +2,8 @@
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'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
+
5
7
  It contains an internal DNS and uses HAProxy for routing/balancing/fail-over for Pods access.
6
8
  The database is a simple sqlite3 db and the server is a Sinatra based application.
7
9
 
@@ -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.
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.0"
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
@@ -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.0
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-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: async-dns
@@ -315,6 +315,7 @@ files:
315
315
  - config/mkitd_config.sh
316
316
  - db/migrate/001_setup.rb
317
317
  - db/migrate/002_mkit_jobs.rb
318
+ - db/migrate/003_service_ports_ssl.rb
318
319
  - db/schema.rb
319
320
  - lib/mkit.rb
320
321
  - lib/mkit/app/controllers/mkit_controller.rb
@@ -350,13 +351,13 @@ files:
350
351
  - lib/mkit/ctypes.rb
351
352
  - lib/mkit/docker_listener.rb
352
353
  - lib/mkit/exceptions.rb
353
- - lib/mkit/haproxy.rb
354
354
  - lib/mkit/job_manager.rb
355
355
  - lib/mkit/mkit_dns.rb
356
356
  - lib/mkit/mkit_interface.rb
357
357
  - lib/mkit/sagas/asaga.rb
358
358
  - lib/mkit/sagas/create_pod_saga.rb
359
359
  - lib/mkit/sagas/saga_manager.rb
360
+ - lib/mkit/ssl/easy_ssl.rb
360
361
  - lib/mkit/status.rb
361
362
  - lib/mkit/utils.rb
362
363
  - 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
-