[web] hosts/add
This commit is contained in:
parent
de64f1ed00
commit
9bdee4f793
|
@ -92,7 +92,20 @@
|
|||
"edit": "Edit",
|
||||
"enroll": "Enroll",
|
||||
"delete": "Delete",
|
||||
"config": "Configuration"
|
||||
"config": "Configuration",
|
||||
"add": "Add",
|
||||
"create": {
|
||||
"name": "Host name",
|
||||
"btn": "Add host",
|
||||
"cancel": "Cancel",
|
||||
"role": "Role",
|
||||
"ip": "IP Address",
|
||||
"error": {
|
||||
"needsname": "Host name is required.",
|
||||
"needsrole": "Role is required.",
|
||||
"invalidip": "Invalid IP address"
|
||||
}
|
||||
}
|
||||
},
|
||||
"roles": {
|
||||
"delete": {
|
||||
|
@ -184,7 +197,8 @@
|
|||
"hosts": "Hosts",
|
||||
"roles": "Roles",
|
||||
"lighthouses": "Lighthouses",
|
||||
"relays": "Relays"
|
||||
"relays": "Relays",
|
||||
"addhost": "Add Host"
|
||||
},
|
||||
"logout": "Log out",
|
||||
"loading": "Dashboard is loading"
|
||||
|
|
|
@ -98,7 +98,8 @@
|
|||
|
||||
<LoadingWrapper isLoading={currentlyLoading} isError={isError} error={error}>
|
||||
<AdminLayout selected="hosts">
|
||||
<h3>{$t("common.page.hosts")}</h3>
|
||||
|
||||
<h3>{$t("common.page.hosts")} <a href="/hosts/add" class="btn btn-primary float-end">{$t("hosts.add")} <i class="fas fa-plus ms-1"></i></a></h3>
|
||||
|
||||
<table class="table table-dark table-hover">
|
||||
<thead>
|
||||
|
@ -114,7 +115,7 @@
|
|||
{#each hosts as host}
|
||||
{#if !(host.isLighthouse || host.isRelay)}
|
||||
<tr>
|
||||
<td>{host.name}</td>
|
||||
<td><a href="/hosts/{host.id}/edit">{host.name}</a></td>
|
||||
<td>{host.metadata?.lastSeenAt}</td>
|
||||
<td>{host.ipAddress}</td>
|
||||
<td><a href="/roles/{host.roleID}/edit">{getRoleName(host.roleID)}</a></td>
|
||||
|
|
|
@ -0,0 +1,196 @@
|
|||
<script lang="ts">
|
||||
import {isLoading, t} from "svelte-i18n";
|
||||
import LoadingWrapper from "$components/LoadingWrapper.svelte";
|
||||
import {onMount} from "svelte";
|
||||
import {APIResult, isAuthedMFA, isAuthedSession} from "$lib/auth.ts";
|
||||
import {Logger, logSetup} from "$lib/logger";
|
||||
import type {APIError} from "$lib/auth.ts";
|
||||
import {PUBLIC_BASE_URL} from "$env/static/public";
|
||||
import {Configuration, HostsApi, NetworksApi, ResponseError, RolesApi} from "$lib/api";
|
||||
import type {Host} from "$lib/api/models/Host.ts";
|
||||
import type {Role} from "$lib/api/models/Role.ts";
|
||||
import AdminLayout from "$components/AdminLayout.svelte";
|
||||
import {page} from "$app/stores";
|
||||
|
||||
let loading = true;
|
||||
let isError = false;
|
||||
let error = '';
|
||||
$: currentlyLoading = $isLoading;
|
||||
|
||||
let hosts: Host[] = [];
|
||||
let roles: Role[] = [];
|
||||
|
||||
let network = "";
|
||||
|
||||
logSetup();
|
||||
let logger = new Logger("hosts/add/+page.svelte");
|
||||
|
||||
onMount(async () => {
|
||||
let session_load_info = await isAuthedSession();
|
||||
if (session_load_info[0] == APIResult.Failed) {
|
||||
let err = session_load_info[1] as APIError;
|
||||
logger.error(`session load failed: ${err.code} ${err.message}`);
|
||||
window.location.href = '/login';
|
||||
return;
|
||||
}
|
||||
|
||||
let mfa_load_info = await isAuthedMFA();
|
||||
if (mfa_load_info[0] == APIResult.Failed) {
|
||||
let err = mfa_load_info[1] as APIError;
|
||||
logger.error(`mfa load failed: ${err.code} ${err.message}`);
|
||||
window.location.href = '/2fa';
|
||||
return;
|
||||
}
|
||||
|
||||
// pull networks
|
||||
const configuration = new Configuration({
|
||||
basePath: PUBLIC_BASE_URL,
|
||||
accessToken: window.localStorage.getItem("session") + " " + window.localStorage.getItem("mfa")
|
||||
});
|
||||
|
||||
const networksApi = new NetworksApi(configuration);
|
||||
let networks;
|
||||
try {
|
||||
networks = await networksApi.networksList();
|
||||
} catch (e) {
|
||||
let resp_json = await e.response.json();
|
||||
if (resp_json.errors[0].code == "ERR_NO_ORG") {
|
||||
window.location.href = "/networkcreate";
|
||||
return;
|
||||
} else {
|
||||
isError = true;
|
||||
error = $t("networkcreate.error.generic", {values:{err:resp_json.errors[0].code}});
|
||||
loading = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
console.log(networks);
|
||||
|
||||
if (networks.data?.length == 0) {
|
||||
window.location.href = '/networkcreate';
|
||||
return;
|
||||
}
|
||||
|
||||
network = networks.data![0].id;
|
||||
|
||||
const hostsApi = new HostsApi(configuration);
|
||||
hosts = (await hostsApi.hostsList({
|
||||
filterIsLighthouse: false,
|
||||
filterIsRelay: false
|
||||
})).data!;
|
||||
|
||||
console.log(hosts);
|
||||
|
||||
const rolesApi = new RolesApi(configuration);
|
||||
roles = (await rolesApi.rolesList()).data!;
|
||||
|
||||
loading = false;
|
||||
});
|
||||
|
||||
function getRoleName(byId: string): string {
|
||||
for (let i = 0; i < roles.length; i++) {
|
||||
if (roles[i].id == byId) {
|
||||
return roles[i].name!;
|
||||
}
|
||||
}
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
let hostName = "";
|
||||
let roleId = "";
|
||||
let ipAddr = "";
|
||||
|
||||
let hasFormErr = false;
|
||||
let formErr = "";
|
||||
|
||||
async function addHost() {
|
||||
hasFormErr = false;
|
||||
loading = true;
|
||||
|
||||
if (hostName == "") {
|
||||
formErr = $t("hosts.create.error.needsname");
|
||||
hasFormErr = true;
|
||||
loading = false;
|
||||
return;
|
||||
}
|
||||
if (roleId == "") {
|
||||
formErr = $t("hosts.create.error.needsrole");
|
||||
hasFormErr = true;
|
||||
loading = false;
|
||||
return;
|
||||
}
|
||||
|
||||
const re = /^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)\.?\b){4}$/;
|
||||
|
||||
// validate IP addr
|
||||
if (!ipAddr.match(re)) {
|
||||
formErr = $t("hosts.create.error.invalidip");
|
||||
hasFormErr = true;
|
||||
loading = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// all is good, actually create the host
|
||||
const configuration = new Configuration({
|
||||
basePath: PUBLIC_BASE_URL,
|
||||
accessToken: window.localStorage.getItem("session") + " " + window.localStorage.getItem("mfa")
|
||||
});
|
||||
const hostsApi = new HostsApi(configuration);
|
||||
try {
|
||||
await hostsApi.hostCreate({
|
||||
hostCreateRequest: {
|
||||
name: hostName,
|
||||
networkID: network,
|
||||
ipAddress: ipAddr,
|
||||
roleID: roleId
|
||||
}
|
||||
})
|
||||
} catch (e) {
|
||||
let body = await (<ResponseError>e).response.json();
|
||||
|
||||
console.log(body);
|
||||
|
||||
formErr = $t("hosts.create.error." + body.errors[0].code);
|
||||
hasFormErr = true;
|
||||
loading = false;
|
||||
|
||||
return;
|
||||
}
|
||||
window.location.href = "/hosts";
|
||||
}
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>{$t("common.title", {values: {title: $t("common.page.hosts")}})}</title>
|
||||
</svelte:head>
|
||||
|
||||
<LoadingWrapper isLoading={currentlyLoading} isError={isError} error={error}>
|
||||
<AdminLayout selected="hosts">
|
||||
<h3>{$t("common.page.addhost")}</h3>
|
||||
|
||||
<form on:submit|preventDefault={addHost}>
|
||||
<label for="name" class="form-label">{$t("hosts.create.name")}</label>
|
||||
<input type="text" id="name" bind:value={hostName} class="form-control" />
|
||||
|
||||
<label for="role" class="form-label">{$t("hosts.create.role")}</label>
|
||||
<select id="role" bind:value={roleId} class="form-select">
|
||||
{#each roles as role}
|
||||
<option value={role.id}>{role.name}</option>
|
||||
{/each}
|
||||
</select>
|
||||
|
||||
<label for="ip" class="form-label">{$t("hosts.create.ip")}</label>
|
||||
<input type="text" id="name" bind:value={ipAddr} class="form-control" />
|
||||
|
||||
{#if loading}
|
||||
<button disabled class="mt-2 btn btn-primary"><i class="fas fa-gear fa-spin"></i></button>
|
||||
{:else}
|
||||
<button class="mt-2 btn btn-primary">{$t("hosts.create.btn")}</button>
|
||||
{/if}
|
||||
<button class="mt-2 btn btn-outline-info">{$t("hosts.create.cancel")}</button>
|
||||
{#if hasFormErr}
|
||||
<p class="text-danger">{formErr}</p>
|
||||
{/if}
|
||||
</form>
|
||||
</AdminLayout>
|
||||
</LoadingWrapper>
|
Loading…
Reference in New Issue