3k release (#693)

This commit is contained in:
James Read 2025-11-06 00:44:19 +00:00 committed by GitHub
commit a67b5b4e8f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 115 additions and 42 deletions

2
.gitignore vendored
View File

@ -17,3 +17,5 @@ webui/
server.log
OliveTin
integration-tests/configs/authRequireGuestsToLogin/sessions.yaml
webui
webui.dev

View File

@ -5,21 +5,10 @@
# Listen on all addresses available, port 1337
listenAddressSingleHTTPFrontend: 0.0.0.0:1337
bannerMessage: "This is an early alpha version of OliveTin 3000. Many thanks are broken, many things will change."
bannerCss: "background-color: #b2e4b2; color: black; font-size: small; text-align: center; padding: .6em; border-radius: 0.5em;"
insecureAllowDumpSos: true
insecureAllowDumpVars: true
# Choose from INFO (default), WARN and DEBUG
# Docs: https://docs.olivetin.app/advanced_configuration/logs.html
logLevel: "INFO"
# Checking for updates https://docs.olivetin.app/reference/updateChecks.html
checkForUpdates: false
authLocalUsers:
enabled: true
# Actions are commands that are executed by OliveTin, and normally show up as
# buttons on the WebUI.
#
@ -55,6 +44,7 @@ actions:
# You can also rate-limit actions too.
- title: date
shell: date
id: date
timeout: 6
icon: clock
popupOnStart: execution-button
@ -322,3 +312,55 @@ dashboards:
- title: 'Start {{ .CurrentEntity.Names }}'
- title: 'Stop {{ .CurrentEntity.Names }}'
# Security - Authentication
# This setting effectively enables or disables guests.
# If set to "true", then users will have to login to do anything.
authRequireGuestsToLogin: false
# This form of auth is the simplest to setup - just define users and passwords
# in the config. OliveTin also supports header-based auth, OAuth2,
# and JWT authentication which are documented separately.
#
# Docs: https://docs.olivetin.app/security/local.html
#
# How to get a hashed password:
# Docs: https://docs.olivetin.app/security/local.html#_get_a_argon2id_hashed_password
authLocalUsers:
enabled: true
# users:
# - username: alice
# usergroup: admins
# password: "$argon2id$v=19$m=65536,t=4,p=2$puyxA0s555TSFx7hnFLCXA$PyhLGpZtvpMMvc2DgMWkM8OJMKO55euwV5gm//1iwx4"
# Security - Access Control
# Policies affect the whole app (eg: ability to view the log list).
# Docs: https://docs.olivetin.app/security/acl.html
defaultPolicy:
showDiagnostics: true
showLogList: true
# Permissions affect actions (eg: ability to view a specific log).
# Docs: https://docs.olivetin.app/security/acl.html
defaultPermissions:
view: true
exec: true
logs: true
# OliveTin uses access control lists to match up policy and permissions to users.
# Docs: https://docs.olivetin.app/security/acl.html
accessControlLists:
- name: admin_acl
matchUsergroups: ["admins"]
policy:
showDiagnostics: true
permissions:
view: true
exec: true
logs: true
# OliveTin contains many more configuration options not in this default config.
# Check out docs.olivetin.app for a setting if you feel like you're missing something.

View File

@ -17,7 +17,7 @@
"@xterm/addon-fit": "^0.10.0",
"@xterm/xterm": "^5.5.0",
"iconify-icon": "^3.0.2",
"picocrank": "^1.6.4",
"picocrank": "^1.8.0",
"unplugin-vue-components": "^30.0.0",
"vite": "^7.1.12",
"vue-router": "^4.6.3"
@ -2362,9 +2362,9 @@
"license": "ISC"
},
"node_modules/picocrank": {
"version": "1.6.4",
"resolved": "https://registry.npmjs.org/picocrank/-/picocrank-1.6.4.tgz",
"integrity": "sha512-zD1wnkoUDAXZOUs9zKqS4rqz9mljeqFwM7QWx4ykXJsmH6iOLAIKh2AVlxa384oeXJXIWM9VLiySEnhQZmQmjA==",
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/picocrank/-/picocrank-1.8.0.tgz",
"integrity": "sha512-YPGmXvw7vvjIcgrAe3io87kZDM+NUa+aiEYxk8CVqBzgI4koXeF+2VEGPHBwknZBBEbJfXsSdnxVwXrLKpWKfw==",
"license": "ISC",
"dependencies": {
"@hugeicons/core-free-icons": "^1.0.16",

View File

@ -30,7 +30,7 @@
"@xterm/addon-fit": "^0.10.0",
"@xterm/xterm": "^5.5.0",
"iconify-icon": "^3.0.2",
"picocrank": "^1.6.4",
"picocrank": "^1.8.0",
"unplugin-vue-components": "^30.0.0",
"vite": "^7.1.12",
"vue-router": "^4.6.3"

View File

@ -1,5 +1,5 @@
<template>
<Header title="OliveTin" :logoUrl="logoUrl" @toggleSidebar="toggleSidebar">
<Header title="OliveTin" :logoUrl="logoUrl" @toggleSidebar="toggleSidebar" :sidebarEnabled="showNavigation">
<template #toolbar>
<div id="banner" v-if="bannerMessage" :style="bannerCss">
<p>{{ bannerMessage }}</p>
@ -86,7 +86,9 @@ const initError = ref(false)
const initErrorMessage = ref('')
function toggleSidebar() {
if (sidebar.value && showNavigation.value) {
sidebar.value.toggle()
}
}
function updateHeaderFromInit() {
@ -132,6 +134,7 @@ async function requestInit() {
showLogs.value = initResponse.showLogList
showDiagnostics.value = initResponse.showDiagnostics
if (showNavigation.value && sidebar.value) {
for (const rootDashboard of initResponse.rootDashboards) {
sidebar.value.addNavigationLink({
id: rootDashboard,
@ -152,6 +155,7 @@ async function requestInit() {
if (showDiagnostics.value) {
sidebar.value.addRouterLink('Diagnostics')
}
}
hasLoaded.value = true;
initError.value = false;

View File

@ -11,8 +11,7 @@ plugins:
- remote: buf.build/bufbuild/es
out: ../frontend/resources/scripts/gen/
# - name: swagger
# out: reports/swagger
# - local: ["go", "run", "github.com/sudorandom/protoc-gen-connect-openapi@latest"]
# out: gen
# - local: protoc-gen-openapiv2
# out: reports/openapiv2

View File

@ -60,15 +60,38 @@ func GetAll() *variableBase {
}
func GetEntities() entitiesByClass {
return contents.Entities
rwmutex.RLock()
copiedEntities := make(entitiesByClass, len(contents.Entities))
for entityName, entityInstances := range contents.Entities {
copiedInstances := make(entityInstancesByKey, len(entityInstances))
for key, entity := range entityInstances {
copiedInstances[key] = entity
}
copiedEntities[entityName] = copiedInstances
}
rwmutex.RUnlock()
return copiedEntities
}
func GetEntityInstances(entityName string) entityInstancesByKey {
rwmutex.RLock()
defer rwmutex.RUnlock()
if entities, ok := contents.Entities[entityName]; ok {
return entities
copiedInstances := make(entityInstancesByKey, len(entities))
for key, entity := range entities {
copiedInstances[key] = entity
}
return copiedInstances
}
return nil
return make(entityInstancesByKey, 0)
}
func AddEntity(entityName string, entityKey string, data any) {

View File

@ -91,7 +91,7 @@ func ParseTemplateWithArgs(source string, ent *Entity, args map[string]string) s
}
templateVariables := &variableBase{
OliveTin: contents.OliveTin,
OliveTin: GetAll().OliveTin,
Arguments: args,
CurrentEntity: entdata,
}
@ -126,5 +126,8 @@ func ParseTemplateBoolWith(source string, ent *Entity) bool {
}
func ClearEntities(entityType string) {
rwmutex.Lock()
defer rwmutex.Unlock()
delete(contents.Entities, entityType)
}