Add RBAC support with roles, permissions, and session management. Implement middleware for authentication and CSRF protection. Enhance audit logging with additional fields. Update HTTP handlers and routes for new features.
This commit is contained in:
@@ -5,9 +5,20 @@
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<script src="https://unpkg.com/htmx.org@1.9.2"></script>
|
||||
<script>
|
||||
// HTMX CSRF token support
|
||||
document.body.addEventListener('htmx:configRequest', function(event) {
|
||||
const csrfToken = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content');
|
||||
if (csrfToken) {
|
||||
event.detail.headers['X-CSRF-Token'] = csrfToken;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<title>{{.Title}}</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet">
|
||||
<meta name="csrf-token" content="fake-csrf-token">
|
||||
{{if .CSRFToken}}
|
||||
<meta name="csrf-token" content="{{.CSRFToken}}">
|
||||
{{end}}
|
||||
</head>
|
||||
<body class="bg-gray-100">
|
||||
<main class="container mx-auto p-4">
|
||||
|
||||
32
internal/templates/hx_iscsi_luns.html
Normal file
32
internal/templates/hx_iscsi_luns.html
Normal file
@@ -0,0 +1,32 @@
|
||||
{{ define "hx_iscsi_luns" }}
|
||||
<div>
|
||||
<table class="w-full">
|
||||
<thead><tr><th>LUN ID</th><th>ZVol</th><th>Size</th><th>Action</th></tr></thead>
|
||||
<tbody>
|
||||
{{ if . }}
|
||||
{{ range . }}
|
||||
<tr>
|
||||
<td>{{ .lun_id }}</td>
|
||||
<td>{{ .zvol }}</td>
|
||||
<td>{{ .size }}</td>
|
||||
<td>
|
||||
<div>
|
||||
<form hx-post="/api/iscsi/unmap_lun" hx-include="closest form" style="display:inline-block">
|
||||
<input type="hidden" name="id" value="{{ .id }}" />
|
||||
<button type="submit">Drain</button>
|
||||
</form>
|
||||
<form hx-post="/api/iscsi/delete_lun" hx-include="closest form" style="display:inline-block">
|
||||
<input type="hidden" name="id" value="{{ .id }}" />
|
||||
<input type="checkbox" name="force" id="force-{{ .id }}" value="1" />
|
||||
<label for="force-{{ .id }}">Force delete</label>
|
||||
<button type="submit">Delete</button>
|
||||
</form>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{{ end }}
|
||||
18
internal/templates/hx_iscsi_target_info.html
Normal file
18
internal/templates/hx_iscsi_target_info.html
Normal file
@@ -0,0 +1,18 @@
|
||||
{{ define "hx_iscsi_target_info" }}
|
||||
<div>
|
||||
<h4>Initiator Connection</h4>
|
||||
<p>IQN: {{ .iqn }}</p>
|
||||
<h5>Portals</h5>
|
||||
<ul>
|
||||
{{ range .portals }}
|
||||
<li>{{ .address }}:{{ .port }}</li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
<h5>Allowed Initiators</h5>
|
||||
<ul>
|
||||
{{ range .initiators }}
|
||||
<li>{{ .iqn }}</li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
</div>
|
||||
{{ end }}
|
||||
19
internal/templates/hx_iscsi_targets.html
Normal file
19
internal/templates/hx_iscsi_targets.html
Normal file
@@ -0,0 +1,19 @@
|
||||
{{ define "hx_iscsi_targets" }}
|
||||
<table class="w-full">
|
||||
<thead><tr><th>Name</th><th>IQN</th><th>Action</th></tr></thead>
|
||||
<tbody>
|
||||
{{ if . }}
|
||||
{{ range . }}
|
||||
<tr>
|
||||
<td>{{ .name }}</td>
|
||||
<td>{{ .iqn }}</td>
|
||||
<td>
|
||||
<button hx-get="/api/iscsi/hx_luns/{{ .id }}">View LUNs</button>
|
||||
<button hx-get="/api/iscsi/target/{{ .id }}">Connection Info</button>
|
||||
</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
</tbody>
|
||||
</table>
|
||||
{{ end }}
|
||||
23
internal/templates/hx_nfs_shares.html
Normal file
23
internal/templates/hx_nfs_shares.html
Normal file
@@ -0,0 +1,23 @@
|
||||
{{define "hx_nfs_shares"}}
|
||||
<div>
|
||||
<table class="min-w-full bg-white">
|
||||
<thead>
|
||||
<tr><th>Name</th><th>Path</th><th>Type</th><th></th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{range .}}
|
||||
<tr class="border-t"><td>{{.Name}}</td><td>{{.Path}}</td><td>{{.Type}}</td>
|
||||
<td>
|
||||
<form hx-post="/shares/nfs/delete" hx-swap="outerHTML" class="inline">
|
||||
<input type="hidden" name="id" value="{{.ID}}" />
|
||||
<button class="px-2 py-1 bg-red-500 text-white rounded text-xs">Delete</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
{{else}}
|
||||
<tr><td colspan="4">No NFS shares</td></tr>
|
||||
{{end}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{{end}}
|
||||
23
internal/templates/hx_smb_shares.html
Normal file
23
internal/templates/hx_smb_shares.html
Normal file
@@ -0,0 +1,23 @@
|
||||
{{define "hx_smb_shares"}}
|
||||
<div>
|
||||
<table class="min-w-full bg-white">
|
||||
<thead>
|
||||
<tr><th>Name</th><th>Path</th><th>Type</th><th>Options</th><th></th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{range .}}
|
||||
<tr class="border-t"><td>{{.Name}}</td><td>{{.Path}}</td><td>{{.Type}}</td><td>{{range $k,$v := .Config}}{{$k}}={{$v}} {{end}}</td>
|
||||
<td>
|
||||
<form hx-post="/shares/smb/delete" hx-swap="outerHTML" class="inline">
|
||||
<input type="hidden" name="id" value="{{.ID}}" />
|
||||
<button class="px-2 py-1 bg-red-500 text-white rounded text-xs">Delete</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
{{else}}
|
||||
<tr><td colspan="5">No SMB shares</td></tr>
|
||||
{{end}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{{end}}
|
||||
23
internal/templates/iscsi.html
Normal file
23
internal/templates/iscsi.html
Normal file
@@ -0,0 +1,23 @@
|
||||
{{ define "iscsi" }}
|
||||
<div class="p-4">
|
||||
<h2 class="text-xl">iSCSI Targets</h2>
|
||||
<div hx-get="/api/iscsi/hx_targets" hx-swap="outerHTML"></div>
|
||||
<div class="mt-4">
|
||||
<h3>Create Target</h3>
|
||||
<form hx-post="/api/iscsi/create_target">
|
||||
<label>Name: <input type="text" name="name"/></label>
|
||||
<label>IQN: <input type="text" name="iqn"/></label>
|
||||
<button type="submit">Create Target</button>
|
||||
</form>
|
||||
</div>
|
||||
<div class="mt-4">
|
||||
<h3>Create LUN</h3>
|
||||
<form hx-post="/api/iscsi/create_lun">
|
||||
<label>Target ID: <input type="text" name="target_id"/></label>
|
||||
<label>ZVol path: <input type="text" name="zvol"/></label>
|
||||
<label>Size (e.g. 10G): <input type="text" name="size"/></label>
|
||||
<button type="submit">Create LUN</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
22
internal/templates/shares_nfs.html
Normal file
22
internal/templates/shares_nfs.html
Normal file
@@ -0,0 +1,22 @@
|
||||
{{define "content"}}
|
||||
<div class="bg-white rounded shadow p-4">
|
||||
<h1 class="text-2xl font-bold">NFS Shares</h1>
|
||||
<div class="mt-4">
|
||||
<button class="px-3 py-2 bg-blue-500 text-white rounded" hx-get="/hx/shares/nfs" hx-swap="outerHTML" hx-target="#nfs-shares">Refresh</button>
|
||||
</div>
|
||||
<div id="nfs-shares" class="mt-4">
|
||||
{{template "hx_nfs_shares" .}}
|
||||
</div>
|
||||
<div class="mt-6">
|
||||
<h2 class="text-lg font-semibold">Create NFS Share</h2>
|
||||
<form hx-post="/shares/nfs/create" hx-swap="afterbegin" class="mt-2">
|
||||
<div class="flex space-x-2">
|
||||
<input name="name" placeholder="share name" class="border rounded p-1" />
|
||||
<input name="path" placeholder="dataset (e.g. tank/ds)" class="border rounded p-1" />
|
||||
<input name="options" placeholder='{"clients":"*(rw)"}' class="border rounded p-1 w-64" />
|
||||
<button class="px-3 py-1 bg-green-500 text-white rounded" type="submit">Create</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
23
internal/templates/shares_smb.html
Normal file
23
internal/templates/shares_smb.html
Normal file
@@ -0,0 +1,23 @@
|
||||
{{define "content"}}
|
||||
<div class="bg-white rounded shadow p-4">
|
||||
<h1 class="text-2xl font-bold">SMB Shares</h1>
|
||||
<div class="mt-4">
|
||||
<button class="px-3 py-2 bg-blue-500 text-white rounded" hx-get="/hx/shares/smb" hx-swap="outerHTML" hx-target="#smb-shares">Refresh</button>
|
||||
</div>
|
||||
<div id="smb-shares" class="mt-4">
|
||||
{{template "hx_smb_shares" .}}
|
||||
</div>
|
||||
<div class="mt-6">
|
||||
<h2 class="text-lg font-semibold">Create SMB Share</h2>
|
||||
<form hx-post="/shares/smb/create" hx-swap="afterbegin" class="mt-2">
|
||||
<div class="flex space-x-2">
|
||||
<input name="name" placeholder="share name" class="border rounded p-1" />
|
||||
<input name="path" placeholder="dataset (e.g. tank/ds)" class="border rounded p-1" />
|
||||
<input name="allowed_users" placeholder="user1,user2" class="border rounded p-1" />
|
||||
<label class="text-sm">Read only <input type="checkbox" name="read_only" value="1" /></label>
|
||||
<button class="px-3 py-1 bg-green-500 text-white rounded" type="submit">Create</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
@@ -5,7 +5,7 @@
|
||||
<button class="px-3 py-2 bg-blue-500 text-white rounded" hx-get="/hx/pools" hx-swap="outerHTML" hx-target="#pools">Refresh pools</button>
|
||||
</div>
|
||||
<div id="pools" class="mt-4">
|
||||
{{template "hx_pools.html" .}}
|
||||
{{template "hx_pools" .}}
|
||||
</div>
|
||||
<div class="mt-6">
|
||||
<h2 class="text-lg font-semibold">Create Pool</h2>
|
||||
|
||||
Reference in New Issue
Block a user