update services and modes page

* start adding new service logic (empty server name, another operation name...)
* update services link logic for new service
* start adding operation and old_server_name fields on submit form
This commit is contained in:
Jordan Blasenhauer 2024-08-06 12:11:27 +02:00
parent d0e2ec69b7
commit c76234e6da
23 changed files with 241 additions and 121 deletions

View file

@ -4,7 +4,7 @@ import json
from .utils.form import get_forms, get_service_settings
def advanced_mode_builder(templates: list[dict], plugins: list, global_config: dict, total_config: dict, service_name: str) -> str:
def advanced_mode_builder(templates: list[dict], plugins: list, global_config: dict, total_config: dict, service_name: str, is_new: bool = False) -> str:
"""Render forms with global config data.
ATM we don't need templates but we need to pass at least one to the function (it will simply not override anything).
"""
@ -31,7 +31,9 @@ def advanced_mode_builder(templates: list[dict], plugins: list, global_config: d
{
"type": "Templates",
"data": {
"templates": get_forms(templates, plugins, settings, ("advanced",)),
"templates": get_forms(templates, plugins, settings, ("advanced",), is_new),
"operation": "new" if is_new else "edit",
"oldServerName": service_name if service_name else "",
},
},
],

View file

@ -4,7 +4,7 @@ import json
from .utils.form import get_forms, get_service_settings
def easy_mode_builder(templates: list[dict], plugins: list, global_config: dict, total_config: dict, service_name: str) -> str:
def easy_mode_builder(templates: list[dict], plugins: list, global_config: dict, total_config: dict, service_name: str, is_new: bool = False) -> str:
"""Render forms with global config data.
ATM we don't need templates but we need to pass at least one to the function (it will simply not override anything).
"""
@ -31,7 +31,9 @@ def easy_mode_builder(templates: list[dict], plugins: list, global_config: dict,
{
"type": "Templates",
"data": {
"templates": get_forms(templates, plugins, settings, ("easy",)),
"templates": get_forms(templates, plugins, settings, ("easy",), is_new),
"operation": "new" if is_new else "edit",
"oldServerName": service_name if service_name else "",
},
},
],

View file

@ -11,7 +11,7 @@ for deps_path in [join(sep, "usr", "share", "bunkerweb", *paths) for paths in ((
from builder.utils.form import get_forms, get_service_settings
def raw_mode_builder(templates: list[dict], plugins: list, global_config: dict, total_config: dict, service_name: str) -> str:
def raw_mode_builder(templates: list[dict], plugins: list, global_config: dict, total_config: dict, service_name: str, is_new: bool = False) -> str:
"""Render forms with global config data.
ATM we don't need templates but we need to pass at least one to the function (it will simply not override anything).
"""
@ -40,6 +40,8 @@ def raw_mode_builder(templates: list[dict], plugins: list, global_config: dict,
"type": "Templates",
"data": {
"templates": get_forms(templates, plugins, settings, ("raw",)),
"operation": "new" if is_new else "edit",
"oldServerName": service_name if service_name else "",
},
},
],

View file

@ -34,7 +34,7 @@ def services_builder(services):
"size": "normal",
"iconName": "plus",
"iconColor": "white",
"modal": services_action(server_name="new", operation="create", title="services_create_title", subtitle="services_create_subtitle"),
"modal": services_action(server_name="new", operation="new", title="services_new_title", subtitle="services_new_subtitle"),
"containerClass": "col-span-12 flex justify-center",
},
},
@ -258,7 +258,7 @@ def services_action(
}
)
if operation == "edit" or operation == "create":
if operation == "edit" or operation == "new":
modes = ("easy", "advanced", "raw")
mode_buttons = []
for mode in modes:
@ -271,7 +271,7 @@ def services_action(
"size": "normal",
"attrs": {
"role": "link",
"data-link": f"modes?service_name={server_name}&mode={mode}" if mode != "create" else f"modes?mode={mode}",
"data-link": f"modes?service_name={server_name}&mode={mode}" if operation != "new" else f"modes?mode={mode}",
},
},
)

View file

@ -24,7 +24,7 @@ def get_service_settings(service_name: str, global_config: dict, total_config: d
return global_config
def get_forms(templates: list = [], plugins: list = [], settings: dict = {}, render_forms: tuple = ("advanced", "easy", "raw")) -> dict:
def get_forms(templates: list = [], plugins: list = [], settings: dict = {}, render_forms: tuple = ("advanced", "easy", "raw"), is_new: bool = False) -> dict:
"""
Will generate every needed form using templates, plugins and settings.
We will run on each plugins, set template value if one, and override by the custom settings value if exists.
@ -36,18 +36,18 @@ def get_forms(templates: list = [], plugins: list = [], settings: dict = {}, ren
for template in templates:
if "advanced" in forms:
forms["advanced"][template.get("name")] = set_advanced(template, plugins, settings)
forms["advanced"][template.get("name")] = set_advanced(template, plugins, settings, is_new)
if "raw" in forms:
forms["raw"][template.get("name")] = set_raw(template, plugins, settings)
forms["raw"][template.get("name")] = set_raw(template, plugins, settings, is_new)
if "easy" in forms:
forms["easy"][template.get("name")] = set_easy(template, plugins, settings)
forms["easy"][template.get("name")] = set_easy(template, plugins, settings, is_new)
return forms
def set_easy(template: list, plugins_base: list, settings: dict) -> dict:
def set_easy(template: list, plugins_base: list, settings: dict, is_new: bool) -> dict:
"""
Prepare the easy form based on the template and plugins data.
We need to loop on each steps and prepare settings and configs for each step.
@ -77,14 +77,7 @@ def set_easy(template: list, plugins_base: list, settings: dict) -> dict:
plugin_setting = copy.deepcopy(plugin.get("settings").get(setting))
plugin_setting = format_setting(
setting,
plugin_setting,
len(step_settings),
loop_id,
template_settings,
settings,
)
plugin_setting = format_setting(setting, plugin_setting, len(step_settings), loop_id, template_settings, settings, is_new)
step_settings_output[setting] = plugin_setting
@ -93,7 +86,7 @@ def set_easy(template: list, plugins_base: list, settings: dict) -> dict:
return steps
def set_raw(template: list, plugins_base: list, settings: dict) -> dict:
def set_raw(template: list, plugins_base: list, settings: dict, is_new: bool) -> dict:
"""
Set the raw form based on the template and plugins data.
It consists of keeping only the value or default value for each plugin settings.
@ -128,15 +121,17 @@ def set_raw(template: list, plugins_base: list, settings: dict) -> dict:
if val != default_val:
raw_value = val
if setting == "SERVER_NAME" and is_new:
raw_value = ""
# Add value only if exists
if raw_value:
raw_settings[setting] = raw_value
print("raw_settings", raw_settings, flush=True)
return raw_settings
def set_advanced(template: list, plugins_base: list, settings: dict) -> dict:
def set_advanced(template: list, plugins_base: list, settings: dict, is_new: bool) -> dict:
"""
Set the advanced form based on the template and plugins data.
It consists of formatting each plugin settings to be used in the advanced form.
@ -150,14 +145,7 @@ def set_advanced(template: list, plugins_base: list, settings: dict) -> dict:
total_settings = len(plugin.get("settings"))
for setting, value in plugin.get("settings").items():
loop_id += 1
value = format_setting(
setting,
value,
total_settings,
loop_id,
template_settings,
settings,
)
value = format_setting(setting, value, total_settings, loop_id, template_settings, settings, is_new)
set_multiples(template, plugins, settings)
@ -352,6 +340,7 @@ def format_setting(
loop_id: Union[str, int],
template_settings: dict,
settings: dict,
is_new: bool = False,
) -> dict:
"""
Format a setting in order to be used with form builder.
@ -395,6 +384,9 @@ def format_setting(
# Update value or set default as value
setting_value["value"] = template_settings.get(setting_name, setting_value.get("default"))
if setting_name == "SERVER_NAME" and is_new:
setting_value["value"] = ""
# Then override by service settings if not a multiple
# Case multiple, we need to keep the default value and override only each multiple group
if setting_name in settings and not "multiple" in setting_value:
@ -406,7 +398,7 @@ def format_setting(
# Then override by service settings
if setting_name in settings:
setting_value["disabled"] = False if settings[setting_name].get("method", "ui") in ("ui", "default", "manual") else True
setting_value["disabled"] = False if settings[setting_name].get("method", "ui") in ("ui", "default", "manual") or is_new else True
# Prepare popover checking "help", "context"
popovers = []

View file

@ -45,6 +45,11 @@ import { v4 as uuidv4 } from "uuid";
* },
* ],
* }
* @param {object} template - Template object with plugin and settings data.
* @param {string} containerClass - Container
* @param {string} [operation="edit"] - Operation type (edit, new, delete).
* @param {string} [oldServerName=""] - Old server name. This is a server name before any changes.
* @param {object} columns - Columns object.
*/
const advancedForm = useAdvancedForm();
@ -61,6 +66,16 @@ const props = defineProps({
required: false,
default: "",
},
operation: {
type: String,
required: false,
default: "edit",
},
oldServerName: {
type: String,
required: false,
default: "",
},
columns: {
type: Object,
required: false,
@ -270,6 +285,8 @@ function getPluginNames(template) {
onMounted(() => {
// SetTemplate only if first time we mount it
advancedForm.setTemplate(props.template);
advancedForm.setOperation(props.operation);
advancedForm.setOldServerName(props.oldServerName);
updateStates();
// I want updatInp to access event, data.base and the container attribut
advancedForm.useListenTempFields();

View file

@ -40,8 +40,10 @@ import { useEasyForm } from "@store/form.js";
* },
* ],
* }
** @param {object} template - Template object with plugin and settings data.
* @param {object} template - Template object with plugin and settings data.
* @param {string} containerClass - Container
* @param {string} [operation="edit"] - Operation type (edit, new, delete).
* @param {string} [oldServerName=""] - Old server name. This is a server name before any changes.
* @param {object} columns - Columns object.
*/
@ -54,6 +56,16 @@ const props = defineProps({
required: true,
default: {},
},
operation: {
type: String,
required: false,
default: "edit",
},
oldServerName: {
type: String,
required: false,
default: "",
},
containerClass: {
type: String,
required: false,
@ -123,6 +135,8 @@ const buttonNext = {
onMounted(() => {
// Restart step one every time the component is mounted
easyForm.setTemplate(props.template);
easyForm.setOperation(props.operation);
easyForm.setOldServerName(props.oldServerName);
data.currStep = 0;
setValidity();
// I want updatInp to access event, data.base and the container attribut

View file

@ -21,6 +21,8 @@ import { useRawForm } from "@store/form.js";
* "MULTISITE": "yes"
* }
* @param {object} template - Template object with plugin and settings data.
* @param {string} [operation="edit"] - Operation type (edit, new, delete).
* @param {string} [oldServerName=""] - Old server name. This is a server name before any changes.
* @param {string} containerClass - Container
* @param {object} columns - Columns object.
*/
@ -34,6 +36,16 @@ const props = defineProps({
required: true,
default: {},
},
operation: {
type: String,
required: false,
default: "edit",
},
oldServerName: {
type: String,
required: false,
default: "",
},
containerClass: {
type: String,
required: false,
@ -151,6 +163,11 @@ const buttonSave = {
onBeforeMount(() => {
rawForm.setRawData(json2raw(props.template));
});
onMounted(() => {
rawForm.setOperation(props.operation);
rawForm.setOldServerName(props.oldServerName);
});
</script>
<template>

View file

@ -24,6 +24,8 @@ import { v4 as uuidv4 } from "uuid";
* }
* }
* @param {object} templates - List of advanced templates that contains settings. Must be a dict with mode as key, then the template name as key with a list of data (different for each modes).
* @param {string} [operation="edit"] - Operation type (edit, new, delete).
* @param {string} [oldServerName=""] - Old server name. This is a server name before any changes.
*/
const props = defineProps({
@ -32,6 +34,16 @@ const props = defineProps({
required: true,
default: {},
},
operation: {
type: String,
required: false,
default: "edit",
},
oldServerName: {
type: String,
required: false,
default: "",
},
});
const comboboxTemplate = {
@ -131,14 +143,20 @@ onBeforeMount(() => {
<Advanced
v-if="data.currModeName === 'advanced'"
:template="props.templates[data.currModeName][data.currTemplateName]"
:operation="props.operation"
:oldServerName="props.oldServerName"
/>
<Raw
v-if="data.currModeName === 'raw'"
:template="props.templates[data.currModeName][data.currTemplateName]"
:operation="props.operation"
:oldServerName="props.oldServerName"
/>
<Easy
v-if="data.currModeName === 'easy'"
:template="props.templates[data.currModeName][data.currTemplateName]"
:operation="props.operation"
:oldServerName="props.oldServerName"
/>
</Container>
</template>

View file

@ -87,7 +87,7 @@
"dashboard_status_warning": "status warning or alert.",
"dashboard_status_info": "status loading or waiting or unknown.",
"dashboard_raw_mode": "raw mode",
"dashboard_raw_mode_subtitle": "Raw mode shows settings as raw key-value pairs of settings (disabled and default ones exclude).",
"dashboard_raw_mode_subtitle": "Raw mode shows settings as raw key-value pairs of settings (disabled ones will be shown but not updated on save).",
"dashboard_raw_invalid": "RAW format is invalid",
"dashboard_advanced_mode": "Advanced mode",
"dashboard_advanced_mode_subtitle": "Advanced mode show settings by plugin in dedicated fields.",
@ -280,8 +280,8 @@
"services_plugins_title": "Details",
"services_edit_title": "Edit",
"services_edit_subtitle": "Choose a mode to edit service",
"services_create_title": "create service",
"services_create_subtitle": "Choose a mode to create a new service",
"services_new_title": "new service",
"services_new_subtitle": "Choose a mode to create a new service",
"services_mode_easy": "Easy mode",
"services_mode_raw": "Raw mode",
"services_mode_advanced": "Advanced mode",
@ -297,6 +297,5 @@
"services_settings_table_status": "Status",
"services_mode_title": "Service mode",
"services_mode_subtitle": "Manage your service settings.",
"services_manage_title": "Service {service_name}",
"services_manage_subtitle": "Manage your service settings."
}

View file

@ -16,7 +16,7 @@
></div>
<div
class="hidden"
data-server-builder="W3sidHlwZSI6ICJjYXJkIiwgImNvbnRhaW5lckNvbHVtbnMiOiB7InBjIjogMTIsICJ0YWJsZXQiOiAxMiwgIm1vYmlsZSI6IDEyfSwgIndpZGdldHMiOiBbeyJ0eXBlIjogIlRpdGxlIiwgImRhdGEiOiB7InRpdGxlIjogImFwcDEuZXhhbXBsZS5jb20iLCAidHlwZSI6ICJjb250YWluZXIiLCAibG93ZXJjYXNlIjogdHJ1ZX19LCB7InR5cGUiOiAiU3VidGl0bGUiLCAiZGF0YSI6IHsic3VidGl0bGUiOiAic2VydmljZXNfbWFuYWdlX3N1YnRpdGxlIiwgInR5cGUiOiAiY29udGFpbmVyIiwgInN1YnRpdGxlQ2xhc3MiOiAibWItNCJ9fSwgeyJ0eXBlIjogIlRlbXBsYXRlcyIsICJkYXRhIjogeyJ0ZW1wbGF0ZXMiOiB7InJhdyI6IHsiZGVmYXVsdCI6IHt9fX19fV19XQ=="
data-server-builder="W3sidHlwZSI6ICJjYXJkIiwgImNvbnRhaW5lckNvbHVtbnMiOiB7InBjIjogMTIsICJ0YWJsZXQiOiAxMiwgIm1vYmlsZSI6IDEyfSwgIndpZGdldHMiOiBbeyJ0eXBlIjogIlRpdGxlIiwgImRhdGEiOiB7InRpdGxlIjogImFwcDEuZXhhbXBsZS5jb20iLCAidHlwZSI6ICJjb250YWluZXIiLCAibG93ZXJjYXNlIjogdHJ1ZX19LCB7InR5cGUiOiAiU3VidGl0bGUiLCAiZGF0YSI6IHsic3VidGl0bGUiOiAic2VydmljZXNfbWFuYWdlX3N1YnRpdGxlIiwgInR5cGUiOiAiY29udGFpbmVyIiwgInN1YnRpdGxlQ2xhc3MiOiAibWItNCJ9fSwgeyJ0eXBlIjogIlRlbXBsYXRlcyIsICJkYXRhIjogeyJ0ZW1wbGF0ZXMiOiB7InJhdyI6IHsiZGVmYXVsdCI6IHsiTVVMVElTSVRFIjogInllcyIsICJTRVJWRVJfTkFNRSI6ICJhcHAxLmV4YW1wbGUuY29tIiwgIkxPR19MRVZFTCI6ICJpbmZvIiwgIkFQSV9XSElURUxJU1RfSVAiOiAiMTI3LjAuMC4wLzI0IDEwLjIwLjMwLjAvMjQiLCAiQlVOS0VSV0VCX0lOU1RBTkNFUyI6ICJidW5rZXJ3ZWIiLCAiVVNFX0JMQUNLTElTVCI6ICJubyIsICJVU0VfQlVOS0VSTkVUIjogIm5vIiwgIkNPUlNfQUxMT1dfT1JJR0lOIjogInNlbGYiLCAiQ1JPU1NfT1JJR0lOX09QRU5FUl9QT0xJQ1kiOiAic2FtZS1vcmlnaW4iLCAiQ1JPU1NfT1JJR0lOX0VNQkVEREVSX1BPTElDWSI6ICJyZXF1aXJlLWNvcnAiLCAiQ1JPU1NfT1JJR0lOX1JFU09VUkNFX1BPTElDWSI6ICJzYW1lLXNpdGUiLCAiVVNFX0NMSUVOVF9DQUNIRSI6ICJ5ZXMiLCAiVVNFX0daSVAiOiAieWVzIiwgIlJFTU9WRV9IRUFERVJTIjogIlNlcnZlciBFeHBlY3QtQ1QgWC1Qb3dlcmVkLUJ5IFgtQXNwTmV0LVZlcnNpb24gWC1Bc3BOZXRNdmMtVmVyc2lvbiBQdWJsaWMtS2V5LVBpbnMiLCAiS0VFUF9VUFNUUkVBTV9IRUFERVJTIjogIkNvbnRlbnQtU2VjdXJpdHktUG9saWN5IFBlcm1pc3Npb25zLVBvbGljeSBYLUZyYW1lLU9wdGlvbnMiLCAiU1RSSUNUX1RSQU5TUE9SVF9TRUNVUklUWSI6ICJtYXgtYWdlPTMxNTM2MDAwOyBpbmNsdWRlU3ViRG9tYWluczsgcHJlbG9hZCIsICJQRVJNSVNTSU9OU19QT0xJQ1kiOiAiYWNjZWxlcm9tZXRlcj0oKSwgYW1iaWVudC1saWdodC1zZW5zb3I9KCksIGF0dHJpYnV0aW9uLXJlcG9ydGluZz0oKSwgYXV0b3BsYXk9KCksIGJhdHRlcnk9KCksIGJsdWV0b290aD0oKSwgYnJvd3NpbmctdG9waWNzPSgpLCBjYW1lcmE9KCksIGNvbXB1dGUtcHJlc3N1cmU9KCksIGRpc3BsYXktY2FwdHVyZT0oKSwgZG9jdW1lbnQtZG9tYWluPSgpLCBlbmNyeXB0ZWQtbWVkaWE9KCksIGV4ZWN1dGlvbi13aGlsZS1ub3QtcmVuZGVyZWQ9KCksIGV4ZWN1dGlvbi13aGlsZS1vdXQtb2Ytdmlld3BvcnQ9KCksIGZ1bGxzY3JlZW49KCksIGdhbWVwYWQ9KCksIGdlb2xvY2F0aW9uPSgpLCBneXJvc2NvcGU9KCksIGhpZD0oKSwgaWRlbnRpdHktY3JlZGVudGlhbHMtZ2V0PSgpLCBpZGxlLWRldGVjdGlvbj0oKSwgbG9jYWwtZm9udHM9KCksIG1hZ25ldG9tZXRlcj0oKSwgbWljcm9waG9uZT0oKSwgbWlkaT0oKSwgb3RwLWNyZWRlbnRpYWxzPSgpLCBwYXltZW50PSgpLCBwaWN0dXJlLWluLXBpY3R1cmU9KCksIHB1YmxpY2tleS1jcmVkZW50aWFscy1jcmVhdGU9KCksIHB1YmxpY2tleS1jcmVkZW50aWFscy1nZXQ9KCksIHNjcmVlbi13YWtlLWxvY2s9KCksIHNlcmlhbD0oKSwgc3BlYWtlci1zZWxlY3Rpb249KCksIHN0b3JhZ2UtYWNjZXNzPSgpLCB1c2I9KCksIHdlYi1zaGFyZT0oKSwgd2luZG93LW1hbmFnZW1lbnQ9KCksIHhyLXNwYXRpYWwtdHJhY2tpbmc9KCkiLCAiRElTQUJMRV9ERUZBVUxUX1NFUlZFUiI6ICJ5ZXMiLCAiU0VSVkVfRklMRVMiOiAibm8iLCAiU0VORF9BTk9OWU1PVVNfUkVQT1JUIjogIm5vIiwgIk1PRFNFQ1VSSVRZX0NSU19WRVJTSU9OIjogIjQiLCAiVVNFX1JFVkVSU0VfUFJPWFkiOiAieWVzIiwgIlJFVkVSU0VfUFJPWFlfSE9TVCI6ICJodHRwOi8vYXBwMTo4MDgwIiwgIlVTRV9XSElURUxJU1QiOiAibm8ifX19LCAib3BlcmF0aW9uIjogImVkaXQiLCAib2xkX3NlcnZpY2VfbmFtZSI6ICIifX1dfV0"
></div>
<div id="app"></div>
<script type="module" src="modes.js"></script>

File diff suppressed because one or more lines are too long

View file

@ -32,6 +32,29 @@ export const createFormStore = (storeName, formType) => {
const isUpdateData = ref(false);
// Data we gonna submit
const formattedData = ref({});
// Get additionnal data for submit
const operation = ref("");
const oldServerName = ref("");
/**
* @name setOperation
* @description Set the operation when we will submit the form.
* @param {string} operation - Operation to set
* @returns {void}
*/
function setOperation(value) {
operation.value = value;
}
/**
* @name setOldServerName
* @description Set the operation when we will submit the form.
* @param {string} oldServeName - old server name to set
* @returns {void}
*/
function setOldServerName(value) {
oldServerName.value = value;
}
/**
* @name setTemplate
@ -49,6 +72,7 @@ export const createFormStore = (storeName, formType) => {
templateUI.value = JSON.parse(JSON.stringify(tempData));
templateUIFormat.value = templateUI.value;
_updateTempState();
console.log("format", formattedData.value);
}
/**
@ -328,7 +352,11 @@ export const createFormStore = (storeName, formType) => {
if (!_isFormTypeAllowed(["advanced", "easy", "raw"])) return;
_updateTempState();
if (!isUpdateData.value) return;
return useSubmitForm(formattedData.value);
data = JSON.parse(JSON.stringify(formattedData.value));
data["operation"] = operation.value;
data["OLD_SERVER_NAME"] = oldServerName.value;
print(data);
}
/**
@ -434,6 +462,8 @@ export const createFormStore = (storeName, formType) => {
isUpdateData,
setTemplate,
setRawData,
setOldServerName,
setOperation,
addMultiple,
delMultiple,
useListenTempFields,

View file

@ -4,7 +4,7 @@ import json
from .utils.form import get_forms, get_service_settings
def advanced_mode_builder(templates: list[dict], plugins: list, global_config: dict, total_config: dict, service_name: str) -> str:
def advanced_mode_builder(templates: list[dict], plugins: list, global_config: dict, total_config: dict, service_name: str, is_new: bool = False) -> str:
"""Render forms with global config data.
ATM we don't need templates but we need to pass at least one to the function (it will simply not override anything).
"""
@ -31,10 +31,12 @@ def advanced_mode_builder(templates: list[dict], plugins: list, global_config: d
{
"type": "Templates",
"data": {
"templates": get_forms(templates, plugins, settings, ("advanced",)),
"templates": get_forms(templates, plugins, settings, ("advanced",), is_new),
"operation": "new" if is_new else "edit",
"old_service_name": service_name if not service_name else "",
},
},
],
}
]
return builder
return base64.b64encode(bytes(json.dumps(builder), "utf-8")).decode("ascii")

View file

@ -4,7 +4,7 @@ import json
from .utils.form import get_forms, get_service_settings
def easy_mode_builder(templates: list[dict], plugins: list, global_config: dict, total_config: dict, service_name: str) -> str:
def easy_mode_builder(templates: list[dict], plugins: list, global_config: dict, total_config: dict, service_name: str, is_new: bool = False) -> str:
"""Render forms with global config data.
ATM we don't need templates but we need to pass at least one to the function (it will simply not override anything).
"""
@ -31,10 +31,12 @@ def easy_mode_builder(templates: list[dict], plugins: list, global_config: dict,
{
"type": "Templates",
"data": {
"templates": get_forms(templates, plugins, settings, ("easy",)),
"templates": get_forms(templates, plugins, settings, ("easy",), is_new),
"operation": "new" if is_new else "edit",
"old_service_name": service_name if not service_name else "",
},
},
],
}
]
return builder
return base64.b64encode(bytes(json.dumps(builder), "utf-8")).decode("ascii")

View file

@ -4,13 +4,14 @@ import json
from .utils.form import get_forms, get_service_settings
def raw_mode_builder(templates: list[dict], plugins: list, global_config: dict, total_config: dict, service_name: str) -> str:
def raw_mode_builder(templates: list[dict], plugins: list, global_config: dict, total_config: dict, service_name: str, is_new: bool = False) -> str:
"""Render forms with global config data.
ATM we don't need templates but we need to pass at least one to the function (it will simply not override anything).
"""
# We need
settings = get_service_settings(service_name, global_config, total_config)
builder = [
{
"type": "card",
@ -32,6 +33,8 @@ def raw_mode_builder(templates: list[dict], plugins: list, global_config: dict,
"type": "Templates",
"data": {
"templates": get_forms(templates, plugins, settings, ("raw",)),
"operation": "new" if is_new else "edit",
"old_service_name": service_name if not service_name else "",
},
},
],

View file

@ -26,7 +26,7 @@ def services_builder(services):
"size": "normal",
"iconName": "plus",
"iconColor": "white",
"modal": services_action(server_name="new", operation="create", title="services_create_title", subtitle="services_create_subtitle"),
"modal": services_action(server_name="new", operation="new", title="services_new_title", subtitle="services_new_subtitle"),
"containerClass": "col-span-12 flex justify-center",
},
},
@ -114,7 +114,7 @@ def services_builder(services):
},
]
return base64.b64encode(bytes(json.dumps(builder), "utf-8")).decode("ascii")
return builder
def services_settings(settings: dict) -> dict:
@ -250,7 +250,7 @@ def services_action(
}
)
if operation == "edit" or operation == "create":
if operation == "edit" or operation == "new":
modes = ("easy", "advanced", "raw")
mode_buttons = []
for mode in modes:
@ -263,7 +263,7 @@ def services_action(
"size": "normal",
"attrs": {
"role": "link",
"data-link": f"modes?service_name={server_name}&mode={mode}" if mode != "create" else f"modes?mode={mode}",
"data-link": f"modes?service_name={server_name}&mode={mode}" if operation != "new" else f"modes?mode={mode}",
},
},
)

View file

@ -24,7 +24,7 @@ def get_service_settings(service_name: str, global_config: dict, total_config: d
return global_config
def get_forms(templates: list = [], plugins: list = [], settings: dict = {}, render_forms: tuple = ("advanced", "easy", "raw")) -> dict:
def get_forms(templates: list = [], plugins: list = [], settings: dict = {}, render_forms: tuple = ("advanced", "easy", "raw"), is_new: bool = False) -> dict:
"""
Will generate every needed form using templates, plugins and settings.
We will run on each plugins, set template value if one, and override by the custom settings value if exists.
@ -36,18 +36,18 @@ def get_forms(templates: list = [], plugins: list = [], settings: dict = {}, ren
for template in templates:
if "advanced" in forms:
forms["advanced"][template.get("name")] = set_advanced(template, plugins, settings)
forms["advanced"][template.get("name")] = set_advanced(template, plugins, settings, is_new)
if "raw" in forms:
forms["raw"][template.get("name")] = set_raw(template, plugins, settings)
forms["raw"][template.get("name")] = set_raw(template, plugins, settings, is_new)
if "easy" in forms:
forms["easy"][template.get("name")] = set_easy(template, plugins, settings)
forms["easy"][template.get("name")] = set_easy(template, plugins, settings, is_new)
return forms
def set_easy(template: list, plugins_base: list, settings: dict) -> dict:
def set_easy(template: list, plugins_base: list, settings: dict, is_new: bool) -> dict:
"""
Prepare the easy form based on the template and plugins data.
We need to loop on each steps and prepare settings and configs for each step.
@ -77,14 +77,7 @@ def set_easy(template: list, plugins_base: list, settings: dict) -> dict:
plugin_setting = copy.deepcopy(plugin.get("settings").get(setting))
plugin_setting = format_setting(
setting,
plugin_setting,
len(step_settings),
loop_id,
template_settings,
settings,
)
plugin_setting = format_setting(setting, plugin_setting, len(step_settings), loop_id, template_settings, settings, is_new)
step_settings_output[setting] = plugin_setting
@ -93,7 +86,7 @@ def set_easy(template: list, plugins_base: list, settings: dict) -> dict:
return steps
def set_raw(template: list, plugins_base: list, settings: dict) -> dict:
def set_raw(template: list, plugins_base: list, settings: dict, is_new: bool) -> dict:
"""
Set the raw form based on the template and plugins data.
It consists of keeping only the value or default value for each plugin settings.
@ -128,15 +121,17 @@ def set_raw(template: list, plugins_base: list, settings: dict) -> dict:
if val != default_val:
raw_value = val
if setting == "SERVER_NAME" and is_new:
raw_value = ""
# Add value only if exists
if raw_value:
raw_settings[setting] = raw_value
print("raw_settings", raw_settings, flush=True)
return raw_settings
def set_advanced(template: list, plugins_base: list, settings: dict) -> dict:
def set_advanced(template: list, plugins_base: list, settings: dict, is_new: bool) -> dict:
"""
Set the advanced form based on the template and plugins data.
It consists of formatting each plugin settings to be used in the advanced form.
@ -150,14 +145,7 @@ def set_advanced(template: list, plugins_base: list, settings: dict) -> dict:
total_settings = len(plugin.get("settings"))
for setting, value in plugin.get("settings").items():
loop_id += 1
value = format_setting(
setting,
value,
total_settings,
loop_id,
template_settings,
settings,
)
value = format_setting(setting, value, total_settings, loop_id, template_settings, settings, is_new)
set_multiples(template, plugins, settings)
@ -352,6 +340,7 @@ def format_setting(
loop_id: Union[str, int],
template_settings: dict,
settings: dict,
is_new: bool = False,
) -> dict:
"""
Format a setting in order to be used with form builder.
@ -395,6 +384,9 @@ def format_setting(
# Update value or set default as value
setting_value["value"] = template_settings.get(setting_name, setting_value.get("default"))
if setting_name == "SERVER_NAME" and is_new:
setting_value["value"] = ""
# Then override by service settings if not a multiple
# Case multiple, we need to keep the default value and override only each multiple group
if setting_name in settings and not "multiple" in setting_value:
@ -406,7 +398,7 @@ def format_setting(
# Then override by service settings
if setting_name in settings:
setting_value["disabled"] = False if settings[setting_name].get("method", "ui") in ("ui", "default", "manual") else True
setting_value["disabled"] = False if settings[setting_name].get("method", "ui") in ("ui", "default", "manual") or is_new else True
# Prepare popover checking "help", "context"
popovers = []

View file

@ -29,19 +29,34 @@
"templates": {
"raw": {
"default": {
"SERVER_NAME": "app1.example.com",
"MULTISITE": "yes",
"LOG_LEVEL": "info",
"API_WHITELIST_IP": "127.0.0.0/24 10.20.30.0/24",
"BUNKERWEB_INSTANCES": "bunkerweb",
"USE_BLACKLIST": "no",
"USE_BUNKERNET": "no",
"CORS_ALLOW_ORIGIN": "self",
"CROSS_ORIGIN_OPENER_POLICY": "same-origin",
"CROSS_ORIGIN_EMBEDDER_POLICY": "require-corp",
"CROSS_ORIGIN_RESOURCE_POLICY": "same-site",
"USE_CLIENT_CACHE": "yes",
"USE_GZIP": "yes",
"REMOVE_HEADERS": "Server Expect-CT X-Powered-By X-AspNet-Version X-AspNetMvc-Version Public-Key-Pins",
"KEEP_UPSTREAM_HEADERS": "Content-Security-Policy Permissions-Policy X-Frame-Options",
"STRICT_TRANSPORT_SECURITY": "max-age=31536000; includeSubDomains; preload",
"PERMISSIONS_POLICY": "accelerometer=(), ambient-light-sensor=(), attribution-reporting=(), autoplay=(), battery=(), bluetooth=(), browsing-topics=(), camera=(), compute-pressure=(), display-capture=(), document-domain=(), encrypted-media=(), execution-while-not-rendered=(), execution-while-out-of-viewport=(), fullscreen=(), gamepad=(), geolocation=(), gyroscope=(), hid=(), identity-credentials-get=(), idle-detection=(), local-fonts=(), magnetometer=(), microphone=(), midi=(), otp-credentials=(), payment=(), picture-in-picture=(), publickey-credentials-create=(), publickey-credentials-get=(), screen-wake-lock=(), serial=(), speaker-selection=(), storage-access=(), usb=(), web-share=(), window-management=(), xr-spatial-tracking=()",
"MODSECURITY_CRS_VERSION": "4"
"DISABLE_DEFAULT_SERVER": "yes",
"SERVE_FILES": "no",
"SEND_ANONYMOUS_REPORT": "no",
"MODSECURITY_CRS_VERSION": "4",
"USE_REVERSE_PROXY": "yes",
"REVERSE_PROXY_HOST": "http://app1:8080",
"USE_WHITELIST": "no"
}
}
}
},
"operation": "edit",
"old_service_name": ""
}
}
]

View file

@ -1 +1 @@
W3sidHlwZSI6ICJjYXJkIiwgImNvbnRhaW5lckNvbHVtbnMiOiB7InBjIjogMTIsICJ0YWJsZXQiOiAxMiwgIm1vYmlsZSI6IDEyfSwgIndpZGdldHMiOiBbeyJ0eXBlIjogIlRpdGxlIiwgImRhdGEiOiB7InRpdGxlIjogImFwcDEuZXhhbXBsZS5jb20iLCAidHlwZSI6ICJjb250YWluZXIiLCAibG93ZXJjYXNlIjogdHJ1ZX19LCB7InR5cGUiOiAiU3VidGl0bGUiLCAiZGF0YSI6IHsic3VidGl0bGUiOiAic2VydmljZXNfbWFuYWdlX3N1YnRpdGxlIiwgInR5cGUiOiAiY29udGFpbmVyIiwgInN1YnRpdGxlQ2xhc3MiOiAibWItNCJ9fSwgeyJ0eXBlIjogIlRlbXBsYXRlcyIsICJkYXRhIjogeyJ0ZW1wbGF0ZXMiOiB7InJhdyI6IHsiZGVmYXVsdCI6IHsiU0VSVkVSX05BTUUiOiAiYXBwMS5leGFtcGxlLmNvbSIsICJDT1JTX0FMTE9XX09SSUdJTiI6ICJzZWxmIiwgIkNST1NTX09SSUdJTl9PUEVORVJfUE9MSUNZIjogInNhbWUtb3JpZ2luIiwgIkNST1NTX09SSUdJTl9FTUJFRERFUl9QT0xJQ1kiOiAicmVxdWlyZS1jb3JwIiwgIkNST1NTX09SSUdJTl9SRVNPVVJDRV9QT0xJQ1kiOiAic2FtZS1zaXRlIiwgIlJFTU9WRV9IRUFERVJTIjogIlNlcnZlciBFeHBlY3QtQ1QgWC1Qb3dlcmVkLUJ5IFgtQXNwTmV0LVZlcnNpb24gWC1Bc3BOZXRNdmMtVmVyc2lvbiBQdWJsaWMtS2V5LVBpbnMiLCAiS0VFUF9VUFNUUkVBTV9IRUFERVJTIjogIkNvbnRlbnQtU2VjdXJpdHktUG9saWN5IFBlcm1pc3Npb25zLVBvbGljeSBYLUZyYW1lLU9wdGlvbnMiLCAiU1RSSUNUX1RSQU5TUE9SVF9TRUNVUklUWSI6ICJtYXgtYWdlPTMxNTM2MDAwOyBpbmNsdWRlU3ViRG9tYWluczsgcHJlbG9hZCIsICJQRVJNSVNTSU9OU19QT0xJQ1kiOiAiYWNjZWxlcm9tZXRlcj0oKSwgYW1iaWVudC1saWdodC1zZW5zb3I9KCksIGF0dHJpYnV0aW9uLXJlcG9ydGluZz0oKSwgYXV0b3BsYXk9KCksIGJhdHRlcnk9KCksIGJsdWV0b290aD0oKSwgYnJvd3NpbmctdG9waWNzPSgpLCBjYW1lcmE9KCksIGNvbXB1dGUtcHJlc3N1cmU9KCksIGRpc3BsYXktY2FwdHVyZT0oKSwgZG9jdW1lbnQtZG9tYWluPSgpLCBlbmNyeXB0ZWQtbWVkaWE9KCksIGV4ZWN1dGlvbi13aGlsZS1ub3QtcmVuZGVyZWQ9KCksIGV4ZWN1dGlvbi13aGlsZS1vdXQtb2Ytdmlld3BvcnQ9KCksIGZ1bGxzY3JlZW49KCksIGdhbWVwYWQ9KCksIGdlb2xvY2F0aW9uPSgpLCBneXJvc2NvcGU9KCksIGhpZD0oKSwgaWRlbnRpdHktY3JlZGVudGlhbHMtZ2V0PSgpLCBpZGxlLWRldGVjdGlvbj0oKSwgbG9jYWwtZm9udHM9KCksIG1hZ25ldG9tZXRlcj0oKSwgbWljcm9waG9uZT0oKSwgbWlkaT0oKSwgb3RwLWNyZWRlbnRpYWxzPSgpLCBwYXltZW50PSgpLCBwaWN0dXJlLWluLXBpY3R1cmU9KCksIHB1YmxpY2tleS1jcmVkZW50aWFscy1jcmVhdGU9KCksIHB1YmxpY2tleS1jcmVkZW50aWFscy1nZXQ9KCksIHNjcmVlbi13YWtlLWxvY2s9KCksIHNlcmlhbD0oKSwgc3BlYWtlci1zZWxlY3Rpb249KCksIHN0b3JhZ2UtYWNjZXNzPSgpLCB1c2I9KCksIHdlYi1zaGFyZT0oKSwgd2luZG93LW1hbmFnZW1lbnQ9KCksIHhyLXNwYXRpYWwtdHJhY2tpbmc9KCkiLCAiTU9EU0VDVVJJVFlfQ1JTX1ZFUlNJT04iOiAiNCJ9fX19fV19XQ==
W3sidHlwZSI6ICJjYXJkIiwgImNvbnRhaW5lckNvbHVtbnMiOiB7InBjIjogMTIsICJ0YWJsZXQiOiAxMiwgIm1vYmlsZSI6IDEyfSwgIndpZGdldHMiOiBbeyJ0eXBlIjogIlRpdGxlIiwgImRhdGEiOiB7InRpdGxlIjogImFwcDEuZXhhbXBsZS5jb20iLCAidHlwZSI6ICJjb250YWluZXIiLCAibG93ZXJjYXNlIjogdHJ1ZX19LCB7InR5cGUiOiAiU3VidGl0bGUiLCAiZGF0YSI6IHsic3VidGl0bGUiOiAic2VydmljZXNfbWFuYWdlX3N1YnRpdGxlIiwgInR5cGUiOiAiY29udGFpbmVyIiwgInN1YnRpdGxlQ2xhc3MiOiAibWItNCJ9fSwgeyJ0eXBlIjogIlRlbXBsYXRlcyIsICJkYXRhIjogeyJ0ZW1wbGF0ZXMiOiB7InJhdyI6IHsiZGVmYXVsdCI6IHsiTVVMVElTSVRFIjogInllcyIsICJMT0dfTEVWRUwiOiAiaW5mbyIsICJBUElfV0hJVEVMSVNUX0lQIjogIjEyNy4wLjAuMC8yNCAxMC4yMC4zMC4wLzI0IiwgIkJVTktFUldFQl9JTlNUQU5DRVMiOiAiYnVua2Vyd2ViIiwgIlVTRV9CTEFDS0xJU1QiOiAibm8iLCAiVVNFX0JVTktFUk5FVCI6ICJubyIsICJDT1JTX0FMTE9XX09SSUdJTiI6ICJzZWxmIiwgIkNST1NTX09SSUdJTl9PUEVORVJfUE9MSUNZIjogInNhbWUtb3JpZ2luIiwgIkNST1NTX09SSUdJTl9FTUJFRERFUl9QT0xJQ1kiOiAicmVxdWlyZS1jb3JwIiwgIkNST1NTX09SSUdJTl9SRVNPVVJDRV9QT0xJQ1kiOiAic2FtZS1zaXRlIiwgIlVTRV9DTElFTlRfQ0FDSEUiOiAieWVzIiwgIlVTRV9HWklQIjogInllcyIsICJSRU1PVkVfSEVBREVSUyI6ICJTZXJ2ZXIgRXhwZWN0LUNUIFgtUG93ZXJlZC1CeSBYLUFzcE5ldC1WZXJzaW9uIFgtQXNwTmV0TXZjLVZlcnNpb24gUHVibGljLUtleS1QaW5zIiwgIktFRVBfVVBTVFJFQU1fSEVBREVSUyI6ICJDb250ZW50LVNlY3VyaXR5LVBvbGljeSBQZXJtaXNzaW9ucy1Qb2xpY3kgWC1GcmFtZS1PcHRpb25zIiwgIlNUUklDVF9UUkFOU1BPUlRfU0VDVVJJVFkiOiAibWF4LWFnZT0zMTUzNjAwMDsgaW5jbHVkZVN1YkRvbWFpbnM7IHByZWxvYWQiLCAiUEVSTUlTU0lPTlNfUE9MSUNZIjogImFjY2VsZXJvbWV0ZXI9KCksIGFtYmllbnQtbGlnaHQtc2Vuc29yPSgpLCBhdHRyaWJ1dGlvbi1yZXBvcnRpbmc9KCksIGF1dG9wbGF5PSgpLCBiYXR0ZXJ5PSgpLCBibHVldG9vdGg9KCksIGJyb3dzaW5nLXRvcGljcz0oKSwgY2FtZXJhPSgpLCBjb21wdXRlLXByZXNzdXJlPSgpLCBkaXNwbGF5LWNhcHR1cmU9KCksIGRvY3VtZW50LWRvbWFpbj0oKSwgZW5jcnlwdGVkLW1lZGlhPSgpLCBleGVjdXRpb24td2hpbGUtbm90LXJlbmRlcmVkPSgpLCBleGVjdXRpb24td2hpbGUtb3V0LW9mLXZpZXdwb3J0PSgpLCBmdWxsc2NyZWVuPSgpLCBnYW1lcGFkPSgpLCBnZW9sb2NhdGlvbj0oKSwgZ3lyb3Njb3BlPSgpLCBoaWQ9KCksIGlkZW50aXR5LWNyZWRlbnRpYWxzLWdldD0oKSwgaWRsZS1kZXRlY3Rpb249KCksIGxvY2FsLWZvbnRzPSgpLCBtYWduZXRvbWV0ZXI9KCksIG1pY3JvcGhvbmU9KCksIG1pZGk9KCksIG90cC1jcmVkZW50aWFscz0oKSwgcGF5bWVudD0oKSwgcGljdHVyZS1pbi1waWN0dXJlPSgpLCBwdWJsaWNrZXktY3JlZGVudGlhbHMtY3JlYXRlPSgpLCBwdWJsaWNrZXktY3JlZGVudGlhbHMtZ2V0PSgpLCBzY3JlZW4td2FrZS1sb2NrPSgpLCBzZXJpYWw9KCksIHNwZWFrZXItc2VsZWN0aW9uPSgpLCBzdG9yYWdlLWFjY2Vzcz0oKSwgdXNiPSgpLCB3ZWItc2hhcmU9KCksIHdpbmRvdy1tYW5hZ2VtZW50PSgpLCB4ci1zcGF0aWFsLXRyYWNraW5nPSgpIiwgIkRJU0FCTEVfREVGQVVMVF9TRVJWRVIiOiAieWVzIiwgIlNFUlZFX0ZJTEVTIjogIm5vIiwgIlNFTkRfQU5PTllNT1VTX1JFUE9SVCI6ICJubyIsICJNT0RTRUNVUklUWV9DUlNfVkVSU0lPTiI6ICI0IiwgIlVTRV9SRVZFUlNFX1BST1hZIjogInllcyIsICJSRVZFUlNFX1BST1hZX0hPU1QiOiAiaHR0cDovL2FwcDE6ODA4MCIsICJVU0VfV0hJVEVMSVNUIjogIm5vIn19fSwgIm9wZXJhdGlvbiI6ICJlZGl0IiwgIm9sZF9zZXJ2aWNlX25hbWUiOiAiIn19XX1d

View file

@ -27,13 +27,13 @@
{
"type": "Title",
"data": {
"title": "services_create_title"
"title": "services_new_title"
}
},
{
"type": "Text",
"data": {
"text": "services_create_subtitle"
"text": "services_new_subtitle"
}
},
{
@ -41,36 +41,36 @@
"data": {
"buttons": [
{
"id": "create-service-btn-new",
"id": "new-service-btn-new",
"text": "services_mode_easy",
"disabled": false,
"color": "info",
"size": "normal",
"attrs": {
"role": "link",
"data-link": "services/easy/new"
"data-link": "modes?mode=easy"
}
},
{
"id": "create-service-btn-new",
"id": "new-service-btn-new",
"text": "services_mode_advanced",
"disabled": false,
"color": "info",
"size": "normal",
"attrs": {
"role": "link",
"data-link": "services/advanced/new"
"data-link": "modes?mode=advanced"
}
},
{
"id": "create-service-btn-new",
"id": "new-service-btn-new",
"text": "services_mode_raw",
"disabled": false,
"color": "info",
"size": "normal",
"attrs": {
"role": "link",
"data-link": "services/raw/new"
"data-link": "modes?mode=raw"
}
}
]
@ -357,7 +357,7 @@
"size": "normal",
"attrs": {
"role": "link",
"data-link": "services/easy/app1.example.com"
"data-link": "modes?service_name=app1.example.com&mode=easy"
}
},
{
@ -368,7 +368,7 @@
"size": "normal",
"attrs": {
"role": "link",
"data-link": "services/advanced/app1.example.com"
"data-link": "modes?service_name=app1.example.com&mode=advanced"
}
},
{
@ -379,7 +379,7 @@
"size": "normal",
"attrs": {
"role": "link",
"data-link": "services/raw/app1.example.com"
"data-link": "modes?service_name=app1.example.com&mode=raw"
}
}
]
@ -778,7 +778,7 @@
"size": "normal",
"attrs": {
"role": "link",
"data-link": "services/easy/www.example.com"
"data-link": "modes?service_name=www.example.com&mode=easy"
}
},
{
@ -789,7 +789,7 @@
"size": "normal",
"attrs": {
"role": "link",
"data-link": "services/advanced/www.example.com"
"data-link": "modes?service_name=www.example.com&mode=advanced"
}
},
{
@ -800,7 +800,7 @@
"size": "normal",
"attrs": {
"role": "link",
"data-link": "services/raw/www.example.com"
"data-link": "modes?service_name=www.example.com&mode=raw"
}
}
]

File diff suppressed because one or more lines are too long

View file

@ -1144,16 +1144,39 @@ def instances():
return render_template("instances.html", title="Instances", data_server_builder=json.dumps(data_server_builder))
def get_service_data():
def get_service_data(page_name: str):
verify_data_in_form(
data={"csrf-token": None},
err_message=f"Missing csrf-token parameter on /{page_name}.",
redirect_url="services",
)
verify_data_in_form(
data={"operation": None},
err_message=f"Missing operation parameter on /{page_name}.",
redirect_url="services",
)
verify_data_in_form(
data={"operation": ("edit", "new", "delete")},
err_message="Invalid operation parameter on /{page_name}.",
redirect_url="services",
)
config = DB.get_config(methods=True, with_drafts=True)
# Check variables
variables = deepcopy(request.form.to_dict())
print(variables, flush=True)
del variables["csrf_token"]
operation = variables.pop("operation")
# Delete custom client variables
variables.pop("SECURITY_LEVEL", None)
variables.pop("mode", None)
try:
variables.pop("SECURITY_LEVEL", None)
variables.pop("mode", None)
except:
pass
# Get server name and old one
old_server_name = ""
@ -1287,42 +1310,38 @@ def services_modes():
if DB.readonly:
return handle_error("Database is in read-only mode", "services")
verify_data_in_form(
data={"operation": ("edit", "new", "delete")},
err_message="Invalid operation parameter on /easy-mode.",
redirect_url="services",
)
config, variables, format_configs, server_name, old_server_name, operation, is_draft, was_draft, is_draft_unchanged = get_service_data()
config, variables, format_configs, server_name, old_server_name, operation, is_draft, was_draft, is_draft_unchanged = get_service_data("modes")
update_service(config, variables, format_configs, server_name, old_server_name, operation, is_draft, was_draft, is_draft_unchanged, "raw-mode")
if not request.args.get("mode"):
return handle_error("Mode type is missing to access /modes.", "services")
service_name = request.args.get("service_name")
mode = request.args.get("mode")
service_name = request.args.get("service_name")
total_config = DB.get_config(methods=True, with_drafts=True)
service_names = total_config["SERVER_NAME"]["value"].split(" ")
if service_name and service_name not in service_names:
return handle_error("Service name not found to access advanced mode.", "services")
# Case new service
if service_name is None:
service_name = "new"
global_config = app.bw_config.get_config(global_only=True, methods=True)
plugins = app.bw_config.get_plugins()
data_server_builder = None
if mode == "raw":
data_server_builder = raw_mode_builder(TEMPLATE_PLACEHOLDER, plugins, global_config, total_config, service_name)
data_server_builder = raw_mode_builder(
TEMPLATE_PLACEHOLDER, plugins, global_config, total_config, service_name or "new", False if service_name else True
)
if mode == "advanced":
data_server_builder = advanced_mode_builder(TEMPLATE_PLACEHOLDER, plugins, global_config, total_config, service_name)
data_server_builder = advanced_mode_builder(
TEMPLATE_PLACEHOLDER, plugins, global_config, total_config, service_name or "new", False if service_name else True
)
if mode == "easy":
data_server_builder = easy_mode_builder(TEMPLATE_PLACEHOLDER, plugins, global_config, total_config, service_name)
data_server_builder = easy_mode_builder(
TEMPLATE_PLACEHOLDER, plugins, global_config, total_config, service_name or "new", False if service_name else True
)
return render_template("modes.html", data_server_builder=data_server_builder)
@ -1334,13 +1353,7 @@ def services():
if DB.readonly:
return handle_error("Database is in read-only mode", "services")
verify_data_in_form(
data={"operation": ("edit", "new", "delete")},
err_message="Invalid operation parameter on /services.",
redirect_url="services",
)
config, variables, format_configs, server_name, old_server_name, operation, is_draft, was_draft, is_draft_unchanged = get_service_data()
config, variables, format_configs, server_name, old_server_name, operation, is_draft, was_draft, is_draft_unchanged = get_service_data("services")
update_service(config, variables, format_configs, server_name, old_server_name, operation, is_draft, was_draft, is_draft_unchanged, "services")
# Display services