Skip to content

Commit

Permalink
roles: add tls support
Browse files Browse the repository at this point in the history
Since we support TLS in this module, we need to add it into roles too.

After the patch TLS params was added. It can be configurated like the
following:

```yaml
server_name:
  listen: "localhost:3013"
  params:
    ssl_key_file: "path/to/key/file"
    ssl_cert_file: "path/to/key/file"
    ssl_ca_file: "path/to/key/file"
    ssl_ciphers: "cipher1:cipher2"
    ssl_password: "password"
    ssl_password_file: "path/to/ssl/password"
```

Closes #199
  • Loading branch information
themilchenko committed Nov 12, 2024
1 parent 5bfaaf8 commit d176d90
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 12 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
### Added

- SSL support (#35).
- SSL support into roles (#199).

### Changed

Expand Down
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -581,6 +581,23 @@ end
return M
```
To enable TLS, provide the following params into roles config (for proper work
it's enough to provide only `ssl_key_file` and `ssl_cert_file`):
```yaml
roles_cfg:
roles.httpd:
default:
listen: 8081
params:
ssl_key_file: "path/to/key/file"
ssl_cert_file: "path/to/key/file"
ssl_ca_file: "path/to/key/file"
ssl_ciphers: "cipher1:cipher2"
ssl_password: "password"
ssl_password_file: "path/to/ssl/password"
```
This role accepts a server by name from a config and creates a route to return
`Hello, world!` to every request by this route.
Expand Down
20 changes: 19 additions & 1 deletion roles/httpd.lua
Original file line number Diff line number Diff line change
Expand Up @@ -72,14 +72,32 @@ local function parse_listen(listen)
return host, port, nil
end

-- get_params returns table with set params from config to
-- pass it into new() func.
local function get_params(params)
if params ~= nil then
return {
ssl_cert_file = params.ssl_cert_file,
ssl_key_file = params.ssl_key_file,
ssl_password = params.ssl_password,
ssl_password_file = params.ssl_password_file,
ssl_ca_file = params.ssl_ca_file,
ssl_ciphers = params.ssl_ciphers,
}
end
end

local function apply_http(name, node)
local host, port, err = parse_listen(node.listen)
if err ~= nil then
error("failed to parse URI: " .. err)
end

local params = get_params(node.params)

if servers[name] == nil then
local httpd = http_server.new(host, port)
local httpd = http_server.new(host, port, params)

httpd:start()
servers[name] = {
httpd = httpd,
Expand Down
56 changes: 45 additions & 11 deletions test/integration/httpd_role_test.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,18 @@ local treegen = require('luatest.treegen')
local server = require('luatest.server')
local fun = require('fun')
local yaml = require('yaml')
local fio = require('fio')
local http_client = require('http.client').new()


local helpers = require('test.helpers')

local g = t.group()
local g = t.group(nil, {
{ use_tls = false },
{ use_tls = true },
})

local ssl_data_dir = fio.abspath(fio.pathjoin(helpers.get_testdir_path(), "ssl_data"))

local config = {
credentials = {
Expand Down Expand Up @@ -55,29 +63,55 @@ local config = {
},
}

g.before_each(function()
local tls_config = table.deepcopy(config)
tls_config.groups['group-001'].replicasets['replicaset-001'].roles_cfg['roles.httpd'].default.params = {
ssl_cert_file = fio.pathjoin(ssl_data_dir, 'server.crt'),
ssl_key_file = fio.pathjoin(ssl_data_dir, 'server.enc.key'),
ssl_password_file = fio.pathjoin(ssl_data_dir, 'passwords'),
}

g.before_each(function(cg)
helpers.skip_if_not_tarantool3()

local dir = treegen.prepare_directory({}, {})

local cfg = config
if cg.params.use_tls then
cfg = tls_config
end

local config_file = treegen.write_file(dir, 'config.yaml',
yaml.encode(config))
yaml.encode(cfg))
local opts = {config_file = config_file, chdir = dir}
g.server = server:new(fun.chain(opts, {alias = 'instance-001'}):tomap())
helpers.update_lua_env_variables(g.server)
cg.server = server:new(fun.chain(opts, {alias = 'instance-001'}):tomap())
helpers.update_lua_env_variables(cg.server)

g.server:start()
cg.server:start()
end)

g.after_each(function()
g.server:stop()
g.after_each(function(cg)
helpers.teardown(cg.server)
end)

g.test_httpd_role_usage = function()
t.assert_equals(g.server:eval(
g.test_httpd_role_usage = function(cg)
if cg.params.use_tls then
local resp = http_client:get('https://localhost:13000/ping', {
ca_file = fio.pathjoin(ssl_data_dir, 'ca.crt')
})
t.assert_equals(resp.status, 200, 'response not 200')
t.assert_equals(resp.body, 'pong')
end

-- We can use https only for one endpoind due to we haven't publish separate
-- certificates for it.
local resp = http_client:get('http://localhost:13001/ping')
t.assert_equals(resp.status, 200, 'response not 200')
t.assert_equals(resp.body, 'pong')

t.assert_equals(cg.server:eval(
'return require("test.mocks.mock_role").get_server_port(1)'
), 13000)
t.assert_equals(g.server:eval(
t.assert_equals(cg.server:eval(
'return require("test.mocks.mock_role").get_server_port(2)'
), 13001)
end
6 changes: 6 additions & 0 deletions test/mocks/mock_role.lua
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ M.validate = function() end
M.apply = function(conf)
for _, server in pairs(conf) do
servers[server.id] = require('roles.httpd').get_server(server.name)

servers[server.id]:route({
path = '/ping',
}, function(tx)
return tx:render({text = 'pong'})
end)
end
end

Expand Down

0 comments on commit d176d90

Please sign in to comment.