mkit 0.9.1 → 0.10.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 +4 -4
- data/README.md +50 -15
- data/db/migrate/004_create_ingress.rb +12 -0
- data/db/migrate/005_create_frontend.rb +20 -0
- data/db/migrate/006_create_backend.rb +18 -0
- data/db/migrate/007_migrate_schema.rb +59 -0
- data/lib/mkit/app/controllers/services_controller.rb +12 -0
- data/lib/mkit/app/helpers/migrations_helper.rb +62 -0
- data/lib/mkit/app/helpers/services_helper.rb +4 -15
- data/lib/mkit/app/model/backend.rb +58 -0
- data/lib/mkit/app/model/frontend.rb +63 -0
- data/lib/mkit/app/model/ingress.rb +98 -0
- data/lib/mkit/app/model/pod.rb +7 -13
- data/lib/mkit/app/model/service.rb +21 -23
- data/lib/mkit/app/model/service_port.rb +0 -1
- data/lib/mkit/app/templates/haproxy/0000_defaults.cfg +2 -2
- data/lib/mkit/app/templates/haproxy/app_haproxy.cfg.erb +28 -0
- data/lib/mkit/client/commands.yaml +13 -0
- data/lib/mkit/config/environment.rb +1 -0
- data/lib/mkit/config/initializers/001_hash.rb +14 -0
- data/lib/mkit/config/initializers/003_custom_exceptions.rb +10 -0
- data/lib/mkit/ctypes.rb +1 -1
- data/lib/mkit/exceptions.rb +13 -1
- data/lib/mkit/pods/docker_listener.rb +19 -14
- data/lib/mkit/sagas/create_pod_saga.rb +9 -7
- data/lib/mkit/sagas/destroy_pod_saga.rb +32 -0
- data/lib/mkit/sagas/saga_manager.rb +2 -0
- data/lib/mkit/version.rb +1 -1
- data/lib/mkit/workers/pod_worker.rb +3 -1
- data/lib/mkit/workers/service_worker.rb +2 -0
- data/samples/apps/httpbin.yml +46 -0
- data/samples/apps/kafka-cluster.yml +18 -8
- data/samples/apps/kafka-magic.yml +27 -10
- data/samples/apps/kafka-zookeeper.yml +18 -7
- data/samples/apps/minio.yml +33 -7
- data/samples/apps/mongo.yml +15 -4
- data/samples/apps/nexus.yml +41 -6
- data/samples/apps/postgres.yml +17 -7
- data/samples/apps/rabbitmq.yml +35 -8
- data/samples/apps/redis-sentinel.yml +15 -5
- data/samples/apps/redis.yml +15 -5
- metadata +14 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 524cddb617c87b3a095f03139dbbd17d8069f15d52b451f704df658e94f2eebb
|
4
|
+
data.tar.gz: f8f86343cdbc20ad16236769e5d16963372b6b470501129c7e74a72d5de5ee3b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 651a204440f41182b41c1ce1fc809a351692ff5e344f72cc2cf5211a42b3634423fdef7ee403ecc82b549ac9f6ca962d5f0ed853294766979fd8e78289c777f1
|
7
|
+
data.tar.gz: b27df3240e917b99a071008b7c440eb56fe41e6a9daa89ccb56fbcd925e212789df87347e64e01f8a21b768a499c7b5662878bdcaf6908531070ae1eaae83279
|
data/README.md
CHANGED
@@ -127,18 +127,52 @@ service:
|
|
127
127
|
name: rabbitmq # unique. Available on internal DNS as 'rabbitmq'
|
128
128
|
image: rabbitmq:3-management-alpine # image
|
129
129
|
network: bridge # docker network - it will be created if it does not exists
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
130
|
+
ingress:
|
131
|
+
# ingress configuration
|
132
|
+
# see https://docs.haproxy.org/3.1/configuration.html
|
133
|
+
frontend: # frontend section
|
134
|
+
- name: http-in-ssl # frontend name - must be unique
|
135
|
+
options: # frontend global section options
|
136
|
+
- option httpclose
|
137
|
+
- option forwardfor
|
138
|
+
bind:
|
139
|
+
port: 443 # to define a range (e.g. 8000-8080), backend `port` must be blank
|
140
|
+
ssl: true # ssl support - default is false
|
141
|
+
mode: http # tcp|http
|
142
|
+
cert: /etc/ssl/certs/server.crt # if empty uses mkit default crt file (mkit.pem)
|
143
|
+
options: # frontend bind section options
|
144
|
+
- accept-proxy
|
145
|
+
- transparent
|
146
|
+
- defer-accept
|
147
|
+
default_backend: admin # backend to use - must point to a backend name
|
148
|
+
- name: http-in
|
149
|
+
bind:
|
150
|
+
port: 80
|
151
|
+
mode: http
|
152
|
+
default_backend: admin
|
153
|
+
- name: server-in
|
154
|
+
bind:
|
155
|
+
port: 5672
|
156
|
+
mode: tcp
|
157
|
+
default_backend: server
|
158
|
+
backend: # backend section
|
159
|
+
- name: admin # backend name - must be unique
|
160
|
+
balance: round_robin # round_robin|least_conn - default is round_robin
|
161
|
+
options: # backend global section options
|
162
|
+
- option httpclose
|
163
|
+
- option forwardfor
|
164
|
+
- cookie JSESSIONID prefix
|
165
|
+
bind:
|
166
|
+
port: 15672 # if this backend is used by a frontend with a range port, this port must be blank
|
167
|
+
mode: http
|
168
|
+
options: # backend bind section options
|
169
|
+
- cookie A
|
170
|
+
- check
|
171
|
+
- name: server
|
172
|
+
balance: round_robin
|
173
|
+
bind:
|
174
|
+
port: 5672
|
175
|
+
mode: tcp
|
142
176
|
resources:
|
143
177
|
min_replicas: 1 # default value. Pods will be available on internal DNS as '<service_name>.internal'
|
144
178
|
max_replicas: 1 # default value
|
@@ -163,9 +197,9 @@ Usage: mkitd [options]
|
|
163
197
|
-b bind specify bind address (e.g. 0.0.0.0)
|
164
198
|
-e env set the environment (default is development)
|
165
199
|
-o addr alias for '-b' option
|
166
|
-
|
167
|
-
|
168
|
-
|
200
|
+
--no-ssl disable ssl - use http for local server. (default is https)
|
201
|
+
--ssl-key-file PATH Path to private key (default mkit internal)
|
202
|
+
--ssl-cert-file PATH Path to certificate (default mkit internal)
|
169
203
|
```
|
170
204
|
|
171
205
|
There's also samples for [systemd](samples/systemd) and [daemontools](samples/daemontools) as well for some miscellaneous [spps](samples/apps).
|
@@ -193,6 +227,7 @@ create create new service
|
|
193
227
|
update update service
|
194
228
|
get print service configuration
|
195
229
|
rm remove service
|
230
|
+
migrate migrate local service definition to the new schema version
|
196
231
|
exec execute a command in a running pod
|
197
232
|
logs view service logs
|
198
233
|
version prints mkit client and server version
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class CreateFrontend < ActiveRecord::Migration[5.1]
|
4
|
+
def up
|
5
|
+
create_table :frontends do |t|
|
6
|
+
t.string :ingress_id
|
7
|
+
t.string :name
|
8
|
+
t.string :mode
|
9
|
+
t.string :port
|
10
|
+
t.string :ssl
|
11
|
+
t.string :crt
|
12
|
+
t.text :options, default: '[]'
|
13
|
+
t.text :bind_options, default: '[]'
|
14
|
+
t.text :default_backend
|
15
|
+
t.string :version
|
16
|
+
t.timestamp :created_at
|
17
|
+
t.timestamp :updated_at
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class CreateBackend < ActiveRecord::Migration[5.1]
|
4
|
+
def up
|
5
|
+
create_table :backends do |t|
|
6
|
+
t.string :ingress_id
|
7
|
+
t.string :name
|
8
|
+
t.string :mode
|
9
|
+
t.string :load_bal
|
10
|
+
t.string :port
|
11
|
+
t.text :options, default: '[]'
|
12
|
+
t.text :bind_options, default: '[]'
|
13
|
+
t.string :version
|
14
|
+
t.timestamp :created_at
|
15
|
+
t.timestamp :updated_at
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class MigrateSchema < ActiveRecord::Migration[5.1]
|
4
|
+
|
5
|
+
#
|
6
|
+
# migrate the schema from service_ports to ingress
|
7
|
+
#
|
8
|
+
def up
|
9
|
+
Service.all.each do |service|
|
10
|
+
ingress_config = service_ports_to_ingress service.service_port
|
11
|
+
service.ingress = Ingress.create(ingress_config)
|
12
|
+
service.service_port.destroy_all
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def service_ports_to_ingress(ports)
|
17
|
+
ingress = { frontend: [], backend: [] }
|
18
|
+
|
19
|
+
ports.each do |port|
|
20
|
+
frontend = {
|
21
|
+
name: "frontend-#{port.external_port}",
|
22
|
+
bind: {
|
23
|
+
port: port.external_port,
|
24
|
+
mode: port.mode
|
25
|
+
},
|
26
|
+
options: [],
|
27
|
+
default_backend: "backend-#{port.external_port}"
|
28
|
+
}
|
29
|
+
|
30
|
+
if port.ssl.start_with?('true')
|
31
|
+
frontend[:bind][:ssl] = true
|
32
|
+
frontend[:bind][:cert] = port.crt
|
33
|
+
end
|
34
|
+
|
35
|
+
backend = {
|
36
|
+
name: "backend-#{port.external_port}",
|
37
|
+
bind: {
|
38
|
+
port: port.internal_port,
|
39
|
+
mode: port.mode
|
40
|
+
},
|
41
|
+
balance: port.load_bal
|
42
|
+
}
|
43
|
+
|
44
|
+
if port.mode == 'http'
|
45
|
+
a= [
|
46
|
+
'option httpclose',
|
47
|
+
'option forwardfor',
|
48
|
+
'cookie JSESSIONID prefix'
|
49
|
+
]
|
50
|
+
backend[:options] = a
|
51
|
+
backend[:bind][:options] = [ 'cookie A check' ]
|
52
|
+
end
|
53
|
+
ingress[:frontend] << frontend
|
54
|
+
ingress[:backend] << backend
|
55
|
+
end
|
56
|
+
|
57
|
+
ingress.remove_symbols_from_keys
|
58
|
+
end
|
59
|
+
end
|
@@ -3,12 +3,14 @@
|
|
3
3
|
require 'mkit/app/model/service'
|
4
4
|
require 'mkit/app/helpers/services_helper'
|
5
5
|
require 'mkit/app/helpers/params_helper'
|
6
|
+
require 'mkit/app/helpers/migrations_helper'
|
6
7
|
require 'mkit/pods/docker_log_listener'
|
7
8
|
require 'mkit/pods/docker_exec_command'
|
8
9
|
|
9
10
|
class ServicesController < MKIt::Server
|
10
11
|
helpers MKIt::ServicesHelper
|
11
12
|
helpers MKIt::ParamsHelper
|
13
|
+
helpers MKIt::MigrationsHelper
|
12
14
|
|
13
15
|
# curl localhost:4567/services
|
14
16
|
get '/services' do
|
@@ -100,6 +102,16 @@ class ServicesController < MKIt::Server
|
|
100
102
|
format_response(srv)
|
101
103
|
end
|
102
104
|
|
105
|
+
post '/services/migrate' do
|
106
|
+
srv = 'no file'
|
107
|
+
if params[:file]
|
108
|
+
tempfile = params[:file][:tempfile]
|
109
|
+
yaml = YAML.safe_load(tempfile.read)
|
110
|
+
srv = migrate_service(yaml).to_yaml
|
111
|
+
end
|
112
|
+
srv
|
113
|
+
end
|
114
|
+
|
103
115
|
#
|
104
116
|
# operations
|
105
117
|
#
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MKIt
|
4
|
+
module MigrationsHelper
|
5
|
+
|
6
|
+
def migrate_service(yaml)
|
7
|
+
yaml['service']['ingress'] = ports_to_ingress(yaml['service']['ports'])
|
8
|
+
yaml['service'].delete('ports')
|
9
|
+
yaml
|
10
|
+
end
|
11
|
+
|
12
|
+
def ports_to_ingress(ports)
|
13
|
+
ingress = { frontend: [], backend: [] }
|
14
|
+
|
15
|
+
ports.each_with_index do |port_config, index|
|
16
|
+
match = port_config.match(/^(.*?):(.*?):(tcp|http):(.*?)($|:ssl$|:ssl,(.+))$/)
|
17
|
+
next unless match
|
18
|
+
|
19
|
+
external_port, internal_port, mode, load_bal, ssl, cert = match.captures
|
20
|
+
|
21
|
+
frontend = {
|
22
|
+
name: "frontend-#{external_port}",
|
23
|
+
options: [],
|
24
|
+
bind: {
|
25
|
+
port: external_port,
|
26
|
+
mode: mode
|
27
|
+
},
|
28
|
+
default_backend: "backend-#{external_port}"
|
29
|
+
}
|
30
|
+
|
31
|
+
if ssl.start_with?(':ssl')
|
32
|
+
frontend[:bind][:ssl] = true
|
33
|
+
frontend[:bind][:cert] = cert
|
34
|
+
end
|
35
|
+
|
36
|
+
backend = {
|
37
|
+
name: "backend-#{external_port}",
|
38
|
+
bind: {
|
39
|
+
port: internal_port,
|
40
|
+
mode: mode
|
41
|
+
},
|
42
|
+
balance: load_bal
|
43
|
+
}
|
44
|
+
|
45
|
+
if mode == 'http'
|
46
|
+
a= [
|
47
|
+
'option httpclose',
|
48
|
+
'option forwardfor',
|
49
|
+
'cookie JSESSIONID prefix'
|
50
|
+
]
|
51
|
+
backend[:options] = a
|
52
|
+
backend[:bind][:options] = [ 'cookie A check' ]
|
53
|
+
end
|
54
|
+
ingress[:frontend] << frontend
|
55
|
+
ingress[:backend] << backend
|
56
|
+
end
|
57
|
+
|
58
|
+
ingress.remove_symbols_from_keys
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|
@@ -34,27 +34,16 @@ module MKIt
|
|
34
34
|
end
|
35
35
|
|
36
36
|
def build_table_row(data)
|
37
|
-
ports = data.
|
37
|
+
ports = data.ingress.frontends&.each.map { |f| build_port(f) }.join(',')
|
38
38
|
pods = data.pod.each.map { |p| p.name.to_s }.join(' ')
|
39
39
|
[data.id, data.name, data.lease&.ip, ports, pods, data.status]
|
40
40
|
end
|
41
41
|
|
42
42
|
def build_port(p)
|
43
|
-
|
44
|
-
|
45
|
-
if p.ssl?
|
46
|
-
"#{p.mode}s/#{p.external_port}"
|
47
|
-
else
|
48
|
-
"#{p.mode}/#{p.external_port}"
|
49
|
-
end
|
50
|
-
when 'tcp'
|
51
|
-
if p.ssl?
|
52
|
-
"s#{p.mode}/#{p.external_port}"
|
53
|
-
else
|
54
|
-
"#{p.mode}/#{p.external_port}"
|
55
|
-
end
|
43
|
+
if p.ssl?
|
44
|
+
"#{p.mode}s/#{p.port}"
|
56
45
|
else
|
57
|
-
"#{p.mode}/#{p.
|
46
|
+
"#{p.mode}/#{p.port}"
|
58
47
|
end
|
59
48
|
end
|
60
49
|
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Backend < ActiveRecord::Base
|
4
|
+
belongs_to :ingress
|
5
|
+
serialize :options, JSON
|
6
|
+
serialize :bind_options, JSON
|
7
|
+
|
8
|
+
def self.create(yaml)
|
9
|
+
validate(yaml)
|
10
|
+
backend = Backend.new
|
11
|
+
backend.name = yaml["name"]
|
12
|
+
backend.port = yaml["bind"]["port"] if yaml["bind"]["port"]
|
13
|
+
backend.mode = yaml["bind"]["mode"] if yaml["bind"]["mode"]
|
14
|
+
backend.options = yaml["options"] if yaml["options"]
|
15
|
+
backend.load_bal = yaml["balance"] if yaml["balance"]
|
16
|
+
backend.bind_options = yaml["bind"]["options"] if yaml["bind"]["options"]
|
17
|
+
backend
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.validate(yaml)
|
21
|
+
raise_bad_configuration "name is mandatory" unless yaml["name"]
|
22
|
+
raise_bad_configuration "bind is mandatory" unless yaml["bind"]
|
23
|
+
raise_bad_configuration "mode is mandatory" unless yaml["bind"]["mode"]
|
24
|
+
raise_bad_configuration "mode must match tcp|http" unless yaml["bind"]["mode"] =~ /^(tcp|http)$/
|
25
|
+
if yaml["balance"]
|
26
|
+
raise_bad_configuration "balance must match round_robin|least_conn" unless yaml["balance"] =~ /^(round_robin|least_conn)$/
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def load_balance
|
31
|
+
case self.load_bal
|
32
|
+
when /^round_robin$/
|
33
|
+
"roundrobin"
|
34
|
+
when /^least_conn$/
|
35
|
+
"leastconn"
|
36
|
+
else
|
37
|
+
"roundrobin"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def to_h(options = {})
|
42
|
+
hash = {
|
43
|
+
name: self.name,
|
44
|
+
balance: self.load_bal,
|
45
|
+
options: self.options,
|
46
|
+
bind: {
|
47
|
+
port: self.port,
|
48
|
+
mode: self.mode,
|
49
|
+
options: self.bind_options
|
50
|
+
}
|
51
|
+
}
|
52
|
+
|
53
|
+
if self.port.nil? || self.port.empty?
|
54
|
+
hash[:bind].delete(:port)
|
55
|
+
end
|
56
|
+
hash.remove_symbols_from_keys
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'mkit/exceptions'
|
3
|
+
|
4
|
+
class Frontend < ActiveRecord::Base
|
5
|
+
belongs_to :ingress
|
6
|
+
serialize :options, JSON
|
7
|
+
serialize :bind_options, JSON
|
8
|
+
has_one :backend
|
9
|
+
|
10
|
+
def self.create(yaml)
|
11
|
+
validate(yaml)
|
12
|
+
frontend = Frontend.new
|
13
|
+
|
14
|
+
frontend.name = yaml["name"]
|
15
|
+
frontend.port = yaml["bind"]["port"] if yaml["bind"]["port"]
|
16
|
+
frontend.mode = yaml["bind"]["mode"] if yaml["bind"]["mode"]
|
17
|
+
frontend.bind_options = yaml["bind"]["options"] if yaml["bind"]["options"]
|
18
|
+
frontend.options = yaml["options"] if yaml["options"]
|
19
|
+
frontend.default_backend = yaml["use_backend"]
|
20
|
+
|
21
|
+
has_ssl = !yaml["bind"]["ssl"].nil? && yaml["bind"]["ssl"].to_s.start_with?('true')
|
22
|
+
frontend.ssl = has_ssl ? 'true' : 'false'
|
23
|
+
if has_ssl
|
24
|
+
frontend.crt = yaml["bind"]["cert"].nil? ? MKIt::Utils.proxy_cert : yaml["bind"]["cert"]
|
25
|
+
end
|
26
|
+
|
27
|
+
frontend
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.validate(yaml)
|
31
|
+
raise_bad_configuration "name is mandatory" unless yaml["name"]
|
32
|
+
raise_bad_configuration "default_backend is mandatory" unless yaml["default_backend"]
|
33
|
+
raise_bad_configuration "bind is mandatory" unless yaml["bind"]
|
34
|
+
raise_bad_configuration "mode is mandatory" unless yaml["bind"]["mode"]
|
35
|
+
raise_bad_configuration "frontend port is mandatory" unless yaml["bind"]["port"]
|
36
|
+
raise_bad_configuration "mode must match tcp|http" unless yaml["bind"]["mode"] =~ /^(tcp|http)$/
|
37
|
+
end
|
38
|
+
|
39
|
+
def ssl?
|
40
|
+
self.ssl == 'true'
|
41
|
+
end
|
42
|
+
|
43
|
+
def to_h(options = {})
|
44
|
+
hash = {
|
45
|
+
name: self.name,
|
46
|
+
options: self.options,
|
47
|
+
bind: {
|
48
|
+
port: self.port,
|
49
|
+
mode: self.mode,
|
50
|
+
ssl: self.ssl,
|
51
|
+
cert: self.ssl? ? self.crt : nil,
|
52
|
+
options: self.bind_options
|
53
|
+
},
|
54
|
+
default_backend: self.default_backend
|
55
|
+
}
|
56
|
+
|
57
|
+
unless self.ssl?
|
58
|
+
hash[:bind].delete(:ssl)
|
59
|
+
hash[:bind].delete(:cert)
|
60
|
+
end
|
61
|
+
hash.remove_symbols_from_keys
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'mkit/app/model/backend'
|
3
|
+
require 'mkit/app/model/frontend'
|
4
|
+
|
5
|
+
class Ingress < ActiveRecord::Base
|
6
|
+
belongs_to :service
|
7
|
+
has_many :frontends, dependent: :destroy
|
8
|
+
has_many :backends, dependent: :destroy
|
9
|
+
|
10
|
+
def self.create(yaml)
|
11
|
+
validate(yaml)
|
12
|
+
ingress = Ingress.new
|
13
|
+
|
14
|
+
yaml["backend"].each do |back|
|
15
|
+
ingress.backends << Backend.create(back)
|
16
|
+
end
|
17
|
+
|
18
|
+
yaml["frontend"].each do |front|
|
19
|
+
ingress.frontends << Frontend.create(front)
|
20
|
+
end
|
21
|
+
ingress
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.validate(yaml)
|
25
|
+
frontend_names = []
|
26
|
+
frontend_ports = []
|
27
|
+
|
28
|
+
# must have at least one frontend and one backend
|
29
|
+
raise_bad_configuration "Ingress section is mandatory" unless yaml
|
30
|
+
raise_bad_configuration "At least one frontend is mandatory" unless yaml["frontend"]
|
31
|
+
raise_bad_configuration "At least one backend is mandatory" unless yaml["backend"]
|
32
|
+
# frontend name is mandatory
|
33
|
+
yaml["frontend"].each { |front| raise "Frontend name is mandatory" unless front["name"] }
|
34
|
+
# backend name is mandatory
|
35
|
+
yaml["backend"].each { |back| raise "Backend name is mandatory" unless back["name"] }
|
36
|
+
# frontend must point to a valid backend name - backend names list
|
37
|
+
backend_names = yaml["backend"].map { |back| back["name"] }
|
38
|
+
|
39
|
+
# frontend validation
|
40
|
+
yaml["frontend"].each do |front|
|
41
|
+
# name is mandatory
|
42
|
+
raise_bad_configuration "Frontend name is mandatory" unless front["name"]
|
43
|
+
# frontend name must be unique
|
44
|
+
if frontend_names.include?(front["name"])
|
45
|
+
raise_bad_configuration "Frontend name '#{front["name"]}' must be unique"
|
46
|
+
end
|
47
|
+
frontend_names << front["name"]
|
48
|
+
|
49
|
+
# bind and mode are mandatory, port is not
|
50
|
+
raise_bad_configuration "Frontend bind and mode are mandatory" unless front["bind"] && front["bind"]["mode"]
|
51
|
+
|
52
|
+
# port must be unique
|
53
|
+
if frontend_ports.include?(front["bind"]["port"])
|
54
|
+
raise_bad_configuration "Frontend port '#{front["bind"]["port"]}' must be unique"
|
55
|
+
end
|
56
|
+
frontend_ports << front["bind"]["port"]
|
57
|
+
|
58
|
+
# default_backend must point to a valid backend name
|
59
|
+
unless backend_names.include?(front["default_backend"])
|
60
|
+
raise_bad_configuration "Frontend default_backend '#{front["default_backend"]}' must point to a valid backend name"
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
# backend validation
|
66
|
+
backend_names.each do |name|
|
67
|
+
if backend_names.count(name) > 1
|
68
|
+
raise_bad_configuration "Backend name '#{name}' must be unique"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# global validations
|
73
|
+
# each backend must point to a valid frontend default_backend
|
74
|
+
frontend_default_backends = yaml["frontend"].map { |front| front["default_backend"] }
|
75
|
+
yaml["backend"].each do |back|
|
76
|
+
unless frontend_default_backends.include?(back["name"])
|
77
|
+
raise_bad_configuration "Backend '#{back["name"]}' must be referenced by at least one frontend default_backend"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# when frontend port is range - e.g. 1200-1220, referred backend port must be empty
|
82
|
+
yaml["frontend"].each do |front|
|
83
|
+
if front["bind"]["port"] =~ /^\d+-\d+$/
|
84
|
+
referred_backend = yaml["backend"].find { |back| back["name"] == front["default_backend"] }
|
85
|
+
raise_bad_configuration "Frontend port range '#{front["bind"]["port"]}' must have an empty backend port" unless referred_backend && (referred_backend["bind"]["port"].nil?)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
true
|
90
|
+
end
|
91
|
+
|
92
|
+
def to_h(options = {})
|
93
|
+
{
|
94
|
+
frontend: self.frontends.map { |front| front.to_h },
|
95
|
+
backend: self.backends.map { |back| back.to_h }
|
96
|
+
}.remove_symbols_from_keys
|
97
|
+
end
|
98
|
+
end
|
data/lib/mkit/app/model/pod.rb
CHANGED
@@ -58,13 +58,7 @@ class Pod < ActiveRecord::Base
|
|
58
58
|
end
|
59
59
|
|
60
60
|
def start
|
61
|
-
|
62
|
-
docker_run = parse
|
63
|
-
MKItLogger.info("deploying docker pod, cmd [#{docker_run}]")
|
64
|
-
create_instance(docker_run)
|
65
|
-
else
|
66
|
-
start_instance(self.name) unless instance.State.Running
|
67
|
-
end
|
61
|
+
start_instance(self.name) unless instance.State.Running
|
68
62
|
end
|
69
63
|
|
70
64
|
def stop
|
@@ -78,12 +72,12 @@ class Pod < ActiveRecord::Base
|
|
78
72
|
end
|
79
73
|
|
80
74
|
def clean_up
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
75
|
+
# stop and destroy pod
|
76
|
+
MkitJob.publish(topic: :destroy_pod_saga,
|
77
|
+
service_id: self.service.id,
|
78
|
+
pod_id: self.id,
|
79
|
+
data: {pod_name: self.name}
|
80
|
+
)
|
87
81
|
end
|
88
82
|
|
89
83
|
def to_h
|