mirror of
https://github.com/Sebclem/hassio-nextcloud-backup.git
synced 2024-11-25 18:43:00 +01:00
🔨 Manage backupConfig
This commit is contained in:
parent
79f1cfdf09
commit
b076f844a5
@ -23,6 +23,7 @@
|
||||
"form-data": "4.0.0",
|
||||
"got": "12.3.0",
|
||||
"http-errors": "2.0.0",
|
||||
"joi": "^17.6.1",
|
||||
"jquery": "3.6.0",
|
||||
"kleur": "^4.1.5",
|
||||
"luxon": "3.0.1",
|
||||
|
@ -26,6 +26,7 @@ specifiers:
|
||||
form-data: 4.0.0
|
||||
got: 12.3.0
|
||||
http-errors: 2.0.0
|
||||
joi: ^17.6.1
|
||||
jquery: 3.6.0
|
||||
kleur: ^4.1.5
|
||||
luxon: 3.0.1
|
||||
@ -48,6 +49,7 @@ dependencies:
|
||||
form-data: 4.0.0
|
||||
got: 12.3.0
|
||||
http-errors: 2.0.0
|
||||
joi: 17.6.1
|
||||
jquery: 3.6.0
|
||||
kleur: 4.1.5
|
||||
luxon: 3.0.1
|
||||
@ -131,6 +133,16 @@ packages:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
/@hapi/hoek/9.3.0:
|
||||
resolution: {integrity: sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==}
|
||||
dev: false
|
||||
|
||||
/@hapi/topo/5.1.0:
|
||||
resolution: {integrity: sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==}
|
||||
dependencies:
|
||||
'@hapi/hoek': 9.3.0
|
||||
dev: false
|
||||
|
||||
/@jridgewell/resolve-uri/3.1.0:
|
||||
resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==}
|
||||
engines: {node: '>=6.0.0'}
|
||||
@ -165,6 +177,20 @@ packages:
|
||||
'@nodelib/fs.scandir': 2.1.5
|
||||
fastq: 1.13.0
|
||||
|
||||
/@sideway/address/4.1.4:
|
||||
resolution: {integrity: sha512-7vwq+rOHVWjyXxVlR76Agnvhy8I9rpzjosTESvmhNeXOXdZZB15Fl+TI9x1SiHZH5Jv2wTGduSxFDIaq0m3DUw==}
|
||||
dependencies:
|
||||
'@hapi/hoek': 9.3.0
|
||||
dev: false
|
||||
|
||||
/@sideway/formula/3.0.0:
|
||||
resolution: {integrity: sha512-vHe7wZ4NOXVfkoRb8T5otiENVlT7a3IAiw7H5M2+GO+9CDgcVUUsX1zalAztCmwyOr2RUTGJdgB+ZvSVqmdHmg==}
|
||||
dev: false
|
||||
|
||||
/@sideway/pinpoint/2.0.0:
|
||||
resolution: {integrity: sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==}
|
||||
dev: false
|
||||
|
||||
/@sindresorhus/is/5.3.0:
|
||||
resolution: {integrity: sha512-CX6t4SYQ37lzxicAqsBtxA3OseeoVrh9cSJ5PFYam0GksYlupRfy1A+Q4aYD3zvcfECLc0zO2u+ZnR2UYKvCrw==}
|
||||
engines: {node: '>=14.16'}
|
||||
@ -1493,6 +1519,16 @@ packages:
|
||||
/isexe/2.0.0:
|
||||
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
|
||||
|
||||
/joi/17.6.1:
|
||||
resolution: {integrity: sha512-Hl7/iBklIX345OCM1TiFSCZRVaAOLDGlWCp0Df2vWYgBgjkezaR7Kvm3joBciBHQjZj5sxXs859r6eqsRSlG8w==}
|
||||
dependencies:
|
||||
'@hapi/hoek': 9.3.0
|
||||
'@hapi/topo': 5.1.0
|
||||
'@sideway/address': 4.1.4
|
||||
'@sideway/formula': 3.0.0
|
||||
'@sideway/pinpoint': 2.0.0
|
||||
dev: false
|
||||
|
||||
/jquery/3.6.0:
|
||||
resolution: {integrity: sha512-JVzAR/AjBvVt2BmYhxRCSYysDsPcssdmTFnzyLEts9qNwmjmu4JTAMYubEfwVOSwpQ1I1sKKFcxhZCI2buerfw==}
|
||||
dev: false
|
||||
|
@ -1,9 +1,11 @@
|
||||
import express from "express"
|
||||
import configRouter from "./config.js";
|
||||
import homeAssistant from "./homeAssistant.js"
|
||||
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
router.use("/homeAssistant", homeAssistant)
|
||||
router.use("/config", configRouter);
|
||||
|
||||
export default router;
|
20
nextcloud_backup/backend/src/routes/config.ts
Normal file
20
nextcloud_backup/backend/src/routes/config.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import { config } from "dotenv";
|
||||
import express from "express";
|
||||
import { saveBackupConfig, validateBackupConfig } from "../services/configService.js";
|
||||
|
||||
const configRouter = express.Router();
|
||||
|
||||
configRouter.put("/backup", (req, res, next) => {
|
||||
validateBackupConfig(req.body)
|
||||
.then(() => {
|
||||
saveBackupConfig(req.body);
|
||||
res.status(204);
|
||||
res.send();
|
||||
})
|
||||
.catch((error) => {
|
||||
res.status(400);
|
||||
res.json(error.details);
|
||||
});
|
||||
});
|
||||
|
||||
export default configRouter;
|
@ -1,9 +1,9 @@
|
||||
import express from "express";
|
||||
import * as haOsService from "../services/homeAssistantService.js"
|
||||
|
||||
const router = express.Router();
|
||||
const homeAssistantRouter = express.Router();
|
||||
|
||||
router.get("/backups/", (req, res, next) => {
|
||||
homeAssistantRouter.get("/backups/", (req, res, next) => {
|
||||
haOsService.getBackups()
|
||||
.then((value)=>{
|
||||
res.json(value.body.data.backups);
|
||||
@ -14,6 +14,5 @@ router.get("/backups/", (req, res, next) => {
|
||||
});
|
||||
|
||||
|
||||
router.get("")
|
||||
|
||||
export default router;
|
||||
export default homeAssistantRouter;
|
52
nextcloud_backup/backend/src/services/configService.ts
Normal file
52
nextcloud_backup/backend/src/services/configService.ts
Normal file
@ -0,0 +1,52 @@
|
||||
import fs from "fs";
|
||||
import Joi from "joi"
|
||||
import logger from "../config/winston.js";
|
||||
import { backupConfigValidation } from "../types/services/backupConfigValidation.js"
|
||||
import { BackupConfig } from "../types/services/backupConfig.js"
|
||||
|
||||
|
||||
const backupConfigPath = "/data/backupConfigV2.json";
|
||||
|
||||
|
||||
export function validateBackupConfig(config: BackupConfig){
|
||||
const validator = Joi.object(backupConfigValidation);
|
||||
return validator.validateAsync(config);
|
||||
}
|
||||
|
||||
export function saveBackupConfig(config: BackupConfig){
|
||||
fs.writeFileSync(backupConfigPath, JSON.stringify(config, undefined, 2));
|
||||
}
|
||||
|
||||
export function getBackupConfig(): BackupConfig {
|
||||
if (!fs.existsSync(backupConfigPath)) {
|
||||
logger.warn("Config file not found, creating default one !")
|
||||
const defaultConfig = getBackupDefaultConfig();
|
||||
saveBackupConfig(defaultConfig);
|
||||
return defaultConfig;
|
||||
} else {
|
||||
return JSON.parse(fs.readFileSync(backupConfigPath).toString());
|
||||
}
|
||||
}
|
||||
|
||||
export function getBackupDefaultConfig(): BackupConfig {
|
||||
return {
|
||||
nameTemplate: "{type}-{ha_version}-{date}_{hour}",
|
||||
cron: [],
|
||||
autoClean: {
|
||||
homeAssistant: {
|
||||
enabled: false,
|
||||
},
|
||||
webdav: {
|
||||
enabled: false
|
||||
},
|
||||
},
|
||||
exclude: {
|
||||
addon: [],
|
||||
folder: [],
|
||||
},
|
||||
autoStopAddon: [],
|
||||
password: {
|
||||
enabled: false,
|
||||
}
|
||||
}
|
||||
}
|
51
nextcloud_backup/backend/src/types/services/backupConfig.ts
Normal file
51
nextcloud_backup/backend/src/types/services/backupConfig.ts
Normal file
@ -0,0 +1,51 @@
|
||||
export enum CronMode {
|
||||
DAILY = "DAILY",
|
||||
WEEKLY = "WEEKLY",
|
||||
MONTHLY = "MONTHLY",
|
||||
CUSTOM = "CUSTOM"
|
||||
}
|
||||
|
||||
export enum Weekday {
|
||||
SUNDAY,
|
||||
MONDAY,
|
||||
TUESDAY,
|
||||
WEDNESDAY,
|
||||
THURSDAY,
|
||||
FRIDAY,
|
||||
SATURDAY
|
||||
}
|
||||
|
||||
|
||||
export interface BackupConfig {
|
||||
nameTemplate: string;
|
||||
cron: CronConfig[];
|
||||
autoClean: {
|
||||
homeAssistant: AutoCleanConfig;
|
||||
webdav: AutoCleanConfig;
|
||||
}
|
||||
exclude: {
|
||||
addon: string[];
|
||||
folder: string[];
|
||||
}
|
||||
autoStopAddon: string[];
|
||||
password: {
|
||||
enabled: boolean;
|
||||
value?: string;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export interface CronConfig {
|
||||
id: string;
|
||||
mode: CronMode;
|
||||
hour?: string;
|
||||
weekday?: Weekday;
|
||||
monthDay: string;
|
||||
custom?: string;
|
||||
}
|
||||
|
||||
|
||||
export interface AutoCleanConfig {
|
||||
enabled: boolean;
|
||||
nbrToKeep?: number;
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
import Joi from "joi";
|
||||
import { CronMode } from "./backupConfig.js";
|
||||
|
||||
const CronConfigValidation = {
|
||||
id: Joi.string().required().not().empty(),
|
||||
mode: Joi.string()
|
||||
.required()
|
||||
.valid(CronMode.CUSTOM, CronMode.DAILY, CronMode.MONTHLY, CronMode.WEEKLY),
|
||||
hour: Joi.alternatives().conditional("mode", {
|
||||
is: CronMode.CUSTOM,
|
||||
then: Joi.forbidden(),
|
||||
otherwise: Joi.string()
|
||||
.pattern(/^\d{2}:\d{2}$/)
|
||||
.required(),
|
||||
}),
|
||||
weekday: Joi.alternatives().conditional("mode", {
|
||||
is: CronMode.WEEKLY,
|
||||
then: Joi.number().min(0).max(6).required(),
|
||||
otherwise: Joi.forbidden(),
|
||||
}),
|
||||
monthDay: Joi.alternatives().conditional("mode", {
|
||||
is: CronMode.MONTHLY,
|
||||
then: Joi.number().min(1).max(28).required(),
|
||||
otherwise: Joi.forbidden(),
|
||||
}),
|
||||
custom: Joi.alternatives().conditional("mode", {
|
||||
is: CronMode.CUSTOM,
|
||||
then: Joi.string().required(),
|
||||
otherwise: Joi.forbidden(),
|
||||
}),
|
||||
};
|
||||
|
||||
const AutoCleanConfig = {
|
||||
enabled: Joi.boolean().required(),
|
||||
nbrToKeep: Joi.alternatives().conditional("enabled", {
|
||||
is: true,
|
||||
then: Joi.number().required().min(0),
|
||||
otherwise: Joi.forbidden(),
|
||||
}),
|
||||
};
|
||||
|
||||
export const backupConfigValidation = {
|
||||
nameTemplate: Joi.string().required().not().empty(),
|
||||
cron: Joi.array().items(CronConfigValidation).required(),
|
||||
autoClean: Joi.object({
|
||||
homeAssistant: Joi.object(AutoCleanConfig).required(),
|
||||
webdav: Joi.object(AutoCleanConfig).required(),
|
||||
}).required(),
|
||||
exclude: Joi.object({
|
||||
addon: Joi.array().items(Joi.string().not().empty()),
|
||||
folder: Joi.array().items(Joi.string().not().empty()),
|
||||
}).required(),
|
||||
autoStopAddon: Joi.array().items(Joi.string().not().empty()),
|
||||
password: Joi.object({
|
||||
enabled: Joi.boolean().required(),
|
||||
value: Joi.alternatives().conditional("enabled", {
|
||||
is: true,
|
||||
then: Joi.string().required().not().empty(),
|
||||
otherwise: Joi.forbidden(),
|
||||
}),
|
||||
}),
|
||||
};
|
Loading…
Reference in New Issue
Block a user