From 08d83d890291d1828b8e5bb43d03470621156078 Mon Sep 17 00:00:00 2001 From: Stavros Kois <47820033+stavros-k@users.noreply.github.com> Date: Mon, 14 Mar 2022 23:53:49 +0200 Subject: [PATCH] feat(selfservicepassword): add selfservicepassword (#2160) --- .../self-service-password/Chart.yaml | 31 ++ .../self-service-password/SKIPINSTALL | 0 .../self-service-password/questions.yaml | 424 ++++++++++++++++++ .../templates/common.yaml | 1 + .../self-service-password/values.yaml | 31 ++ .../img/appicons/self-service-passsword.png | Bin 0 -> 12656 bytes docs/apps/app-requests.md | 1 + docs/manual/default-ports.md | 1 + 8 files changed, 489 insertions(+) create mode 100644 charts/incubator/self-service-password/Chart.yaml create mode 100644 charts/incubator/self-service-password/SKIPINSTALL create mode 100644 charts/incubator/self-service-password/questions.yaml create mode 100644 charts/incubator/self-service-password/templates/common.yaml create mode 100644 charts/incubator/self-service-password/values.yaml create mode 100644 docs/_static/img/appicons/self-service-passsword.png diff --git a/charts/incubator/self-service-password/Chart.yaml b/charts/incubator/self-service-password/Chart.yaml new file mode 100644 index 00000000000..3e6152178bd --- /dev/null +++ b/charts/incubator/self-service-password/Chart.yaml @@ -0,0 +1,31 @@ +apiVersion: v2 +appVersion: "3.2.0" +dependencies: +- name: common + repository: https://truecharts.org + version: 9.1.2 +deprecated: false +description: Self Service Password is a PHP application that allows users to change their password in an LDAP directory. +home: https://github.com/truecharts/apps/tree/master/charts/stable/self-service-password +icon: https://truecharts.org/_static/img/appicons/self-service-password.png +keywords: +- password +- self-service +- ldap +kubeVersion: '>=1.16.0-0' +maintainers: +- email: info@truecharts.org + name: TrueCharts + url: https://truecharts.org +name: self-service-password +sources: +- https://github.com/tiredofit/docker-self-service-password +- https://hub.docker.com/r/tiredofit/self-service-password +- https://self-service-password.readthedocs.io/en/latest +type: application +version: 0.0.1 +annotations: + truecharts.org/catagories: | + - productivity + truecharts.org/SCALE-support: "true" + truecharts.org/grade: U diff --git a/charts/incubator/self-service-password/SKIPINSTALL b/charts/incubator/self-service-password/SKIPINSTALL new file mode 100644 index 00000000000..e69de29bb2d diff --git a/charts/incubator/self-service-password/questions.yaml b/charts/incubator/self-service-password/questions.yaml new file mode 100644 index 00000000000..ba7fbde97ad --- /dev/null +++ b/charts/incubator/self-service-password/questions.yaml @@ -0,0 +1,424 @@ +# Include{groups} +portals: + open: + protocols: + - "$kubernetes-resource_configmap_portal_protocol" + host: + - "$kubernetes-resource_configmap_portal_host" + ports: + - "$kubernetes-resource_configmap_portal_port" +questions: + - variable: portal + group: "Container Image" + label: "Configure Portal Button" + schema: + type: dict + hidden: true + attrs: + - variable: enabled + label: "Enable" + description: "enable the portal button" + schema: + hidden: true + editable: false + type: boolean + default: true +# Include{global} + + - variable: controller + group: "Controller" + label: "" + schema: + additional_attrs: true + type: dict + attrs: + - variable: advanced + label: "Show Advanced Controller Settings" + schema: + type: boolean + default: false + show_subquestions_if: true + subquestions: + - variable: type + description: "Please specify type of workload to deploy" + label: "(Advanced) Controller Type" + schema: + type: string + default: "deployment" + required: true + enum: + - value: "deployment" + description: "Deployment" + - value: "statefulset" + description: "Statefulset" + - value: "daemonset" + description: "Daemonset" + - variable: replicas + description: "Number of desired pod replicas" + label: "Desired Replicas" + schema: + type: int + default: 1 + required: true + - variable: strategy + description: "Please specify type of workload to deploy" + label: "(Advanced) Update Strategy" + schema: + type: string + default: "Recreate" + required: true + enum: + - value: "Recreate" + description: "Recreate: Kill existing pods before creating new ones" + - value: "RollingUpdate" + description: "RollingUpdate: Create new pods and then kill old ones" + - value: "OnDelete" + description: "(Legacy) OnDelete: ignore .spec.template changes" +# Include{controllerExpert} + - variable: env + group: "Container Configuration" + label: "Image Environment" + schema: + additional_attrs: true + type: dict + attrs: + - variable: SETUP_MODE + label: "SETUP_MODE" + description: "Select if you will provide Environment Variables or Configuration File, to overwrite the default configuration." + schema: + type: string + default: "MANUAL" + enum: + - value: "MANUAL" + description: "Configuration File" + - value: "AUTO" + description: "Environment Variables" + - variable: ENABLE_RESET_LOG + label: "ENABLE_RESET_LOG" + description: "Write to log detailing password resets." + schema: + type: boolean + default: false +# Include{containerConfig} + + - variable: service + group: "Networking and Services" + label: "Configure Service(s)" + schema: + additional_attrs: true + type: dict + attrs: + - variable: main + label: "Main Service" + description: "The Primary service on which the healthcheck runs, often the webUI" + schema: + additional_attrs: true + type: dict + attrs: +# Include{serviceSelector} + - variable: main + label: "Main Service Port Configuration" + schema: + additional_attrs: true + type: dict + attrs: + - variable: port + label: "Port" + description: "This port exposes the container port on the service" + schema: + type: int + default: 10182 + required: true + - variable: advanced + label: "Show Advanced settings" + schema: + type: boolean + default: false + show_subquestions_if: true + subquestions: + - variable: enabled + label: "Enable the port" + schema: + type: boolean + default: true + - variable: protocol + label: "Port Type" + schema: + type: string + default: "HTTP" + enum: + - value: HTTP + description: "HTTP" + - value: "HTTPS" + description: "HTTPS" + - value: TCP + description: "TCP" + - value: "UDP" + description: "UDP" + - variable: nodePort + label: "Node Port (Optional)" + description: "This port gets exposed to the node. Only considered when service type is NodePort, Simple or LoadBalancer" + schema: + type: int + min: 9000 + max: 65535 + - variable: targetPort + label: "Target Port" + description: "The internal(!) port on the container the Application runs on" + schema: + type: int + default: 80 + + - variable: serviceexpert + group: "Networking and Services" + label: "Show Expert Config" + schema: + type: boolean + default: false + show_subquestions_if: true + subquestions: + - variable: hostNetwork + group: "Networking and Services" + label: "Host-Networking (Complicated)" + schema: + type: boolean + default: false + +# Include{serviceExpert} + +# Include{serviceList} + + - variable: persistence + label: "Integrated Persistent Storage" + description: "Integrated Persistent Storage" + group: "Storage and Persistence" + schema: + additional_attrs: true + type: dict + attrs: + - variable: config + label: "App Config Storage" + description: "Stores the Application Configuration." + schema: + additional_attrs: true + type: dict + attrs: + - variable: type + label: "Type of Storage" + description: "Sets the persistence type, Anything other than PVC could break rollback!" + schema: + type: string + default: "simplePVC" + enum: + - value: "simplePVC" + description: "PVC (simple)" + - value: "simpleHP" + description: "HostPath (simple)" + - value: "emptyDir" + description: "emptyDir" + - value: "pvc" + description: "pvc" + - value: "hostPath" + description: "hostPath" +# Include{persistenceBasic} + - variable: hostPath + label: "hostPath" + description: "Path inside the container the storage is mounted" + schema: + show_if: [["type", "=", "hostPath"]] + type: hostpath + - variable: medium + label: "EmptyDir Medium" + schema: + show_if: [["type", "=", "emptyDir"]] + type: string + default: "" + enum: + - value: "" + description: "Default" + - value: "Memory" + description: "Memory" +# Include{persistenceAdvanced} + - variable: addons + label: "App addons Storage" + description: "Stores the Application addons." + schema: + additional_attrs: true + type: dict + attrs: + - variable: type + label: "Type of Storage" + description: "Sets the persistence type, Anything other than PVC could break rollback!" + schema: + type: string + default: "simplePVC" + enum: + - value: "simplePVC" + description: "PVC (simple)" + - value: "simpleHP" + description: "HostPath (simple)" + - value: "emptyDir" + description: "emptyDir" + - value: "pvc" + description: "pvc" + - value: "hostPath" + description: "hostPath" +# Include{persistenceBasic} + - variable: hostPath + label: "hostPath" + description: "Path inside the container the storage is mounted" + schema: + show_if: [["type", "=", "hostPath"]] + type: hostpath + - variable: medium + label: "EmptyDir Medium" + schema: + show_if: [["type", "=", "emptyDir"]] + type: string + default: "" + enum: + - value: "" + description: "Default" + - value: "Memory" + description: "Memory" +# Include{persistenceAdvanced} + - variable: logs + label: "App Logs Storage" + description: "Stores the Application Logs." + schema: + additional_attrs: true + type: dict + attrs: + - variable: type + label: "Type of Storage" + description: "Sets the persistence type, Anything other than PVC could break rollback!" + schema: + type: string + default: "simplePVC" + enum: + - value: "simplePVC" + description: "PVC (simple)" + - value: "simpleHP" + description: "HostPath (simple)" + - value: "emptyDir" + description: "emptyDir" + - value: "pvc" + description: "pvc" + - value: "hostPath" + description: "hostPath" +# Include{persistenceBasic} + - variable: hostPath + label: "hostPath" + description: "Path inside the container the storage is mounted" + schema: + show_if: [["type", "=", "hostPath"]] + type: hostpath + - variable: medium + label: "EmptyDir Medium" + schema: + show_if: [["type", "=", "emptyDir"]] + type: string + default: "" + enum: + - value: "" + description: "Default" + - value: "Memory" + description: "Memory" +# Include{persistenceAdvanced} + +# Include{persistenceList} + + - variable: ingress + label: "" + group: "Ingress" + schema: + additional_attrs: true + type: dict + attrs: + - variable: main + label: "Main Ingress" + schema: + additional_attrs: true + type: dict + attrs: +# Include{ingressDefault} + +# Include{ingressTLS} + +# Include{ingressTraefik} + +# Include{ingressExpert} + +# Include{ingressList} + +# Include{security} + + - variable: advancedSecurity + label: "Show Advanced Security Settings" + group: "Security and Permissions" + schema: + type: boolean + default: false + show_subquestions_if: true + subquestions: + - variable: securityContext + label: "Security Context" + schema: + additional_attrs: true + type: dict + attrs: + - variable: privileged + label: "Privileged mode" + schema: + type: boolean + default: false + - variable: readOnlyRootFilesystem + label: "ReadOnly Root Filesystem" + schema: + type: boolean + default: false + - variable: allowPrivilegeEscalation + label: "Allow Privilege Escalation" + schema: + type: boolean + default: false + - variable: runAsNonRoot + label: "runAsNonRoot" + schema: + type: boolean + default: true +# Include{securityContextAdvanced} + + - variable: podSecurityContext + group: "Security and Permissions" + label: "Pod Security Context" + schema: + additional_attrs: true + type: dict + attrs: + - variable: runAsUser + label: "runAsUser" + description: "The UserID of the user running the application" + schema: + type: int + default: 568 + - variable: runAsGroup + label: "runAsGroup" + description: The groupID this App of the user running the application" + schema: + type: int + default: 568 + - variable: fsGroup + label: "fsGroup" + description: "The group that should own ALL storage." + schema: + type: int + default: 568 +# Include{podSecurityContextAdvanced} + + +# Include{resources} + +# Include{advanced} + +# Include{addons} diff --git a/charts/incubator/self-service-password/templates/common.yaml b/charts/incubator/self-service-password/templates/common.yaml new file mode 100644 index 00000000000..a17e923ef88 --- /dev/null +++ b/charts/incubator/self-service-password/templates/common.yaml @@ -0,0 +1 @@ +{{- include "common.all" . }} diff --git a/charts/incubator/self-service-password/values.yaml b/charts/incubator/self-service-password/values.yaml new file mode 100644 index 00000000000..a6009ea0e89 --- /dev/null +++ b/charts/incubator/self-service-password/values.yaml @@ -0,0 +1,31 @@ +image: + repository: tccr.io/truecharts/self-service-password + pullPolicy: IfNotPresent + tag: v5.2.1@sha256:3b0a77651ba87ed0b09caec33d2b7c4beb54ac8428e02309a92459c2cdc875a1 + +securityContext: + readOnlyRootFilesystem: false + runAsNonRoot: false + +podSecurityContext: + runAsUser: 0 + runAsGroup: 0 + +env: + SETUP_MODE: "manual" + ENABLE_RESET_LOG: true + +service: + main: + ports: + main: + port: 10182 + targetPort: 80 + +persistence: + config: + enabled: true + mountPath: "/assets/custom" + logs: + enabled: true + mountPath: "/www/logs" diff --git a/docs/_static/img/appicons/self-service-passsword.png b/docs/_static/img/appicons/self-service-passsword.png new file mode 100644 index 0000000000000000000000000000000000000000..d3f2c4c8305651564f4a59ea8d205ba9d8d884b3 GIT binary patch literal 12656 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 e{4rsgocRCa7#8u^LRl#Q0000