浏览代码

Enhancement: support dot-notated field properties in docker labels (#2195)

icyleaf 1 年之前
父节点
当前提交
8ea2ccf
共有 6 个文件被更改,包括 88 次插入15 次删除
  1. 17 0
      docs/configs/docker.md
  2. 0 6
      package-lock.json
  3. 0 1
      package.json
  4. 0 7
      pnpm-lock.yaml
  5. 1 1
      src/utils/config/service-helpers.js
  6. 70 0
      src/utils/config/shvl.js

+ 17 - 0
docs/configs/docker.md

@@ -153,6 +153,23 @@ labels:
     - homepage.widget.fields=["field1","field2"] # optional
     - homepage.widget.fields=["field1","field2"] # optional
 ```
 ```
 
 
+You can add specify fields for e.g. the [CustomAPI](/widgets/services/customapi) widget by using array-style dot notation:
+
+```yaml
+labels:
+    - homepage.group=Media
+    - homepage.name=Emby
+    - homepage.icon=emby.png
+    - homepage.href=http://emby.home/
+    - homepage.description=Media server
+    - homepage.widget.type=customapi
+    - homepage.widget.url=http://argus.service/api/v1/service/summary/emby
+    - homepage.widget.field[0].label=Deployed Version
+    - homepage.widget.field[0].field.status=deployed_version
+    - homepage.widget.field[1].label=Latest Version
+    - homepage.widget.field[1].field.status=latest_version
+```
+
 ## Docker Swarm
 ## Docker Swarm
 
 
 Docker swarm is supported and Docker services are specified with the same `server` and `container` notation. To enable swarm support you will need to include a `swarm` setting in your docker.yaml, e.g.
 Docker swarm is supported and Docker services are specified with the same `server` and `container` notation. To enable swarm support you will need to include a `swarm` setting in your docker.yaml, e.g.

+ 0 - 6
package-lock.json

@@ -30,7 +30,6 @@
         "react-i18next": "^11.18.6",
         "react-i18next": "^11.18.6",
         "react-icons": "^4.4.0",
         "react-icons": "^4.4.0",
         "recharts": "^2.7.2",
         "recharts": "^2.7.2",
-        "shvl": "^3.0.0",
         "swr": "^1.3.0",
         "swr": "^1.3.0",
         "systeminformation": "^5.17.12",
         "systeminformation": "^5.17.12",
         "tough-cookie": "^4.1.2",
         "tough-cookie": "^4.1.2",
@@ -5628,11 +5627,6 @@
         "node": ">=4"
         "node": ">=4"
       }
       }
     },
     },
-    "node_modules/shvl": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/shvl/-/shvl-3.0.0.tgz",
-      "integrity": "sha512-5IomAM3ykE/g9K9L6lhODc+TpCuN03rrhlboegeKyyfh66DDdpRD5JN37DYhNHH+RaYjiIDx64K/Ms/xQYOR5w=="
-    },
     "node_modules/side-channel": {
     "node_modules/side-channel": {
       "version": "1.0.4",
       "version": "1.0.4",
       "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
       "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",

+ 0 - 1
package.json

@@ -32,7 +32,6 @@
     "react-i18next": "^11.18.6",
     "react-i18next": "^11.18.6",
     "react-icons": "^4.4.0",
     "react-icons": "^4.4.0",
     "recharts": "^2.7.2",
     "recharts": "^2.7.2",
-    "shvl": "^3.0.0",
     "swr": "^1.3.0",
     "swr": "^1.3.0",
     "systeminformation": "^5.17.12",
     "systeminformation": "^5.17.12",
     "tough-cookie": "^4.1.2",
     "tough-cookie": "^4.1.2",

+ 0 - 7
pnpm-lock.yaml

@@ -71,9 +71,6 @@ dependencies:
   recharts:
   recharts:
     specifier: ^2.7.2
     specifier: ^2.7.2
     version: 2.7.2(prop-types@15.8.1)(react-dom@18.2.0)(react@18.2.0)
     version: 2.7.2(prop-types@15.8.1)(react-dom@18.2.0)(react@18.2.0)
-  shvl:
-    specifier: ^3.0.0
-    version: 3.0.0
   swr:
   swr:
     specifier: ^1.3.0
     specifier: ^1.3.0
     version: 1.3.0(react@18.2.0)
     version: 1.3.0(react@18.2.0)
@@ -3614,10 +3611,6 @@ packages:
       rechoir: 0.6.2
       rechoir: 0.6.2
     dev: false
     dev: false
 
 
-  /shvl@3.0.0:
-    resolution: {integrity: sha512-5IomAM3ykE/g9K9L6lhODc+TpCuN03rrhlboegeKyyfh66DDdpRD5JN37DYhNHH+RaYjiIDx64K/Ms/xQYOR5w==}
-    dev: false
-
   /side-channel@1.0.4:
   /side-channel@1.0.4:
     resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==}
     resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==}
     dependencies:
     dependencies:

+ 1 - 1
src/utils/config/service-helpers.js

@@ -3,13 +3,13 @@ import path from "path";
 
 
 import yaml from "js-yaml";
 import yaml from "js-yaml";
 import Docker from "dockerode";
 import Docker from "dockerode";
-import * as shvl from "shvl";
 import { CustomObjectsApi, NetworkingV1Api, ApiextensionsV1Api } from "@kubernetes/client-node";
 import { CustomObjectsApi, NetworkingV1Api, ApiextensionsV1Api } from "@kubernetes/client-node";
 
 
 import createLogger from "utils/logger";
 import createLogger from "utils/logger";
 import checkAndCopyConfig, { CONF_DIR, substituteEnvironmentVars } from "utils/config/config";
 import checkAndCopyConfig, { CONF_DIR, substituteEnvironmentVars } from "utils/config/config";
 import getDockerArguments from "utils/config/docker";
 import getDockerArguments from "utils/config/docker";
 import getKubeConfig from "utils/config/kubernetes";
 import getKubeConfig from "utils/config/kubernetes";
+import * as shvl from "utils/config/shvl";
 
 
 const logger = createLogger("service-helpers");
 const logger = createLogger("service-helpers");
 
 

+ 70 - 0
src/utils/config/shvl.js

@@ -0,0 +1,70 @@
+/* eslint-disable */
+
+/*
+Code primarely based on shvl repository: https://github.com/robinvdvleuten/shvl
+
+MIT License
+
+Copyright (c) Robin van der Vleuten <robin@webstronauts.co>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+export function get(object, path, def) {
+  return (
+    // Split the path into keys and reduce the object to the target value
+    object = path.split(/[.[\]]+/).reduce(function (obj, p) {
+      // Check each nested object to see if the key exists
+      return obj && obj[p] !== undefined ? obj[p] : undefined;
+    }, object)
+  ) === undefined
+    // If the final value is undefined, return the default value
+    ? def
+    : object;  // Otherwise, return the value found
+}
+
+export function set(obj, path, val) {
+  // Split the path into keys and filter out any empty strings
+  const keys = path.split(/[.[\]]+/).filter(Boolean);
+
+  // Pop the last key to set the value later
+  const lastKey = keys.pop();
+
+  // Prevent setting dangerous keys like __proto__
+  if (/^(__proto__|constructor|prototype)$/.test(lastKey)) return obj;
+
+  // Reduce the object to the nested object where we want to set the value
+  keys.reduce((acc, key, i) => {
+    // Again, block dangerous keys
+    if (/^(__proto__|constructor|prototype)$/.test(key)) return {};
+
+    // Check if next key is an array index
+    const isIndex = /^\d+$/.test(keys[i + 1]);
+
+    // If current key doesn't exist, initialise it as an array or object
+    acc[key] = Array.isArray(acc[key])
+      ? acc[key]
+      : (isIndex ? [] : acc[key] || {});
+
+    // Return nested object for next iteration
+    return acc[key];
+  }, obj)[lastKey] = val;  // Finally set the value
+
+  return obj;
+}