Beginnings of secret admin w/dialog
This commit is contained in:
parent
1f02e0af11
commit
6d1651f3ec
@ -1,7 +1,7 @@
|
|||||||
require "kemal"
|
require "kemal"
|
||||||
|
|
||||||
# This is a kemal app, you can add handlers, middleware, etc.
|
# This is a kemal app, you can add handlers, middleware, etc.
|
||||||
|
|
||||||
# A basic hello world get endpoint
|
# A basic hello world get endpoint
|
||||||
get "/" do
|
get "/" do
|
||||||
"Hello World Crystal!"
|
"Hello World Crystal!"
|
||||||
@ -10,7 +10,7 @@ end
|
|||||||
# The `/ping/` endpoint is configured in the container as a healthcheck
|
# The `/ping/` endpoint is configured in the container as a healthcheck
|
||||||
# You can make it better by checking that your database is responding
|
# You can make it better by checking that your database is responding
|
||||||
# or whatever checks you think are important
|
# or whatever checks you think are important
|
||||||
#
|
#
|
||||||
get "/ping/" do
|
get "/ping/" do
|
||||||
"OK"
|
"OK"
|
||||||
end
|
end
|
||||||
|
52
public/bars.svg
Normal file
52
public/bars.svg
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
<svg width="16" height="16" viewBox="0 0 135 140" xmlns="http://www.w3.org/2000/svg" fill="#494949">
|
||||||
|
<rect y="10" width="15" height="120" rx="6">
|
||||||
|
<animate attributeName="height"
|
||||||
|
begin="0.5s" dur="1s"
|
||||||
|
values="120;110;100;90;80;70;60;50;40;140;120" calcMode="linear"
|
||||||
|
repeatCount="indefinite" />
|
||||||
|
<animate attributeName="y"
|
||||||
|
begin="0.5s" dur="1s"
|
||||||
|
values="10;15;20;25;30;35;40;45;50;0;10" calcMode="linear"
|
||||||
|
repeatCount="indefinite" />
|
||||||
|
</rect>
|
||||||
|
<rect x="30" y="10" width="15" height="120" rx="6">
|
||||||
|
<animate attributeName="height"
|
||||||
|
begin="0.25s" dur="1s"
|
||||||
|
values="120;110;100;90;80;70;60;50;40;140;120" calcMode="linear"
|
||||||
|
repeatCount="indefinite" />
|
||||||
|
<animate attributeName="y"
|
||||||
|
begin="0.25s" dur="1s"
|
||||||
|
values="10;15;20;25;30;35;40;45;50;0;10" calcMode="linear"
|
||||||
|
repeatCount="indefinite" />
|
||||||
|
</rect>
|
||||||
|
<rect x="60" width="15" height="140" rx="6">
|
||||||
|
<animate attributeName="height"
|
||||||
|
begin="0s" dur="1s"
|
||||||
|
values="120;110;100;90;80;70;60;50;40;140;120" calcMode="linear"
|
||||||
|
repeatCount="indefinite" />
|
||||||
|
<animate attributeName="y"
|
||||||
|
begin="0s" dur="1s"
|
||||||
|
values="10;15;20;25;30;35;40;45;50;0;10" calcMode="linear"
|
||||||
|
repeatCount="indefinite" />
|
||||||
|
</rect>
|
||||||
|
<rect x="90" y="10" width="15" height="120" rx="6">
|
||||||
|
<animate attributeName="height"
|
||||||
|
begin="0.25s" dur="1s"
|
||||||
|
values="120;110;100;90;80;70;60;50;40;140;120" calcMode="linear"
|
||||||
|
repeatCount="indefinite" />
|
||||||
|
<animate attributeName="y"
|
||||||
|
begin="0.25s" dur="1s"
|
||||||
|
values="10;15;20;25;30;35;40;45;50;0;10" calcMode="linear"
|
||||||
|
repeatCount="indefinite" />
|
||||||
|
</rect>
|
||||||
|
<rect x="120" y="10" width="15" height="120" rx="6">
|
||||||
|
<animate attributeName="height"
|
||||||
|
begin="0.5s" dur="1s"
|
||||||
|
values="120;110;100;90;80;70;60;50;40;140;120" calcMode="linear"
|
||||||
|
repeatCount="indefinite" />
|
||||||
|
<animate attributeName="y"
|
||||||
|
begin="0.5s" dur="1s"
|
||||||
|
values="10;15;20;25;30;35;40;45;50;0;10" calcMode="linear"
|
||||||
|
repeatCount="indefinite" />
|
||||||
|
</rect>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.3 KiB |
@ -1,15 +1,23 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<link rel="stylesheet" href="https://matcha.mizu.sh/matcha.css" />
|
<link rel="stylesheet" href="https://matcha.mizu.sh/matcha.css" />
|
||||||
<script src="https://unpkg.com/htmx.org@2.0.0"></script>
|
<script src="https://unpkg.com/htmx.org@2.0.0"></script>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<header class="container">
|
<header class="container">
|
||||||
<h1>Your Funko Collection</h1>
|
<h1>FaaSO Admin Interface</h1>
|
||||||
</header>
|
</header>
|
||||||
<main class=container>
|
<main class=container>
|
||||||
|
<h2>Your Funko Collection
|
||||||
|
<button id="update-funkos" style="float:right; display:inline;" hx-trigger="load, click, every 60s"
|
||||||
|
hx-get="funkos/?format=html" hx-target="#funko-list">
|
||||||
|
Refresh
|
||||||
|
</button>
|
||||||
|
</h2>
|
||||||
<span id="message"></span>
|
<span id="message"></span>
|
||||||
<table hx-target="#message">
|
<table hx-target="#message">
|
||||||
<thead>
|
<thead>
|
||||||
@ -24,12 +32,60 @@
|
|||||||
<tbody id="funko-list">
|
<tbody id="funko-list">
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<button id="update-funkos" style="float:right;" hx-trigger="load, click, every 60s" hx-get="funkos/?format=html"
|
|
||||||
hx-target="#funko-list">Update</button>
|
|
||||||
</main>
|
</main>
|
||||||
<script>
|
<script>
|
||||||
update_funkos =function() {
|
update_funkos = function () {
|
||||||
document.getElementById("update-funkos").click()
|
document.getElementById("update-funkos").click()
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
</body>
|
<main class=container>
|
||||||
|
<h2>
|
||||||
|
Your Secrets
|
||||||
|
<button id="update-secrets" style="float:right; display:inline;" hx-trigger="load, click, every 60s"
|
||||||
|
hx-get="secrets/?format=html" hx-target="#secret-list">
|
||||||
|
Refresh
|
||||||
|
</button>
|
||||||
|
<button style="float:right; display:inline;" onclick="show_new_secret()">
|
||||||
|
Add
|
||||||
|
</button>
|
||||||
|
</h2>
|
||||||
|
<span id="message"></span>
|
||||||
|
<table hx-target="#message">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Funko</th>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Actions</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id="secret-list">
|
||||||
|
</tbody>
|
||||||
|
<dialog id="add-secret">
|
||||||
|
<topic>New Secret</topic>
|
||||||
|
<form hx-post="secrets/">
|
||||||
|
<input placeholder="funko name" id="new-secret-funko" name="funko">
|
||||||
|
<input placeholder="secret name" id="new-secret-name" name="name">
|
||||||
|
<input placeholder="secret value" type="password" id="new-secret-password" name="value">
|
||||||
|
<button type="submit" hx-on:htmx:after-request="update_secrets(); hide_new_secret()">CREATE</button>
|
||||||
|
<button onclick="hide_new_secret()">CANCEL</button>
|
||||||
|
</form>
|
||||||
|
</dialog>
|
||||||
|
<script>
|
||||||
|
update_secrets = function() {
|
||||||
|
document.getElementById("update-secrets").click()
|
||||||
|
}
|
||||||
|
show_new_secret = function() {
|
||||||
|
document.getElementById('new-secret-funko').value=""
|
||||||
|
document.getElementById('add-secret').value=""
|
||||||
|
document.getElementById('add-secret').value=""
|
||||||
|
document.getElementById('add-secret').show()
|
||||||
|
}
|
||||||
|
hide_new_secret = function() {
|
||||||
|
document.getElementById('new-secret-funko').value=""
|
||||||
|
document.getElementById('add-secret').value=""
|
||||||
|
document.getElementById('add-secret').value=""
|
||||||
|
document.getElementById('add-secret').hide()
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</main>
|
||||||
|
</body>
|
@ -39,7 +39,7 @@ module Proxy
|
|||||||
ReverseOnly Yes
|
ReverseOnly Yes
|
||||||
ReverseMagic Yes
|
ReverseMagic Yes
|
||||||
ReversePath "/admin/" "http://127.0.0.1:3000/"
|
ReversePath "/admin/" "http://127.0.0.1:3000/"
|
||||||
) + funkos.map { |funko| %(ReversePath "/faaso/#{funko}/" "http://#{funko}:3000/") }.join("\n")
|
) + funkos.map { |funko| %(ReversePath "/faaso/#{funko.split("-")[0]}/" "http://#{funko}:3000/") }.join("\n")
|
||||||
|
|
||||||
if @@current_config != config
|
if @@current_config != config
|
||||||
File.open("tinyproxy.conf", "w") do |file|
|
File.open("tinyproxy.conf", "w") do |file|
|
||||||
|
@ -7,15 +7,30 @@ module Secrets
|
|||||||
|
|
||||||
# Gets a secret in form {"name": "funko_name-secret_name", "value": "secret_value"}
|
# Gets a secret in form {"name": "funko_name-secret_name", "value": "secret_value"}
|
||||||
post "/secrets/" do |env|
|
post "/secrets/" do |env|
|
||||||
name = env.params.json["name"].as(String)
|
funko = env.params.body["funko"].as(String)
|
||||||
value = env.params.json["value"].as(String)
|
name = env.params.body["name"].as(String)
|
||||||
SECRETS[name] = value
|
value = env.params.body["value"].as(String)
|
||||||
|
if funko.empty? || name.empty? || value.empty?
|
||||||
|
halt env, status_code: 400, response: "Bad request"
|
||||||
|
end
|
||||||
|
SECRETS["#{funko}-#{name}"] = value
|
||||||
Secrets.update_secrets
|
Secrets.update_secrets
|
||||||
halt env, status_code: 201, response: "Created"
|
halt env, status_code: 201, response: "Created"
|
||||||
end
|
end
|
||||||
|
|
||||||
get "/secrets/" do |env|
|
get "/secrets/" do |env|
|
||||||
halt env, status_code: 200, response: SECRETS.keys.to_json
|
result = [] of Hash(String, String)
|
||||||
|
SECRETS.each { |k, _|
|
||||||
|
result << {
|
||||||
|
"funko" => k.split("-")[0],
|
||||||
|
"name" => k.split("-", 2)[1],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if env.params.query.fetch("format", "json") == "html"
|
||||||
|
render "src/views/secrets.ecr"
|
||||||
|
else
|
||||||
|
result.to_json
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Deletes a secret from the disk and memory
|
# Deletes a secret from the disk and memory
|
||||||
|
@ -96,10 +96,11 @@ module Funko
|
|||||||
|
|
||||||
Log.info { "Scaling #{name} from #{current_scale} to #{new_scale}" }
|
Log.info { "Scaling #{name} from #{current_scale} to #{new_scale}" }
|
||||||
if new_scale > current_scale
|
if new_scale > current_scale
|
||||||
Log.info { "Adding instance" }
|
|
||||||
(current_scale...new_scale).each {
|
(current_scale...new_scale).each {
|
||||||
|
Log.info { "Adding instance" }
|
||||||
id = create_container
|
id = create_container
|
||||||
start(id)
|
start(id)
|
||||||
|
sleep 0.1.seconds
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
containers.select { |container| container.@state == "running" }.sort! { |i, j|
|
containers.select { |container| container.@state == "running" }.sort! { |i, j|
|
||||||
@ -109,6 +110,7 @@ module Funko
|
|||||||
docker_api.containers.stop(container.@id)
|
docker_api.containers.stop(container.@id)
|
||||||
current_scale -= 1
|
current_scale -= 1
|
||||||
break if current_scale == new_scale
|
break if current_scale == new_scale
|
||||||
|
sleep 0.1.seconds
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
<button hx-get="funkos/<%= f["name"] %>/restart" hx-on:htmx:after-request="update_funkos()">Restart</button>
|
<button hx-get="funkos/<%= f["name"] %>/restart" hx-on:htmx:after-request="update_funkos()">Restart</button>
|
||||||
<%- end -%>
|
<%- end -%>
|
||||||
<%- end -%>
|
<%- end -%>
|
||||||
<img id="spinner-<%= f["name"] %>" src="https://htmx.org/img/bars.svg" class="htmx-indicator">
|
<img id="spinner-<%= f["name"] %>" src="bars.svg" class="htmx-indicator">
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<%- end -%>
|
<%- end -%>
|
||||||
|
11
src/views/secrets.ecr
Normal file
11
src/views/secrets.ecr
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<%- result.each do |f| -%>
|
||||||
|
<tr hx-indicator="#spinner-<%= f["name"] %>">
|
||||||
|
<td><%= f["funko"] %></td>
|
||||||
|
<td><%= f["name"] %></td>
|
||||||
|
<td>
|
||||||
|
<button hx-post="secrets/" hx-on:htmx:after-request="update_secrets()">Change</button>
|
||||||
|
<button hx-delete="secrets/<%= f["funko"] %>-<%= f["name"] %>/" hx-on:htmx:after-request="update_secrets()">Delete</button>
|
||||||
|
<img id="spinner-<%= f["name"] %>" src="bars.svg" class="htmx-indicator">
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<%- end -%>
|
@ -8,4 +8,4 @@
|
|||||||
ReverseOnly Yes
|
ReverseOnly Yes
|
||||||
ReverseMagic Yes
|
ReverseMagic Yes
|
||||||
ReversePath "/admin/" "http://127.0.0.1:3000/"
|
ReversePath "/admin/" "http://127.0.0.1:3000/"
|
||||||
ReversePath "/faaso/hello-fkvrm2/" "http://hello-fkvrm2:3000/"
|
ReversePath "/faaso/hello/" "http://hello-c9ge0d:3000/"
|
Loading…
Reference in New Issue
Block a user