From 881b4e0a305d94922602a4b1471fea0f929059ff Mon Sep 17 00:00:00 2001 From: sonicaj Date: Thu, 4 Jan 2024 11:59:32 +0000 Subject: [PATCH] Publish new changes in catalog --- .../wordpress/1.1.9/ci/basic-values.yaml | 10 - community/wordpress/1.1.9/ci/cron-values.yaml | 14 - community/wordpress/1.1.9/questions.yaml | 349 ------------ .../wordpress/{1.1.9 => 1.2.0}/Chart.lock | 0 .../wordpress/{1.1.9 => 1.2.0}/Chart.yaml | 2 +- .../wordpress/{1.1.9 => 1.2.0}/README.md | 0 .../wordpress/{1.1.9 => 1.2.0}/app-readme.md | 0 .../{1.1.9 => 1.2.0}/charts/common-1.2.6.tgz | Bin .../wordpress/1.2.0/ci/basic-values.yaml | 10 + community/wordpress/1.2.0/ci/cron-values.yaml | 14 + .../wordpress/{1.1.9 => 1.2.0}/ix_values.yaml | 9 +- .../wordpress/{1.1.9 => 1.2.0}/metadata.yaml | 0 community/wordpress/1.2.0/migrations/migrate | 73 +++ community/wordpress/1.2.0/questions.yaml | 533 ++++++++++++++++++ .../{1.1.9 => 1.2.0}/templates/NOTES.txt | 0 .../templates/_configuration.tpl | 0 .../{1.1.9 => 1.2.0}/templates/_cron.tpl | 0 .../{1.1.9 => 1.2.0}/templates/_mariadb.tpl | 0 .../templates/_persistence.tpl | 49 +- .../{1.1.9 => 1.2.0}/templates/_portal.tpl | 0 .../{1.1.9 => 1.2.0}/templates/_service.tpl | 0 .../{1.1.9 => 1.2.0}/templates/_wordpress.tpl | 0 .../{1.1.9 => 1.2.0}/templates/common.yaml | 0 test/minio/1.1.0/Chart.lock | 6 + test/minio/1.1.0/Chart.yaml | 26 + test/minio/1.1.0/README.md | 16 + test/minio/1.1.0/app-readme.md | 16 + test/minio/1.1.0/charts/common-1.2.6.tgz | Bin 0 -> 63149 bytes test/minio/1.1.0/ci/snmd-https-values.yaml | 118 ++++ .../1.1.0/ci/snmd-logsearch-https-values.yaml | 130 +++++ .../minio/1.1.0/ci/snmd-logsearch-values.yaml | 34 ++ test/minio/1.1.0/ci/snmd-values.yaml | 22 + test/minio/1.1.0/ci/snsd-https-values.yaml | 104 ++++ .../1.1.0/ci/snsd-logsearch-https-values.yaml | 115 ++++ .../minio/1.1.0/ci/snsd-logsearch-values.yaml | 25 + test/minio/1.1.0/ci/snsd-values.yaml | 17 + test/minio/1.1.0/ix_values.yaml | 50 ++ test/minio/1.1.0/metadata.yaml | 18 + test/minio/1.1.0/migrations/migrate | 63 +++ test/minio/1.1.0/questions.yaml | 512 +++++++++++++++++ test/minio/1.1.0/templates/NOTES.txt | 1 + test/minio/1.1.0/templates/_configuration.tpl | 61 ++ test/minio/1.1.0/templates/_helpers.tpl | 115 ++++ test/minio/1.1.0/templates/_logsearch.tpl | 51 ++ test/minio/1.1.0/templates/_minio.tpl | 145 +++++ test/minio/1.1.0/templates/_portal.tpl | 20 + test/minio/1.1.0/templates/_postgres.tpl | 20 + test/minio/1.1.0/templates/common.yaml | 25 + test/minio/1.1.0/to_keep_versions.md | 3 + test/minio/1.1.0/upgrade_strategy_disable | 62 ++ 50 files changed, 2435 insertions(+), 403 deletions(-) delete mode 100644 community/wordpress/1.1.9/ci/basic-values.yaml delete mode 100644 community/wordpress/1.1.9/ci/cron-values.yaml delete mode 100644 community/wordpress/1.1.9/questions.yaml rename community/wordpress/{1.1.9 => 1.2.0}/Chart.lock (100%) rename community/wordpress/{1.1.9 => 1.2.0}/Chart.yaml (97%) rename community/wordpress/{1.1.9 => 1.2.0}/README.md (100%) rename community/wordpress/{1.1.9 => 1.2.0}/app-readme.md (100%) rename community/wordpress/{1.1.9 => 1.2.0}/charts/common-1.2.6.tgz (100%) create mode 100644 community/wordpress/1.2.0/ci/basic-values.yaml create mode 100644 community/wordpress/1.2.0/ci/cron-values.yaml rename community/wordpress/{1.1.9 => 1.2.0}/ix_values.yaml (71%) rename community/wordpress/{1.1.9 => 1.2.0}/metadata.yaml (100%) create mode 100755 community/wordpress/1.2.0/migrations/migrate create mode 100644 community/wordpress/1.2.0/questions.yaml rename community/wordpress/{1.1.9 => 1.2.0}/templates/NOTES.txt (100%) rename community/wordpress/{1.1.9 => 1.2.0}/templates/_configuration.tpl (100%) rename community/wordpress/{1.1.9 => 1.2.0}/templates/_cron.tpl (100%) rename community/wordpress/{1.1.9 => 1.2.0}/templates/_mariadb.tpl (100%) rename community/wordpress/{1.1.9 => 1.2.0}/templates/_persistence.tpl (52%) rename community/wordpress/{1.1.9 => 1.2.0}/templates/_portal.tpl (100%) rename community/wordpress/{1.1.9 => 1.2.0}/templates/_service.tpl (100%) rename community/wordpress/{1.1.9 => 1.2.0}/templates/_wordpress.tpl (100%) rename community/wordpress/{1.1.9 => 1.2.0}/templates/common.yaml (100%) create mode 100644 test/minio/1.1.0/Chart.lock create mode 100644 test/minio/1.1.0/Chart.yaml create mode 100644 test/minio/1.1.0/README.md create mode 100644 test/minio/1.1.0/app-readme.md create mode 100644 test/minio/1.1.0/charts/common-1.2.6.tgz create mode 100644 test/minio/1.1.0/ci/snmd-https-values.yaml create mode 100644 test/minio/1.1.0/ci/snmd-logsearch-https-values.yaml create mode 100644 test/minio/1.1.0/ci/snmd-logsearch-values.yaml create mode 100644 test/minio/1.1.0/ci/snmd-values.yaml create mode 100644 test/minio/1.1.0/ci/snsd-https-values.yaml create mode 100644 test/minio/1.1.0/ci/snsd-logsearch-https-values.yaml create mode 100644 test/minio/1.1.0/ci/snsd-logsearch-values.yaml create mode 100644 test/minio/1.1.0/ci/snsd-values.yaml create mode 100644 test/minio/1.1.0/ix_values.yaml create mode 100644 test/minio/1.1.0/metadata.yaml create mode 100755 test/minio/1.1.0/migrations/migrate create mode 100644 test/minio/1.1.0/questions.yaml create mode 100644 test/minio/1.1.0/templates/NOTES.txt create mode 100644 test/minio/1.1.0/templates/_configuration.tpl create mode 100644 test/minio/1.1.0/templates/_helpers.tpl create mode 100644 test/minio/1.1.0/templates/_logsearch.tpl create mode 100644 test/minio/1.1.0/templates/_minio.tpl create mode 100644 test/minio/1.1.0/templates/_portal.tpl create mode 100644 test/minio/1.1.0/templates/_postgres.tpl create mode 100644 test/minio/1.1.0/templates/common.yaml create mode 100644 test/minio/1.1.0/to_keep_versions.md create mode 100755 test/minio/1.1.0/upgrade_strategy_disable diff --git a/community/wordpress/1.1.9/ci/basic-values.yaml b/community/wordpress/1.1.9/ci/basic-values.yaml deleted file mode 100644 index 25f5e4ec4c..0000000000 --- a/community/wordpress/1.1.9/ci/basic-values.yaml +++ /dev/null @@ -1,10 +0,0 @@ -wpStorage: - data: - type: hostPath - hostPath: /mnt/{{ .Release.Name }}/data - mariadbData: - type: hostPath - hostPath: /mnt/{{ .Release.Name }}/mariadbData - mariadbBackup: - type: hostPath - hostPath: /mnt/{{ .Release.Name }}/mariadbBackup diff --git a/community/wordpress/1.1.9/ci/cron-values.yaml b/community/wordpress/1.1.9/ci/cron-values.yaml deleted file mode 100644 index a595138e40..0000000000 --- a/community/wordpress/1.1.9/ci/cron-values.yaml +++ /dev/null @@ -1,14 +0,0 @@ -wpConfig: - enableCronJob: true - cronSchedule: "*/1 * * * *" - -wpStorage: - data: - type: hostPath - hostPath: /mnt/{{ .Release.Name }}/data - mariadbData: - type: hostPath - hostPath: /mnt/{{ .Release.Name }}/mariadbData - mariadbBackup: - type: hostPath - hostPath: /mnt/{{ .Release.Name }}/mariadbBackup diff --git a/community/wordpress/1.1.9/questions.yaml b/community/wordpress/1.1.9/questions.yaml deleted file mode 100644 index 55653ba9ab..0000000000 --- a/community/wordpress/1.1.9/questions.yaml +++ /dev/null @@ -1,349 +0,0 @@ -groups: - - name: Wordpress Configuration - description: Configure Wordpress - - name: Network Configuration - description: Configure Network for Wordpress - - name: Storage Configuration - description: Configure Storage for Wordpress - - name: Resources Configuration - description: Configure Resources for Wordpress - -portals: - web_portal: - protocols: - - "$kubernetes-resource_configmap_portal_protocol" - host: - - "$kubernetes-resource_configmap_portal_host" - ports: - - "$kubernetes-resource_configmap_portal_port" - path: "$kubernetes-resource_configmap_portal_path" - admin: - protocols: - - "$kubernetes-resource_configmap_portal_protocol" - host: - - "$kubernetes-resource_configmap_portal_host" - ports: - - "$kubernetes-resource_configmap_portal_port" - path: /wp-admin - -questions: - - variable: wpConfig - label: "" - group: Wordpress Configuration - schema: - type: dict - attrs: - - variable: enableCronJob - label: Enable CronJob - description: | - Enable CronJob for Wordpress executed by Kubernetes scheduler.
- This will also disable running cron on page load. - schema: - type: boolean - default: false - - variable: cronSchedule - label: Cron Schedule - description: Cron schedule for Wordpress CronJob. - schema: - type: string - default: "*/15 * * * *" - show_if: [["enableCronJob", "=", true]] - required: true - - variable: additionalEnvs - label: Additional Environment Variables - description: Configure additional environment variables for Wordpress. - schema: - type: list - default: [] - items: - - variable: env - label: Environment Variable - schema: - type: dict - attrs: - - variable: name - label: Name - schema: - type: string - required: true - - variable: value - label: Value - schema: - type: string - required: true - - - variable: wpNetwork - label: "" - group: Network Configuration - schema: - type: dict - attrs: - - variable: webPort - label: Web Port - description: The port for the Wordpress WebUI. - schema: - type: int - default: 30040 - min: 9000 - max: 65535 - required: true - - - variable: wpStorage - label: "" - group: Storage Configuration - schema: - type: dict - attrs: - - variable: data - label: Wordpress Data Storage - description: The path to store Wordpress data. - schema: - type: dict - attrs: - - variable: type - label: Type - description: | - ixVolume: Is dataset created automatically by the system.
- Host Path: Is a path that already exists on the system. - schema: - type: string - required: true - immutable: true - default: ixVolume - enum: - - value: hostPath - description: Host Path (Path that already exists on the system) - - value: ixVolume - description: ixVolume (Dataset created automatically by the system) - - variable: datasetName - label: Dataset Name - schema: - type: string - show_if: [["type", "=", "ixVolume"]] - required: true - hidden: true - immutable: true - default: data - $ref: - - "normalize/ixVolume" - - variable: hostPath - label: Host Path - schema: - type: hostpath - show_if: [["type", "=", "hostPath"]] - required: true - - variable: mariadbData - label: Wordpress MariaDB Data Storage - description: The path to store Wordpress MariaDB Data. - schema: - type: dict - attrs: - - variable: type - label: Type - description: | - ixVolume: Is dataset created automatically by the system.
- Host Path: Is a path that already exists on the system. - schema: - type: string - required: true - immutable: true - default: ixVolume - enum: - - value: hostPath - description: Host Path (Path that already exists on the system) - - value: ixVolume - description: ixVolume (Dataset created automatically by the system) - - variable: datasetName - label: Dataset Name - schema: - type: string - show_if: [["type", "=", "ixVolume"]] - required: true - hidden: true - immutable: true - default: mariadbData - $ref: - - "normalize/ixVolume" - - variable: hostPath - label: Host Path - schema: - type: hostpath - show_if: [["type", "=", "hostPath"]] - required: true - - variable: mariadbBackup - label: Wordpress MariaDB Backup Storage - description: The path to store Wordpress MariaDB Backup. - schema: - type: dict - attrs: - - variable: type - label: Type - description: | - ixVolume: Is dataset created automatically by the system.
- Host Path: Is a path that already exists on the system. - schema: - type: string - required: true - immutable: true - default: ixVolume - enum: - - value: hostPath - description: Host Path (Path that already exists on the system) - - value: ixVolume - description: ixVolume (Dataset created automatically by the system) - - variable: datasetName - label: Dataset Name - schema: - type: string - show_if: [["type", "=", "ixVolume"]] - required: true - hidden: true - immutable: true - default: mariadbBackup - $ref: - - "normalize/ixVolume" - - variable: hostPath - label: Host Path - schema: - type: hostpath - show_if: [["type", "=", "hostPath"]] - required: true - - variable: additionalStorages - label: Additional Storage - description: Additional storage for Wordpress. - schema: - type: list - default: [] - items: - - variable: storageEntry - label: Storage Entry - schema: - type: dict - attrs: - - variable: type - label: Type - description: | - ixVolume: Is dataset created automatically by the system.
- Host Path: Is a path that already exists on the system.
- SMB Share: Is a SMB share that is mounted to a persistent volume claim. - schema: - type: string - required: true - default: "ixVolume" - immutable: true - enum: - - value: "hostPath" - description: Host Path (Path that already exists on the system) - - value: "ixVolume" - description: ixVolume (Dataset created automatically by the system) - - value: "smb-pv-pvc" - description: SMB Share (Mounts a persistent volume claim to a SMB share) - - variable: mountPath - label: Mount Path - description: The path inside the container to mount the storage. - schema: - type: path - required: true - - variable: hostPath - label: Host Path - description: The host path to use for storage. - schema: - type: hostpath - show_if: [["type", "=", "hostPath"]] - required: true - - variable: datasetName - label: Dataset Name - description: The name of the dataset to use for storage. - schema: - type: string - show_if: [["type", "=", "ixVolume"]] - required: true - immutable: true - default: "storage_entry" - $ref: - - "normalize/ixVolume" - - variable: server - label: Server - description: The server for the SMB share. - schema: - type: string - show_if: [["type", "=", "smb-pv-pvc"]] - required: true - - variable: share - label: Share - description: The share name for the SMB share. - schema: - type: string - show_if: [["type", "=", "smb-pv-pvc"]] - required: true - - variable: domain - label: Domain (Optional) - description: The domain for the SMB share. - schema: - type: string - show_if: [["type", "=", "smb-pv-pvc"]] - - variable: username - label: Username - description: The username for the SMB share. - schema: - type: string - show_if: [["type", "=", "smb-pv-pvc"]] - required: true - - variable: password - label: Password - description: The password for the SMB share. - schema: - type: string - show_if: [["type", "=", "smb-pv-pvc"]] - required: true - private: true - - variable: size - label: Size (in Gi) - description: The size of the volume quota. - schema: - type: int - show_if: [["type", "=", "smb-pv-pvc"]] - required: true - min: 1 - default: 1 - - - variable: resources - label: "" - group: Resources Configuration - schema: - type: dict - attrs: - - variable: limits - label: Limits - schema: - type: dict - attrs: - - variable: cpu - label: CPU - description: CPU limit for Wordpress. - schema: - type: string - max_length: 6 - valid_chars: '^(0\.[1-9]|[1-9][0-9]*)(\.[0-9]|m?)$' - valid_chars_error: | - Valid CPU limit formats are
- - Plain Integer - eg. 1
- - Float - eg. 0.5
- - Milicpu - eg. 500m - default: "4000m" - required: true - - variable: memory - label: Memory - description: Memory limit for Wordpress. - schema: - type: string - max_length: 12 - valid_chars: '^[1-9][0-9]*([EPTGMK]i?|e[0-9]+)?$' - valid_chars_error: | - Valid Memory limit formats are
- - Suffixed with E/P/T/G/M/K - eg. 1G
- - Suffixed with Ei/Pi/Ti/Gi/Mi/Ki - eg. 1Gi
- - Plain Integer in bytes - eg. 1024
- - Exponent - eg. 134e6 - default: "8Gi" - required: true diff --git a/community/wordpress/1.1.9/Chart.lock b/community/wordpress/1.2.0/Chart.lock similarity index 100% rename from community/wordpress/1.1.9/Chart.lock rename to community/wordpress/1.2.0/Chart.lock diff --git a/community/wordpress/1.1.9/Chart.yaml b/community/wordpress/1.2.0/Chart.yaml similarity index 97% rename from community/wordpress/1.1.9/Chart.yaml rename to community/wordpress/1.2.0/Chart.yaml index 628a2c0ec4..b85678ef14 100644 --- a/community/wordpress/1.1.9/Chart.yaml +++ b/community/wordpress/1.2.0/Chart.yaml @@ -3,7 +3,7 @@ description: Wordpress is a web content management system annotations: title: Wordpress type: application -version: 1.1.9 +version: 1.2.0 apiVersion: v2 appVersion: 6.4.2 kubeVersion: '>=1.16.0-0' diff --git a/community/wordpress/1.1.9/README.md b/community/wordpress/1.2.0/README.md similarity index 100% rename from community/wordpress/1.1.9/README.md rename to community/wordpress/1.2.0/README.md diff --git a/community/wordpress/1.1.9/app-readme.md b/community/wordpress/1.2.0/app-readme.md similarity index 100% rename from community/wordpress/1.1.9/app-readme.md rename to community/wordpress/1.2.0/app-readme.md diff --git a/community/wordpress/1.1.9/charts/common-1.2.6.tgz b/community/wordpress/1.2.0/charts/common-1.2.6.tgz similarity index 100% rename from community/wordpress/1.1.9/charts/common-1.2.6.tgz rename to community/wordpress/1.2.0/charts/common-1.2.6.tgz diff --git a/community/wordpress/1.2.0/ci/basic-values.yaml b/community/wordpress/1.2.0/ci/basic-values.yaml new file mode 100644 index 0000000000..d94c10bb33 --- /dev/null +++ b/community/wordpress/1.2.0/ci/basic-values.yaml @@ -0,0 +1,10 @@ +wpStorage: + data: + type: pvc + mariadbData: + type: pvc + mariadbBackup: + type: emptyDir + emptyDirConfig: + medium: "" + size: "" diff --git a/community/wordpress/1.2.0/ci/cron-values.yaml b/community/wordpress/1.2.0/ci/cron-values.yaml new file mode 100644 index 0000000000..304f44de48 --- /dev/null +++ b/community/wordpress/1.2.0/ci/cron-values.yaml @@ -0,0 +1,14 @@ +wpConfig: + enableCronJob: true + cronSchedule: "*/1 * * * *" + +wpStorage: + data: + type: pvc + mariadbData: + type: pvc + mariadbBackup: + type: emptyDir + emptyDirConfig: + medium: "" + size: "" diff --git a/community/wordpress/1.1.9/ix_values.yaml b/community/wordpress/1.2.0/ix_values.yaml similarity index 71% rename from community/wordpress/1.1.9/ix_values.yaml rename to community/wordpress/1.2.0/ix_values.yaml index 215ab82706..88b4f799af 100644 --- a/community/wordpress/1.1.9/ix_values.yaml +++ b/community/wordpress/1.2.0/ix_values.yaml @@ -19,11 +19,14 @@ wpNetwork: wpStorage: data: type: ixVolume - datasetName: data + ixVolumeConfig: + datasetName: data mariadbData: type: ixVolume - datasetName: mariadbData + ixVolumeConfig: + datasetName: mariadbData mariadbBackup: type: ixVolume - datasetName: mariadbBackup + ixVolumeConfig: + datasetName: mariadbBackup additionalStorages: [] diff --git a/community/wordpress/1.1.9/metadata.yaml b/community/wordpress/1.2.0/metadata.yaml similarity index 100% rename from community/wordpress/1.1.9/metadata.yaml rename to community/wordpress/1.2.0/metadata.yaml diff --git a/community/wordpress/1.2.0/migrations/migrate b/community/wordpress/1.2.0/migrations/migrate new file mode 100755 index 0000000000..e0f0bea2b0 --- /dev/null +++ b/community/wordpress/1.2.0/migrations/migrate @@ -0,0 +1,73 @@ +#!/usr/bin/python3 +import json +import os +import sys + + +def storage_migrate(storage): + delete_keys = [] + if storage['type'] == 'hostPath': + # Check if the key exists, if not we have already migrated + if not storage.get('hostPath'): + return storage + + storage['hostPathConfig'] = {'hostPath': storage['hostPath']} + delete_keys.append('hostPath') + + elif storage['type'] == 'ixVolume': + # Check if the key exists, if not we have already migrated + if not storage.get('datasetName'): + return storage + + storage['ixVolumeConfig'] = {'datasetName': storage['datasetName']} + delete_keys.append('datasetName') + + elif storage['type'] == 'smb-pv-pvc': + # Check if the key exists, if not we have already migrated + if not storage.get('server'): + return storage + + storage['smbConfig'] = { + 'server': storage['server'], + 'share': storage['share'], + 'domain': storage['domain'], + 'username': storage['username'], + 'password': storage['password'], + 'size': storage['size'], + } + delete_keys.extend(['server', 'share', 'domain', 'username', 'password', 'size']) + + for key in delete_keys: + storage.pop(key, None) + + return storage + + +def migrate(values): + storage_key = 'wpStorage' + storages = ['data', 'mariadbData', 'mariadbBackup'] + + for storage in storages: + check_val = values.get(storage_key, {}).get(storage, {}) + if not isinstance(check_val, dict) or not check_val: + raise Exception(f'Storage section {storage} is malformed') + + values[storage_key][storage] = storage_migrate(check_val) + + additionalStorages = values.get(storage_key, {}).get('additionalStorages', []) + for idx, storage in enumerate(additionalStorages): + if not isinstance(storage, dict) or not storage: + raise Exception(f'Item {idx} in additionalStorages is malformed') + + values[storage_key]['additionalStorages'][idx] = storage_migrate(storage) + + return values + + +if __name__ == '__main__': + if len(sys.argv) != 2: + exit(1) + + if os.path.exists(sys.argv[1]): + with open(sys.argv[1], 'r') as f: + print(json.dumps(migrate(json.loads(f.read())))) diff --git a/community/wordpress/1.2.0/questions.yaml b/community/wordpress/1.2.0/questions.yaml new file mode 100644 index 0000000000..f10bac59c1 --- /dev/null +++ b/community/wordpress/1.2.0/questions.yaml @@ -0,0 +1,533 @@ +groups: + - name: Wordpress Configuration + description: Configure Wordpress + - name: Network Configuration + description: Configure Network for Wordpress + - name: Storage Configuration + description: Configure Storage for Wordpress + - name: Resources Configuration + description: Configure Resources for Wordpress + +portals: + web_portal: + protocols: + - "$kubernetes-resource_configmap_portal_protocol" + host: + - "$kubernetes-resource_configmap_portal_host" + ports: + - "$kubernetes-resource_configmap_portal_port" + path: "$kubernetes-resource_configmap_portal_path" + admin: + protocols: + - "$kubernetes-resource_configmap_portal_protocol" + host: + - "$kubernetes-resource_configmap_portal_host" + ports: + - "$kubernetes-resource_configmap_portal_port" + path: /wp-admin + +questions: + - variable: wpConfig + label: "" + group: Wordpress Configuration + schema: + type: dict + attrs: + - variable: enableCronJob + label: Enable CronJob + description: | + Enable CronJob for Wordpress executed by Kubernetes scheduler.
+ This will also disable running cron on page load. + schema: + type: boolean + default: false + - variable: cronSchedule + label: Cron Schedule + description: Cron schedule for Wordpress CronJob. + schema: + type: string + default: "*/15 * * * *" + show_if: [["enableCronJob", "=", true]] + required: true + - variable: additionalEnvs + label: Additional Environment Variables + description: Configure additional environment variables for Wordpress. + schema: + type: list + default: [] + items: + - variable: env + label: Environment Variable + schema: + type: dict + attrs: + - variable: name + label: Name + schema: + type: string + required: true + - variable: value + label: Value + schema: + type: string + required: true + + - variable: wpNetwork + label: "" + group: Network Configuration + schema: + type: dict + attrs: + - variable: webPort + label: Web Port + description: The port for the Wordpress WebUI. + schema: + type: int + default: 30040 + min: 9000 + max: 65535 + required: true + + - variable: wpStorage + label: "" + group: Storage Configuration + schema: + type: dict + attrs: + - variable: data + label: Wordpress Data Storage + description: The path to store Wordpress data. + schema: + type: dict + attrs: + - variable: type + label: Type + description: | + ixVolume: Is dataset created automatically by the system.
+ Host Path: Is a path that already exists on the system. + schema: + type: string + required: true + immutable: true + default: ixVolume + enum: + - value: hostPath + description: Host Path (Path that already exists on the system) + - value: ixVolume + description: ixVolume (Dataset created automatically by the system) + - variable: ixVolumeConfig + label: ixVolume Configuration + description: The configuration for the ixVolume dataset. + schema: + type: dict + show_if: [["type", "=", "ixVolume"]] + $ref: + - "normalize/ixVolume" + attrs: + - variable: aclEnable + label: Enable ACL + description: Enable ACL for the dataset. + schema: + type: boolean + default: false + - variable: datasetName + label: Dataset Name + description: The name of the dataset to use for storage. + schema: + type: string + required: true + immutable: true + hidden: true + default: "data" + - variable: aclEntries + label: ACL Configuration + schema: + type: dict + show_if: [["aclEnable", "=", true]] + attrs: [] + - variable: hostPathConfig + label: Host Path Configuration + schema: + type: dict + show_if: [["type", "=", "hostPath"]] + attrs: + - variable: aclEnable + label: Enable ACL + description: Enable ACL for the dataset. + schema: + type: boolean + default: false + - variable: acl + label: ACL Configuration + schema: + type: dict + show_if: [["aclEnable", "=", true]] + attrs: [] + $ref: + - "normalize/acl" + - variable: hostPath + label: Host Path + description: The host path to use for storage. + schema: + type: hostpath + show_if: [["aclEnable", "=", false]] + required: true + + - variable: mariadbData + label: Wordpress MariaDB Data Storage + description: The path to store Wordpress MariaDB Data. + schema: + type: dict + attrs: + - variable: type + label: Type + description: | + ixVolume: Is dataset created automatically by the system.
+ Host Path: Is a path that already exists on the system. + schema: + type: string + required: true + immutable: true + default: ixVolume + enum: + - value: hostPath + description: Host Path (Path that already exists on the system) + - value: ixVolume + description: ixVolume (Dataset created automatically by the system) + - variable: ixVolumeConfig + label: ixVolume Configuration + description: The configuration for the ixVolume dataset. + schema: + type: dict + # Nothing to show for the user + hidden: true + show_if: [["type", "=", "ixVolume"]] + $ref: + - "normalize/ixVolume" + attrs: + - variable: aclEnable + label: Enable ACL + description: Enable ACL for the dataset. + schema: + type: boolean + # MariaDB does a CHMOD at startup + # Which fails with ACL + hidden: true + default: false + - variable: datasetName + label: Dataset Name + description: The name of the dataset to use for storage. + schema: + type: string + required: true + immutable: true + hidden: true + default: mariadbData + - variable: aclEntries + label: ACL Configuration + schema: + type: dict + show_if: [["aclEnable", "=", true]] + attrs: [] + - variable: hostPathConfig + label: Host Path Configuration + schema: + type: dict + show_if: [["type", "=", "hostPath"]] + attrs: + - variable: aclEnable + label: Enable ACL + description: Enable ACL for the dataset. + schema: + type: boolean + # MariaDB does a CHMOD at startup + # Which fails with ACL + hidden: true + default: false + - variable: acl + label: ACL Configuration + schema: + type: dict + show_if: [["aclEnable", "=", true]] + attrs: [] + $ref: + - "normalize/acl" + - variable: hostPath + label: Host Path + description: The host path to use for storage. + schema: + type: hostpath + show_if: [["aclEnable", "=", false]] + required: true + + - variable: mariadbBackup + label: Wordpress MariaDB Backup Storage + description: The path to store Wordpress MariaDB Backup. + schema: + type: dict + attrs: + - variable: type + label: Type + description: | + ixVolume: Is dataset created automatically by the system.
+ Host Path: Is a path that already exists on the system. + schema: + type: string + required: true + immutable: true + default: ixVolume + enum: + - value: hostPath + description: Host Path (Path that already exists on the system) + - value: ixVolume + description: ixVolume (Dataset created automatically by the system) + - variable: ixVolumeConfig + label: ixVolume Configuration + description: The configuration for the ixVolume dataset. + schema: + type: dict + # Nothing to show for the user + hidden: true + show_if: [["type", "=", "ixVolume"]] + $ref: + - "normalize/ixVolume" + attrs: + - variable: aclEnable + label: Enable ACL + description: Enable ACL for the dataset. + schema: + type: boolean + # MariaDB does a CHMOD at startup + # Which fails with ACL + hidden: true + default: false + - variable: datasetName + label: Dataset Name + description: The name of the dataset to use for storage. + schema: + type: string + required: true + immutable: true + hidden: true + default: mariadbBackup + - variable: aclEntries + label: ACL Configuration + schema: + type: dict + show_if: [["aclEnable", "=", true]] + attrs: [] + - variable: hostPathConfig + label: Host Path Configuration + schema: + type: dict + show_if: [["type", "=", "hostPath"]] + attrs: + - variable: aclEnable + label: Enable ACL + description: Enable ACL for the dataset. + schema: + type: boolean + # MariaDB does a CHMOD at startup + # Which fails with ACL + hidden: true + default: false + - variable: acl + label: ACL Configuration + schema: + type: dict + show_if: [["aclEnable", "=", true]] + attrs: [] + $ref: + - "normalize/acl" + - variable: hostPath + label: Host Path + description: The host path to use for storage. + schema: + type: hostpath + show_if: [["aclEnable", "=", false]] + required: true + + - variable: additionalStorages + label: Additional Storage + description: Additional storage for Wordpress. + schema: + type: list + default: [] + items: + - variable: storageEntry + label: Storage Entry + schema: + type: dict + attrs: + - variable: type + label: Type + description: | + ixVolume: Is dataset created automatically by the system.
+ Host Path: Is a path that already exists on the system.
+ SMB Share: Is a SMB share that is mounted to a persistent volume claim. + schema: + type: string + required: true + default: "ixVolume" + immutable: true + enum: + - value: "hostPath" + description: Host Path (Path that already exists on the system) + - value: "ixVolume" + description: ixVolume (Dataset created automatically by the system) + - value: "smb-pv-pvc" + description: SMB Share (Mounts a persistent volume claim to a SMB share) + - variable: readOnly + label: Read Only + description: Mount the volume as read only. + schema: + type: boolean + default: false + - variable: mountPath + label: Mount Path + description: The path inside the container to mount the storage. + schema: + type: path + required: true + - variable: hostPathConfig + label: Host Path Configuration + schema: + type: dict + show_if: [["type", "=", "hostPath"]] + attrs: + - variable: aclEnable + label: Enable ACL + description: Enable ACL for the dataset. + schema: + type: boolean + default: false + - variable: acl + label: ACL Configuration + schema: + type: dict + show_if: [["aclEnable", "=", true]] + attrs: [] + $ref: + - "normalize/acl" + - variable: hostPath + label: Host Path + description: The host path to use for storage. + schema: + type: hostpath + show_if: [["aclEnable", "=", false]] + required: true + - variable: ixVolumeConfig + label: ixVolume Configuration + description: The configuration for the ixVolume dataset. + schema: + type: dict + show_if: [["type", "=", "ixVolume"]] + $ref: + - "normalize/ixVolume" + attrs: + - variable: aclEnable + label: Enable ACL + description: Enable ACL for the dataset. + schema: + type: boolean + default: false + - variable: datasetName + label: Dataset Name + description: The name of the dataset to use for storage. + schema: + type: string + required: true + immutable: true + default: "storage_entry" + - variable: aclEntries + label: ACL Configuration + schema: + type: dict + show_if: [["aclEnable", "=", true]] + attrs: [] + - variable: smbConfig + label: SMB Share Configuration + description: The configuration for the SMB Share. + schema: + type: dict + show_if: [["type", "=", "smb-pv-pvc"]] + attrs: + - variable: server + label: Server + description: The server for the SMB share. + schema: + type: string + required: true + - variable: share + label: Share + description: The share name for the SMB share. + schema: + type: string + required: true + - variable: domain + label: Domain (Optional) + description: The domain for the SMB share. + schema: + type: string + - variable: username + label: Username + description: The username for the SMB share. + schema: + type: string + required: true + - variable: password + label: Password + description: The password for the SMB share. + schema: + type: string + required: true + private: true + - variable: size + label: Size (in Gi) + description: The size of the volume quota. + schema: + type: int + required: true + min: 1 + default: 1 + + - variable: resources + label: "" + group: Resources Configuration + schema: + type: dict + attrs: + - variable: limits + label: Limits + schema: + type: dict + attrs: + - variable: cpu + label: CPU + description: CPU limit for Wordpress. + schema: + type: string + max_length: 6 + valid_chars: '^(0\.[1-9]|[1-9][0-9]*)(\.[0-9]|m?)$' + valid_chars_error: | + Valid CPU limit formats are
+ - Plain Integer - eg. 1
+ - Float - eg. 0.5
+ - Milicpu - eg. 500m + default: "4000m" + required: true + - variable: memory + label: Memory + description: Memory limit for Wordpress. + schema: + type: string + max_length: 12 + valid_chars: '^[1-9][0-9]*([EPTGMK]i?|e[0-9]+)?$' + valid_chars_error: | + Valid Memory limit formats are
+ - Suffixed with E/P/T/G/M/K - eg. 1G
+ - Suffixed with Ei/Pi/Ti/Gi/Mi/Ki - eg. 1Gi
+ - Plain Integer in bytes - eg. 1024
+ - Exponent - eg. 134e6 + default: "8Gi" + required: true diff --git a/community/wordpress/1.1.9/templates/NOTES.txt b/community/wordpress/1.2.0/templates/NOTES.txt similarity index 100% rename from community/wordpress/1.1.9/templates/NOTES.txt rename to community/wordpress/1.2.0/templates/NOTES.txt diff --git a/community/wordpress/1.1.9/templates/_configuration.tpl b/community/wordpress/1.2.0/templates/_configuration.tpl similarity index 100% rename from community/wordpress/1.1.9/templates/_configuration.tpl rename to community/wordpress/1.2.0/templates/_configuration.tpl diff --git a/community/wordpress/1.1.9/templates/_cron.tpl b/community/wordpress/1.2.0/templates/_cron.tpl similarity index 100% rename from community/wordpress/1.1.9/templates/_cron.tpl rename to community/wordpress/1.2.0/templates/_cron.tpl diff --git a/community/wordpress/1.1.9/templates/_mariadb.tpl b/community/wordpress/1.2.0/templates/_mariadb.tpl similarity index 100% rename from community/wordpress/1.1.9/templates/_mariadb.tpl rename to community/wordpress/1.2.0/templates/_mariadb.tpl diff --git a/community/wordpress/1.1.9/templates/_persistence.tpl b/community/wordpress/1.2.0/templates/_persistence.tpl similarity index 52% rename from community/wordpress/1.1.9/templates/_persistence.tpl rename to community/wordpress/1.2.0/templates/_persistence.tpl index 405d7af3f8..f02393809c 100644 --- a/community/wordpress/1.1.9/templates/_persistence.tpl +++ b/community/wordpress/1.2.0/templates/_persistence.tpl @@ -2,44 +2,33 @@ persistence: data: enabled: true - type: {{ .Values.wpStorage.data.type }} - datasetName: {{ .Values.wpStorage.data.datasetName | default "" }} - hostPath: {{ .Values.wpStorage.data.hostPath | default "" }} + {{- include "wp.storage.ci.migration" (dict "storage" .Values.wpStorage.data) }} + {{- include "ix.v1.common.app.storageOptions" (dict "storage" .Values.wpStorage.data) | nindent 4 }} targetSelector: wordpress: wordpress: mountPath: /var/www/html + {{- if and (eq .Values.wpStorage.data.type "ixVolume") + (not (.Values.wpStorage.data.ixVolumeConfig | default dict).aclEnable) }} 01-permissions: mountPath: /mnt/directories/data + {{- end }} wordpress-cron: wordpress-cron: mountPath: /var/www/html {{- range $idx, $storage := .Values.wpStorage.additionalStorages }} {{ printf "wp-%v" (int $idx) }}: - {{- $size := "" -}} - {{- if $storage.size -}} - {{- $size = (printf "%vGi" $storage.size) -}} - {{- end }} enabled: true - type: {{ $storage.type }} - datasetName: {{ $storage.datasetName | default "" }} - hostPath: {{ $storage.hostPath | default "" }} - server: {{ $storage.server | default "" }} - share: {{ $storage.share | default "" }} - domain: {{ $storage.domain | default "" }} - username: {{ $storage.username | default "" }} - password: {{ $storage.password | default "" }} - size: {{ $size }} - {{- if eq $storage.type "smb-pv-pvc" }} - mountOptions: - - key: noperm - {{- end }} + {{- include "wp.storage.ci.migration" (dict "storage" $storage) }} + {{- include "ix.v1.common.app.storageOptions" (dict "storage" $storage) | nindent 4 }} targetSelector: wordpress: wordpress: mountPath: {{ $storage.mountPath }} + {{- if and (eq $storage.type "ixVolume") (not ($storage.ixVolumeConfig | default dict).aclEnable) }} 01-permissions: mountPath: /mnt/directories{{ $storage.mountPath }} + {{- end }} {{- end }} tmp: enabled: true @@ -57,9 +46,8 @@ persistence: mountPath: /var/run mariadbdata: enabled: true - type: {{ .Values.wpStorage.mariadbData.type }} - datasetName: {{ .Values.wpStorage.mariadbData.datasetName | default "" }} - hostPath: {{ .Values.wpStorage.mariadbData.hostPath | default "" }} + {{- include "wp.storage.ci.migration" (dict "storage" .Values.wpStorage.mariadbData) }} + {{- include "ix.v1.common.app.storageOptions" (dict "storage" .Values.wpStorage.mariadbData) | nindent 4 }} targetSelector: # MariaDB pod mariadb: @@ -71,9 +59,8 @@ persistence: mountPath: /mnt/directories/mariadb_data mariadbbackup: enabled: true - type: {{ .Values.wpStorage.mariadbBackup.type }} - datasetName: {{ .Values.wpStorage.mariadbBackup.datasetName | default "" }} - hostPath: {{ .Values.wpStorage.mariadbBackup.hostPath | default "" }} + {{- include "wp.storage.ci.migration" (dict "storage" .Values.wpStorage.mariadbBackup) }} + {{- include "ix.v1.common.app.storageOptions" (dict "storage" .Values.wpStorage.mariadbBackup) | nindent 4 }} targetSelector: # MariaDB backup pod mariadbbackup: @@ -84,3 +71,13 @@ persistence: permissions: mountPath: /mnt/directories/mariadb_backup {{- end -}} + +{{/* TODO: Remove on the next version bump, eg 1.2.0+ */}} +{{- define "wp.storage.ci.migration" -}} + {{- $storage := .storage -}} + + {{- if $storage.hostPath -}} + {{- $_ := set $storage "hostPathConfig" dict -}} + {{- $_ := set $storage.hostPathConfig "hostPath" $storage.hostPath -}} + {{- end -}} +{{- end -}} diff --git a/community/wordpress/1.1.9/templates/_portal.tpl b/community/wordpress/1.2.0/templates/_portal.tpl similarity index 100% rename from community/wordpress/1.1.9/templates/_portal.tpl rename to community/wordpress/1.2.0/templates/_portal.tpl diff --git a/community/wordpress/1.1.9/templates/_service.tpl b/community/wordpress/1.2.0/templates/_service.tpl similarity index 100% rename from community/wordpress/1.1.9/templates/_service.tpl rename to community/wordpress/1.2.0/templates/_service.tpl diff --git a/community/wordpress/1.1.9/templates/_wordpress.tpl b/community/wordpress/1.2.0/templates/_wordpress.tpl similarity index 100% rename from community/wordpress/1.1.9/templates/_wordpress.tpl rename to community/wordpress/1.2.0/templates/_wordpress.tpl diff --git a/community/wordpress/1.1.9/templates/common.yaml b/community/wordpress/1.2.0/templates/common.yaml similarity index 100% rename from community/wordpress/1.1.9/templates/common.yaml rename to community/wordpress/1.2.0/templates/common.yaml diff --git a/test/minio/1.1.0/Chart.lock b/test/minio/1.1.0/Chart.lock new file mode 100644 index 0000000000..4a156de2e3 --- /dev/null +++ b/test/minio/1.1.0/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: common + repository: file://../../../common + version: 1.2.6 +digest: sha256:956cef64e364b567d2e5327a00e60b68f3ef765e003d6c35afc143bb81ecc26b +generated: "2024-01-02T19:33:31.872916193+02:00" diff --git a/test/minio/1.1.0/Chart.yaml b/test/minio/1.1.0/Chart.yaml new file mode 100644 index 0000000000..00c796ff51 --- /dev/null +++ b/test/minio/1.1.0/Chart.yaml @@ -0,0 +1,26 @@ +name: minio +description: High Performance, Kubernetes Native Object Storage +annotations: + title: MinIO +type: application +version: 1.1.0 +apiVersion: v2 +appVersion: '2023-12-07' +kubeVersion: '>=1.16.0-0' +maintainers: + - name: truenas + url: https://www.truenas.com/ + email: dev@ixsystems.com +dependencies: + - name: common + repository: file://../../../common + version: 1.2.6 +home: https://min.io +icon: https://media.sys.truenas.net/apps/minio/icons/icon.png +sources: + - https://github.com/minio/minio + - https://github.com/truenas/charts/tree/master/enterprise/minio +keywords: + - storage + - object-storage + - S3 diff --git a/test/minio/1.1.0/README.md b/test/minio/1.1.0/README.md new file mode 100644 index 0000000000..f4c20c7e50 --- /dev/null +++ b/test/minio/1.1.0/README.md @@ -0,0 +1,16 @@ +# MinIO + +[MinIO](https://min.io) is a High Performance Object Storage released under Apache License v2.0. +It is API compatible with Amazon S3 cloud storage service. Use MinIO to build high performance infrastructure +for machine learning, analytics and application data workloads. + +> During the installation process, a container will be launched with **root** privileges. This is required +> in order to apply the correct permissions to the MinIO data directory. Afterward, the `MinIO` container +> will run as a **non**-root user (`568`). +> Same applies to the `postgres` container. This will run afterwards as a **non**-root user (`999`). +> On each upgrade, a container will be launched with **root** privileges in order to apply the correct +> permissions to the `postgres` backups directory. Container that performs the backup will run as a **non**-root user (`999`) afterwards. +> Keep in mind the permissions on the backup directory will be changed to `999:999` on **every** update. +> But will only be changed once for the `MinIO` and `postgres` data directories. + +When Multi Mode is enabled and entries contain `://` (url) will enable Host Networking. Regardless of the selection in the `Networking` section. diff --git a/test/minio/1.1.0/app-readme.md b/test/minio/1.1.0/app-readme.md new file mode 100644 index 0000000000..f4c20c7e50 --- /dev/null +++ b/test/minio/1.1.0/app-readme.md @@ -0,0 +1,16 @@ +# MinIO + +[MinIO](https://min.io) is a High Performance Object Storage released under Apache License v2.0. +It is API compatible with Amazon S3 cloud storage service. Use MinIO to build high performance infrastructure +for machine learning, analytics and application data workloads. + +> During the installation process, a container will be launched with **root** privileges. This is required +> in order to apply the correct permissions to the MinIO data directory. Afterward, the `MinIO` container +> will run as a **non**-root user (`568`). +> Same applies to the `postgres` container. This will run afterwards as a **non**-root user (`999`). +> On each upgrade, a container will be launched with **root** privileges in order to apply the correct +> permissions to the `postgres` backups directory. Container that performs the backup will run as a **non**-root user (`999`) afterwards. +> Keep in mind the permissions on the backup directory will be changed to `999:999` on **every** update. +> But will only be changed once for the `MinIO` and `postgres` data directories. + +When Multi Mode is enabled and entries contain `://` (url) will enable Host Networking. Regardless of the selection in the `Networking` section. diff --git a/test/minio/1.1.0/charts/common-1.2.6.tgz b/test/minio/1.1.0/charts/common-1.2.6.tgz new file mode 100644 index 0000000000000000000000000000000000000000..77b6c4064197231782c2192e40c5c65ee34bb665 GIT binary patch literal 63149 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 literal 0 HcmV?d00001 diff --git a/test/minio/1.1.0/ci/snmd-https-values.yaml b/test/minio/1.1.0/ci/snmd-https-values.yaml new file mode 100644 index 0000000000..66a6de8c69 --- /dev/null +++ b/test/minio/1.1.0/ci/snmd-https-values.yaml @@ -0,0 +1,118 @@ +# When inside the versioned minio folder, run: +# helm dependency update +# helm template -f ix_values.yaml -f ci/basic-https-values.yaml . + +# Always use a unique hostPath for each test +# Release.Namespace is guaranteed to be a unique value +# in the test environment (ct-install) + +minioCreds: + rootUser: minio_test + rootPass: minio_test + +minioRunAs: + user: 1000 + group: 1000 + +minioNetwork: + certificateID: 1 + +minioMultiMode: + - /data{1...4} + +minioStorage: + - type: pvc + mountPath: /data1 + - type: pvc + mountPath: /data2 + - type: pvc + mountPath: /data3 + - type: pvc + mountPath: /data4 + +ixCertificates: + "1": + certificate: | + -----BEGIN CERTIFICATE----- + MIIEdjCCA16gAwIBAgIDYFMYMA0GCSqGSIb3DQEBCwUAMGwxDDAKBgNVBAMMA2Fz + ZDELMAkGA1UEBhMCVVMxDTALBgNVBAgMBGFzZGYxCzAJBgNVBAcMAmFmMQ0wCwYD + VQQKDARhc2RmMQwwCgYDVQQLDANhc2QxFjAUBgkqhkiG9w0BCQEWB2FAYS5jb20w + HhcNMjEwODMwMjMyMzU0WhcNMjMxMjAzMjMyMzU0WjBuMQswCQYDVQQDDAJhZDEL + MAkGA1UEBhMCVVMxDTALBgNVBAgMBGFzZGYxDTALBgNVBAcMBGFzZGYxDTALBgNV + BAoMBGFkc2YxDTALBgNVBAsMBGFzZGYxFjAUBgkqhkiG9w0BCQEWB2FAYS5jb20w + ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC7+1xOHRQyOnQTHFcrdasX + Zl0gzutVlA890a1wiQpdD5dOtCLo7+eqVYjqVKo9W8RUIArXWmBu/AbkH7oVFWC1 + P973W1+ArF5sA70f7BZgqRKJTIisuIFIlRETgfnP2pfQmHRZtGaIJRZI4vQCdYgW + 2g0KOvvNcZJCVq1OrhKiNiY1bWCp66DGg0ic6OEkZFHTm745zUNQaf2dNgsxKU0H + PGjVLJI//yrRFAOSBUqgD4c50krnMF7fU/Fqh+UyOu8t6Y/HsySh3urB+Zie331t + AzV6QV39KKxRflNx/yuWrtIEslGTm+xHKoCYJEk/nZ3mX8Y5hG6wWAb7A/FuDVg3 + AgMBAAGjggEdMIIBGTAnBgNVHREEIDAehwTAqAADhwTAqAAFhwTAqAC2hwTAqACB + hwTAqACSMB0GA1UdDgQWBBQ4G2ff4tgZl4vmo4xCfqmJhdqShzAMBgNVHRMBAf8E + AjAAMIGYBgNVHSMEgZAwgY2AFLlYf9L99nxJDcpCM/LT3V5hQ/a3oXCkbjBsMQww + CgYDVQQDDANhc2QxCzAJBgNVBAYTAlVTMQ0wCwYDVQQIDARhc2RmMQswCQYDVQQH + DAJhZjENMAsGA1UECgwEYXNkZjEMMAoGA1UECwwDYXNkMRYwFAYJKoZIhvcNAQkB + FgdhQGEuY29tggNgUxcwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwEwDgYDVR0PAQH/ + BAQDAgWgMA0GCSqGSIb3DQEBCwUAA4IBAQA6FpOInEHB5iVk3FP67GybJ29vHZTD + KQHbQgmg8s4L7qIsA1HQ+DMCbdylpA11x+t/eL/n48BvGw2FNXpN6uykhLHJjbKR + h8yITa2KeD3LjLYhScwIigXmTVYSP3km6s8jRL6UKT9zttnIHyXVpBDya6Q4WTMx + fmfC6O7t1PjQ5ZyVtzizIUP8ah9n4TKdXU4A3QIM6WsJXpHb+vqp1WDWJ7mKFtgj + x5TKv3wcPnktx0zMPfLb5BTSE9rc9djcBG0eIAsPT4FgiatCUChe7VhuMnqskxEz + MymJLoq8+mzucRwFkOkR2EIt1x+Irl2mJVMeBow63rVZfUQBD8h++LqB + -----END CERTIFICATE----- + + -----BEGIN CERTIFICATE----- + MIIEhDCCA2ygAwIBAgIDYFMXMA0GCSqGSIb3DQEBCwUAMGwxDDAKBgNVBAMMA2Fz + ZDELMAkGA1UEBhMCVVMxDTALBgNVBAgMBGFzZGYxCzAJBgNVBAcMAmFmMQ0wCwYD + VQQKDARhc2RmMQwwCgYDVQQLDANhc2QxFjAUBgkqhkiG9w0BCQEWB2FAYS5jb20w + HhcNMjEwODMwMjMyMDQ1WhcNMzEwODI4MjMyMDQ1WjBsMQwwCgYDVQQDDANhc2Qx + CzAJBgNVBAYTAlVTMQ0wCwYDVQQIDARhc2RmMQswCQYDVQQHDAJhZjENMAsGA1UE + CgwEYXNkZjEMMAoGA1UECwwDYXNkMRYwFAYJKoZIhvcNAQkBFgdhQGEuY29tMIIB + IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAq//c0hEEr83CS1pMgsHX50jt + 2MqIbcf63UUNJTiYpUUvUQSFJFc7m/dr+RTZvu97eDCnD5K2qkHHvTPaPZwY+Djf + iy7N641Sz6u/y3Yo3xxs1Aermsfedh48vusJpjbkT2XS44VjbkrpKcWDNVpp3Evd + M7oJotXeUsZ+imiyVCfr4YhoY5gbGh/r+KN9Wf9YKoUyfLLZGwdZkhtX2zIbidsL + Thqi9YTaUHttGinjiBBum234u/CfvKXsfG3yP2gvBGnlvZnM9ktv+lVffYNqlf7H + VmB1bKKk84HtzuW5X76SGAgOG8eHX4x5ZLI1WQUuoQOVRl1I0UCjBtbz8XhwvQID + AQABo4IBLTCCASkwLQYDVR0RBCYwJIcEwKgABYcEwKgAA4cEwKgAkocEwKgAtYcE + wKgAgYcEwKgAtjAdBgNVHQ4EFgQUuVh/0v32fEkNykIz8tPdXmFD9rcwDwYDVR0T + AQH/BAUwAwEB/zCBmAYDVR0jBIGQMIGNgBS5WH/S/fZ8SQ3KQjPy091eYUP2t6Fw + pG4wbDEMMAoGA1UEAwwDYXNkMQswCQYDVQQGEwJVUzENMAsGA1UECAwEYXNkZjEL + MAkGA1UEBwwCYWYxDTALBgNVBAoMBGFzZGYxDDAKBgNVBAsMA2FzZDEWMBQGCSqG + SIb3DQEJARYHYUBhLmNvbYIDYFMXMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEF + BQcDAjAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBAKEocOmVuWlr + zegtKYMe8NhHIkFY9oVn5ym6RHNOJpPH4QF8XYC3Z5+iC5yGh4P/jVe/4I4SF6Ql + PtofU0jNq5vzapt/y+m008eXqPQFmoUOvu+JavoRVcRx2LIP5AgBA1mF56CSREsX + TkuJAA9IUQ8EjnmAoAeKINuPaKxGDuU8BGCMqr/qd564MKNf9XYL+Fb2rlkA0O2d + 2No34DQLgqSmST/LAvPM7Cbp6knYgnKmGr1nETCXasg1cueHLnWWTvps2HiPp2D/ + +Fq0uqcZLu4Mdo0CPs4e5sHRyldEnRSKh0DVLprq9zr/GMipmPLJUsT5Jed3sj0w + M7Y3vwxshpo= + -----END CERTIFICATE----- + privatekey: | + -----BEGIN PRIVATE KEY----- + MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC7+1xOHRQyOnQT + HFcrdasXZl0gzutVlA890a1wiQpdD5dOtCLo7+eqVYjqVKo9W8RUIArXWmBu/Abk + H7oVFWC1P973W1+ArF5sA70f7BZgqRKJTIisuIFIlRETgfnP2pfQmHRZtGaIJRZI + 4vQCdYgW2g0KOvvNcZJCVq1OrhKiNiY1bWCp66DGg0ic6OEkZFHTm745zUNQaf2d + NgsxKU0HPGjVLJI//yrRFAOSBUqgD4c50krnMF7fU/Fqh+UyOu8t6Y/HsySh3urB + +Zie331tAzV6QV39KKxRflNx/yuWrtIEslGTm+xHKoCYJEk/nZ3mX8Y5hG6wWAb7 + A/FuDVg3AgMBAAECggEAapt30rj9DitGTtxAt13pJMEhyYxvvD3WkvmJwguF/Bbu + eW0Ba1c668fMeRCA54FWi1sMqusPS4HUqqUvk+tmyAOsAF4qgD/A4MMSC7uJSVI5 + N/JWhJWyhCY94/FPakiO1nbPbVw41bcqtzU2qvparpME2CtxSCbDiqm7aaag3Kqe + EF0fGSUdZ+TYl9JM05+eIyiX+UY19Fg0OjTHMn8nGpxcNTfDBdQ68TKvdo/dtIKL + PLKzJUNNdM8odC4CvQtfGMqaslwZwXkiOl5VJcW21ncj/Y0ngEMKeD/i65ZoqGdR + 0FKCQYEAGtM2FvJcZQ92Wsw7yj2bK2MSegVUyLK32QKBgQDe8syVCepPzRsfjfxA + 6TZlWcGuTZLhwIx97Ktw3VcQ1f4rLoEYlv0xC2VWBORpzIsJo4I/OLmgp8a+Ga8z + FkVRnq90dV3t4NP9uJlHgcODHnOardC2UUka4olBSCG6zmK4Jxi34lOxhGRkshOo + L4IBeOIB5g+ZrEEXkzfYJHESRQKBgQDX2YhFhGIrT8BAnC5BbXbhm8h6Bhjz8DYL + d+qhVJjef7L/aJxViU0hX9Ba2O8CLK3FZeREFE3hJPiJ4TZSlN4evxs5p+bbNDcA + 0mhRI/o3X4ac6IxdRebyYnCOB/Cu94/MzppcZcotlCekKNike7eorCcX4Qavm7Pu + MUuQ+ifmSwKBgEnchoqZzlbBzMqXb4rRuIO7SL9GU/MWp3TQg7vQmJerTZlgvsQ2 + wYsOC3SECmhCq4117iCj2luvOdihCboTFsQDnn0mpQe6BIF6Ns3J38wAuqv0CcFd + DKsrge1uyD3rQilgSoAhKzkUc24o0PpXQurZ8YZPgbuXpbj5vPaOnCdBAoGACYc7 + wb3XS4wos3FxhUfcwJbM4b4VKeeHqzfu7pI6cU/3ydiHVitKcVe2bdw3qMPqI9Wc + nvi6e17Tbdq4OCsEJx1OiVwFD9YdO3cOTc6lw/3+hjypvZBRYo+/4jUthbu96E+S + dtOzehGZMmDvN0uSzupSi3ZOgkAAUFpyuIKickMCgYAId0PCRjonO2thn/R0rZ7P + //L852uyzYhXKw5/fjFGhQ6LbaLgIRFaCZ0L2809u0HFnNvJjHv4AKP6j+vFQYYY + qQ+66XnfsA9G/bu4MDS9AX83iahD9IdLXQAy8I19prAbpVumKegPbMnNYNB/TYEc + 3G15AKCXo7jjOUtHY01DCQ== + -----END PRIVATE KEY----- diff --git a/test/minio/1.1.0/ci/snmd-logsearch-https-values.yaml b/test/minio/1.1.0/ci/snmd-logsearch-https-values.yaml new file mode 100644 index 0000000000..11631ab912 --- /dev/null +++ b/test/minio/1.1.0/ci/snmd-logsearch-https-values.yaml @@ -0,0 +1,130 @@ +# When inside the versioned minio folder, run: +# helm dependency update +# helm template -f ix_values.yaml -f ci/logsearch-https-values.yaml . + +# Always use a unique hostPath for each test +# Release.Namespace is guaranteed to be a unique value +# in the test environment (ct-install) + +minioCreds: + rootUser: minio_test + rootPass: minio_test + +minioNetwork: + certificateID: 1 + +minioRunAs: + user: 1000 + group: 1000 + +minioMultiMode: + - /data{1...4} + +minioStorage: + - type: pvc + mountPath: /data1 + - type: pvc + mountPath: /data2 + - type: pvc + mountPath: /data3 + - type: pvc + mountPath: /data4 + +minioLogging: + logsearch: + enabled: true + diskCapacityGB: 5 + pgData: + type: pvc + pgBackup: + type: emptyDir + emptyDirConfig: + size: "" + medium: "" + +ixCertificates: + "1": + certificate: | + -----BEGIN CERTIFICATE----- + MIIEdjCCA16gAwIBAgIDYFMYMA0GCSqGSIb3DQEBCwUAMGwxDDAKBgNVBAMMA2Fz + ZDELMAkGA1UEBhMCVVMxDTALBgNVBAgMBGFzZGYxCzAJBgNVBAcMAmFmMQ0wCwYD + VQQKDARhc2RmMQwwCgYDVQQLDANhc2QxFjAUBgkqhkiG9w0BCQEWB2FAYS5jb20w + HhcNMjEwODMwMjMyMzU0WhcNMjMxMjAzMjMyMzU0WjBuMQswCQYDVQQDDAJhZDEL + MAkGA1UEBhMCVVMxDTALBgNVBAgMBGFzZGYxDTALBgNVBAcMBGFzZGYxDTALBgNV + BAoMBGFkc2YxDTALBgNVBAsMBGFzZGYxFjAUBgkqhkiG9w0BCQEWB2FAYS5jb20w + ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC7+1xOHRQyOnQTHFcrdasX + Zl0gzutVlA890a1wiQpdD5dOtCLo7+eqVYjqVKo9W8RUIArXWmBu/AbkH7oVFWC1 + P973W1+ArF5sA70f7BZgqRKJTIisuIFIlRETgfnP2pfQmHRZtGaIJRZI4vQCdYgW + 2g0KOvvNcZJCVq1OrhKiNiY1bWCp66DGg0ic6OEkZFHTm745zUNQaf2dNgsxKU0H + PGjVLJI//yrRFAOSBUqgD4c50krnMF7fU/Fqh+UyOu8t6Y/HsySh3urB+Zie331t + AzV6QV39KKxRflNx/yuWrtIEslGTm+xHKoCYJEk/nZ3mX8Y5hG6wWAb7A/FuDVg3 + AgMBAAGjggEdMIIBGTAnBgNVHREEIDAehwTAqAADhwTAqAAFhwTAqAC2hwTAqACB + hwTAqACSMB0GA1UdDgQWBBQ4G2ff4tgZl4vmo4xCfqmJhdqShzAMBgNVHRMBAf8E + AjAAMIGYBgNVHSMEgZAwgY2AFLlYf9L99nxJDcpCM/LT3V5hQ/a3oXCkbjBsMQww + CgYDVQQDDANhc2QxCzAJBgNVBAYTAlVTMQ0wCwYDVQQIDARhc2RmMQswCQYDVQQH + DAJhZjENMAsGA1UECgwEYXNkZjEMMAoGA1UECwwDYXNkMRYwFAYJKoZIhvcNAQkB + FgdhQGEuY29tggNgUxcwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwEwDgYDVR0PAQH/ + BAQDAgWgMA0GCSqGSIb3DQEBCwUAA4IBAQA6FpOInEHB5iVk3FP67GybJ29vHZTD + KQHbQgmg8s4L7qIsA1HQ+DMCbdylpA11x+t/eL/n48BvGw2FNXpN6uykhLHJjbKR + h8yITa2KeD3LjLYhScwIigXmTVYSP3km6s8jRL6UKT9zttnIHyXVpBDya6Q4WTMx + fmfC6O7t1PjQ5ZyVtzizIUP8ah9n4TKdXU4A3QIM6WsJXpHb+vqp1WDWJ7mKFtgj + x5TKv3wcPnktx0zMPfLb5BTSE9rc9djcBG0eIAsPT4FgiatCUChe7VhuMnqskxEz + MymJLoq8+mzucRwFkOkR2EIt1x+Irl2mJVMeBow63rVZfUQBD8h++LqB + -----END CERTIFICATE----- + + -----BEGIN CERTIFICATE----- + MIIEhDCCA2ygAwIBAgIDYFMXMA0GCSqGSIb3DQEBCwUAMGwxDDAKBgNVBAMMA2Fz + ZDELMAkGA1UEBhMCVVMxDTALBgNVBAgMBGFzZGYxCzAJBgNVBAcMAmFmMQ0wCwYD + VQQKDARhc2RmMQwwCgYDVQQLDANhc2QxFjAUBgkqhkiG9w0BCQEWB2FAYS5jb20w + HhcNMjEwODMwMjMyMDQ1WhcNMzEwODI4MjMyMDQ1WjBsMQwwCgYDVQQDDANhc2Qx + CzAJBgNVBAYTAlVTMQ0wCwYDVQQIDARhc2RmMQswCQYDVQQHDAJhZjENMAsGA1UE + CgwEYXNkZjEMMAoGA1UECwwDYXNkMRYwFAYJKoZIhvcNAQkBFgdhQGEuY29tMIIB + IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAq//c0hEEr83CS1pMgsHX50jt + 2MqIbcf63UUNJTiYpUUvUQSFJFc7m/dr+RTZvu97eDCnD5K2qkHHvTPaPZwY+Djf + iy7N641Sz6u/y3Yo3xxs1Aermsfedh48vusJpjbkT2XS44VjbkrpKcWDNVpp3Evd + M7oJotXeUsZ+imiyVCfr4YhoY5gbGh/r+KN9Wf9YKoUyfLLZGwdZkhtX2zIbidsL + Thqi9YTaUHttGinjiBBum234u/CfvKXsfG3yP2gvBGnlvZnM9ktv+lVffYNqlf7H + VmB1bKKk84HtzuW5X76SGAgOG8eHX4x5ZLI1WQUuoQOVRl1I0UCjBtbz8XhwvQID + AQABo4IBLTCCASkwLQYDVR0RBCYwJIcEwKgABYcEwKgAA4cEwKgAkocEwKgAtYcE + wKgAgYcEwKgAtjAdBgNVHQ4EFgQUuVh/0v32fEkNykIz8tPdXmFD9rcwDwYDVR0T + AQH/BAUwAwEB/zCBmAYDVR0jBIGQMIGNgBS5WH/S/fZ8SQ3KQjPy091eYUP2t6Fw + pG4wbDEMMAoGA1UEAwwDYXNkMQswCQYDVQQGEwJVUzENMAsGA1UECAwEYXNkZjEL + MAkGA1UEBwwCYWYxDTALBgNVBAoMBGFzZGYxDDAKBgNVBAsMA2FzZDEWMBQGCSqG + SIb3DQEJARYHYUBhLmNvbYIDYFMXMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEF + BQcDAjAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBAKEocOmVuWlr + zegtKYMe8NhHIkFY9oVn5ym6RHNOJpPH4QF8XYC3Z5+iC5yGh4P/jVe/4I4SF6Ql + PtofU0jNq5vzapt/y+m008eXqPQFmoUOvu+JavoRVcRx2LIP5AgBA1mF56CSREsX + TkuJAA9IUQ8EjnmAoAeKINuPaKxGDuU8BGCMqr/qd564MKNf9XYL+Fb2rlkA0O2d + 2No34DQLgqSmST/LAvPM7Cbp6knYgnKmGr1nETCXasg1cueHLnWWTvps2HiPp2D/ + +Fq0uqcZLu4Mdo0CPs4e5sHRyldEnRSKh0DVLprq9zr/GMipmPLJUsT5Jed3sj0w + M7Y3vwxshpo= + -----END CERTIFICATE----- + privatekey: | + -----BEGIN PRIVATE KEY----- + MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC7+1xOHRQyOnQT + HFcrdasXZl0gzutVlA890a1wiQpdD5dOtCLo7+eqVYjqVKo9W8RUIArXWmBu/Abk + H7oVFWC1P973W1+ArF5sA70f7BZgqRKJTIisuIFIlRETgfnP2pfQmHRZtGaIJRZI + 4vQCdYgW2g0KOvvNcZJCVq1OrhKiNiY1bWCp66DGg0ic6OEkZFHTm745zUNQaf2d + NgsxKU0HPGjVLJI//yrRFAOSBUqgD4c50krnMF7fU/Fqh+UyOu8t6Y/HsySh3urB + +Zie331tAzV6QV39KKxRflNx/yuWrtIEslGTm+xHKoCYJEk/nZ3mX8Y5hG6wWAb7 + A/FuDVg3AgMBAAECggEAapt30rj9DitGTtxAt13pJMEhyYxvvD3WkvmJwguF/Bbu + eW0Ba1c668fMeRCA54FWi1sMqusPS4HUqqUvk+tmyAOsAF4qgD/A4MMSC7uJSVI5 + N/JWhJWyhCY94/FPakiO1nbPbVw41bcqtzU2qvparpME2CtxSCbDiqm7aaag3Kqe + EF0fGSUdZ+TYl9JM05+eIyiX+UY19Fg0OjTHMn8nGpxcNTfDBdQ68TKvdo/dtIKL + PLKzJUNNdM8odC4CvQtfGMqaslwZwXkiOl5VJcW21ncj/Y0ngEMKeD/i65ZoqGdR + 0FKCQYEAGtM2FvJcZQ92Wsw7yj2bK2MSegVUyLK32QKBgQDe8syVCepPzRsfjfxA + 6TZlWcGuTZLhwIx97Ktw3VcQ1f4rLoEYlv0xC2VWBORpzIsJo4I/OLmgp8a+Ga8z + FkVRnq90dV3t4NP9uJlHgcODHnOardC2UUka4olBSCG6zmK4Jxi34lOxhGRkshOo + L4IBeOIB5g+ZrEEXkzfYJHESRQKBgQDX2YhFhGIrT8BAnC5BbXbhm8h6Bhjz8DYL + d+qhVJjef7L/aJxViU0hX9Ba2O8CLK3FZeREFE3hJPiJ4TZSlN4evxs5p+bbNDcA + 0mhRI/o3X4ac6IxdRebyYnCOB/Cu94/MzppcZcotlCekKNike7eorCcX4Qavm7Pu + MUuQ+ifmSwKBgEnchoqZzlbBzMqXb4rRuIO7SL9GU/MWp3TQg7vQmJerTZlgvsQ2 + wYsOC3SECmhCq4117iCj2luvOdihCboTFsQDnn0mpQe6BIF6Ns3J38wAuqv0CcFd + DKsrge1uyD3rQilgSoAhKzkUc24o0PpXQurZ8YZPgbuXpbj5vPaOnCdBAoGACYc7 + wb3XS4wos3FxhUfcwJbM4b4VKeeHqzfu7pI6cU/3ydiHVitKcVe2bdw3qMPqI9Wc + nvi6e17Tbdq4OCsEJx1OiVwFD9YdO3cOTc6lw/3+hjypvZBRYo+/4jUthbu96E+S + dtOzehGZMmDvN0uSzupSi3ZOgkAAUFpyuIKickMCgYAId0PCRjonO2thn/R0rZ7P + //L852uyzYhXKw5/fjFGhQ6LbaLgIRFaCZ0L2809u0HFnNvJjHv4AKP6j+vFQYYY + qQ+66XnfsA9G/bu4MDS9AX83iahD9IdLXQAy8I19prAbpVumKegPbMnNYNB/TYEc + 3G15AKCXo7jjOUtHY01DCQ== + -----END PRIVATE KEY----- diff --git a/test/minio/1.1.0/ci/snmd-logsearch-values.yaml b/test/minio/1.1.0/ci/snmd-logsearch-values.yaml new file mode 100644 index 0000000000..ba5442026b --- /dev/null +++ b/test/minio/1.1.0/ci/snmd-logsearch-values.yaml @@ -0,0 +1,34 @@ +# When inside the versioned minio folder, run: +# helm dependency update +# helm template -f ix_values.yaml -f ci/logsearch-values.yaml . + +# Always use a unique hostPath for each test + +minioCreds: + rootUser: minio_test + rootPass: minio_test + +minioMultiMode: + - /data{1...4} + +minioStorage: + - type: pvc + mountPath: /data1 + - type: pvc + mountPath: /data2 + - type: pvc + mountPath: /data3 + - type: pvc + mountPath: /data4 + +minioLogging: + logsearch: + enabled: true + diskCapacityGB: 5 + pgData: + type: pvc + pgBackup: + type: emptyDir + emptyDirConfig: + size: "" + medium: "" diff --git a/test/minio/1.1.0/ci/snmd-values.yaml b/test/minio/1.1.0/ci/snmd-values.yaml new file mode 100644 index 0000000000..c6558d8d8b --- /dev/null +++ b/test/minio/1.1.0/ci/snmd-values.yaml @@ -0,0 +1,22 @@ +# When inside the versioned minio folder, run: +# helm dependency update +# helm template -f ix_values.yaml -f ci/basic-values.yaml . + +# Always use a unique hostPath for each test + +minioCreds: + rootUser: minio_test + rootPass: minio_test + +minioMultiMode: + - /data{1...4} + +minioStorage: + - type: pvc + mountPath: /data1 + - type: pvc + mountPath: /data2 + - type: pvc + mountPath: /data3 + - type: pvc + mountPath: /data4 diff --git a/test/minio/1.1.0/ci/snsd-https-values.yaml b/test/minio/1.1.0/ci/snsd-https-values.yaml new file mode 100644 index 0000000000..8723232467 --- /dev/null +++ b/test/minio/1.1.0/ci/snsd-https-values.yaml @@ -0,0 +1,104 @@ +# When inside the versioned minio folder, run: +# helm dependency update +# helm template -f ix_values.yaml -f ci/basic-https-values.yaml . + +# Always use a unique hostPath for each test + + +minioCreds: + rootUser: minio_test + rootPass: minio_test + +minioNetwork: + certificateID: 1 + +minioStorage: + - type: pvc + mountPath: /data1 + +ixCertificates: + "1": + certificate: | + -----BEGIN CERTIFICATE----- + MIIEdjCCA16gAwIBAgIDYFMYMA0GCSqGSIb3DQEBCwUAMGwxDDAKBgNVBAMMA2Fz + ZDELMAkGA1UEBhMCVVMxDTALBgNVBAgMBGFzZGYxCzAJBgNVBAcMAmFmMQ0wCwYD + VQQKDARhc2RmMQwwCgYDVQQLDANhc2QxFjAUBgkqhkiG9w0BCQEWB2FAYS5jb20w + HhcNMjEwODMwMjMyMzU0WhcNMjMxMjAzMjMyMzU0WjBuMQswCQYDVQQDDAJhZDEL + MAkGA1UEBhMCVVMxDTALBgNVBAgMBGFzZGYxDTALBgNVBAcMBGFzZGYxDTALBgNV + BAoMBGFkc2YxDTALBgNVBAsMBGFzZGYxFjAUBgkqhkiG9w0BCQEWB2FAYS5jb20w + ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC7+1xOHRQyOnQTHFcrdasX + Zl0gzutVlA890a1wiQpdD5dOtCLo7+eqVYjqVKo9W8RUIArXWmBu/AbkH7oVFWC1 + P973W1+ArF5sA70f7BZgqRKJTIisuIFIlRETgfnP2pfQmHRZtGaIJRZI4vQCdYgW + 2g0KOvvNcZJCVq1OrhKiNiY1bWCp66DGg0ic6OEkZFHTm745zUNQaf2dNgsxKU0H + PGjVLJI//yrRFAOSBUqgD4c50krnMF7fU/Fqh+UyOu8t6Y/HsySh3urB+Zie331t + AzV6QV39KKxRflNx/yuWrtIEslGTm+xHKoCYJEk/nZ3mX8Y5hG6wWAb7A/FuDVg3 + AgMBAAGjggEdMIIBGTAnBgNVHREEIDAehwTAqAADhwTAqAAFhwTAqAC2hwTAqACB + hwTAqACSMB0GA1UdDgQWBBQ4G2ff4tgZl4vmo4xCfqmJhdqShzAMBgNVHRMBAf8E + AjAAMIGYBgNVHSMEgZAwgY2AFLlYf9L99nxJDcpCM/LT3V5hQ/a3oXCkbjBsMQww + CgYDVQQDDANhc2QxCzAJBgNVBAYTAlVTMQ0wCwYDVQQIDARhc2RmMQswCQYDVQQH + DAJhZjENMAsGA1UECgwEYXNkZjEMMAoGA1UECwwDYXNkMRYwFAYJKoZIhvcNAQkB + FgdhQGEuY29tggNgUxcwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwEwDgYDVR0PAQH/ + BAQDAgWgMA0GCSqGSIb3DQEBCwUAA4IBAQA6FpOInEHB5iVk3FP67GybJ29vHZTD + KQHbQgmg8s4L7qIsA1HQ+DMCbdylpA11x+t/eL/n48BvGw2FNXpN6uykhLHJjbKR + h8yITa2KeD3LjLYhScwIigXmTVYSP3km6s8jRL6UKT9zttnIHyXVpBDya6Q4WTMx + fmfC6O7t1PjQ5ZyVtzizIUP8ah9n4TKdXU4A3QIM6WsJXpHb+vqp1WDWJ7mKFtgj + x5TKv3wcPnktx0zMPfLb5BTSE9rc9djcBG0eIAsPT4FgiatCUChe7VhuMnqskxEz + MymJLoq8+mzucRwFkOkR2EIt1x+Irl2mJVMeBow63rVZfUQBD8h++LqB + -----END CERTIFICATE----- + + -----BEGIN CERTIFICATE----- + MIIEhDCCA2ygAwIBAgIDYFMXMA0GCSqGSIb3DQEBCwUAMGwxDDAKBgNVBAMMA2Fz + ZDELMAkGA1UEBhMCVVMxDTALBgNVBAgMBGFzZGYxCzAJBgNVBAcMAmFmMQ0wCwYD + VQQKDARhc2RmMQwwCgYDVQQLDANhc2QxFjAUBgkqhkiG9w0BCQEWB2FAYS5jb20w + HhcNMjEwODMwMjMyMDQ1WhcNMzEwODI4MjMyMDQ1WjBsMQwwCgYDVQQDDANhc2Qx + CzAJBgNVBAYTAlVTMQ0wCwYDVQQIDARhc2RmMQswCQYDVQQHDAJhZjENMAsGA1UE + CgwEYXNkZjEMMAoGA1UECwwDYXNkMRYwFAYJKoZIhvcNAQkBFgdhQGEuY29tMIIB + IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAq//c0hEEr83CS1pMgsHX50jt + 2MqIbcf63UUNJTiYpUUvUQSFJFc7m/dr+RTZvu97eDCnD5K2qkHHvTPaPZwY+Djf + iy7N641Sz6u/y3Yo3xxs1Aermsfedh48vusJpjbkT2XS44VjbkrpKcWDNVpp3Evd + M7oJotXeUsZ+imiyVCfr4YhoY5gbGh/r+KN9Wf9YKoUyfLLZGwdZkhtX2zIbidsL + Thqi9YTaUHttGinjiBBum234u/CfvKXsfG3yP2gvBGnlvZnM9ktv+lVffYNqlf7H + VmB1bKKk84HtzuW5X76SGAgOG8eHX4x5ZLI1WQUuoQOVRl1I0UCjBtbz8XhwvQID + AQABo4IBLTCCASkwLQYDVR0RBCYwJIcEwKgABYcEwKgAA4cEwKgAkocEwKgAtYcE + wKgAgYcEwKgAtjAdBgNVHQ4EFgQUuVh/0v32fEkNykIz8tPdXmFD9rcwDwYDVR0T + AQH/BAUwAwEB/zCBmAYDVR0jBIGQMIGNgBS5WH/S/fZ8SQ3KQjPy091eYUP2t6Fw + pG4wbDEMMAoGA1UEAwwDYXNkMQswCQYDVQQGEwJVUzENMAsGA1UECAwEYXNkZjEL + MAkGA1UEBwwCYWYxDTALBgNVBAoMBGFzZGYxDDAKBgNVBAsMA2FzZDEWMBQGCSqG + SIb3DQEJARYHYUBhLmNvbYIDYFMXMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEF + BQcDAjAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBAKEocOmVuWlr + zegtKYMe8NhHIkFY9oVn5ym6RHNOJpPH4QF8XYC3Z5+iC5yGh4P/jVe/4I4SF6Ql + PtofU0jNq5vzapt/y+m008eXqPQFmoUOvu+JavoRVcRx2LIP5AgBA1mF56CSREsX + TkuJAA9IUQ8EjnmAoAeKINuPaKxGDuU8BGCMqr/qd564MKNf9XYL+Fb2rlkA0O2d + 2No34DQLgqSmST/LAvPM7Cbp6knYgnKmGr1nETCXasg1cueHLnWWTvps2HiPp2D/ + +Fq0uqcZLu4Mdo0CPs4e5sHRyldEnRSKh0DVLprq9zr/GMipmPLJUsT5Jed3sj0w + M7Y3vwxshpo= + -----END CERTIFICATE----- + privatekey: | + -----BEGIN PRIVATE KEY----- + MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC7+1xOHRQyOnQT + HFcrdasXZl0gzutVlA890a1wiQpdD5dOtCLo7+eqVYjqVKo9W8RUIArXWmBu/Abk + H7oVFWC1P973W1+ArF5sA70f7BZgqRKJTIisuIFIlRETgfnP2pfQmHRZtGaIJRZI + 4vQCdYgW2g0KOvvNcZJCVq1OrhKiNiY1bWCp66DGg0ic6OEkZFHTm745zUNQaf2d + NgsxKU0HPGjVLJI//yrRFAOSBUqgD4c50krnMF7fU/Fqh+UyOu8t6Y/HsySh3urB + +Zie331tAzV6QV39KKxRflNx/yuWrtIEslGTm+xHKoCYJEk/nZ3mX8Y5hG6wWAb7 + A/FuDVg3AgMBAAECggEAapt30rj9DitGTtxAt13pJMEhyYxvvD3WkvmJwguF/Bbu + eW0Ba1c668fMeRCA54FWi1sMqusPS4HUqqUvk+tmyAOsAF4qgD/A4MMSC7uJSVI5 + N/JWhJWyhCY94/FPakiO1nbPbVw41bcqtzU2qvparpME2CtxSCbDiqm7aaag3Kqe + EF0fGSUdZ+TYl9JM05+eIyiX+UY19Fg0OjTHMn8nGpxcNTfDBdQ68TKvdo/dtIKL + PLKzJUNNdM8odC4CvQtfGMqaslwZwXkiOl5VJcW21ncj/Y0ngEMKeD/i65ZoqGdR + 0FKCQYEAGtM2FvJcZQ92Wsw7yj2bK2MSegVUyLK32QKBgQDe8syVCepPzRsfjfxA + 6TZlWcGuTZLhwIx97Ktw3VcQ1f4rLoEYlv0xC2VWBORpzIsJo4I/OLmgp8a+Ga8z + FkVRnq90dV3t4NP9uJlHgcODHnOardC2UUka4olBSCG6zmK4Jxi34lOxhGRkshOo + L4IBeOIB5g+ZrEEXkzfYJHESRQKBgQDX2YhFhGIrT8BAnC5BbXbhm8h6Bhjz8DYL + d+qhVJjef7L/aJxViU0hX9Ba2O8CLK3FZeREFE3hJPiJ4TZSlN4evxs5p+bbNDcA + 0mhRI/o3X4ac6IxdRebyYnCOB/Cu94/MzppcZcotlCekKNike7eorCcX4Qavm7Pu + MUuQ+ifmSwKBgEnchoqZzlbBzMqXb4rRuIO7SL9GU/MWp3TQg7vQmJerTZlgvsQ2 + wYsOC3SECmhCq4117iCj2luvOdihCboTFsQDnn0mpQe6BIF6Ns3J38wAuqv0CcFd + DKsrge1uyD3rQilgSoAhKzkUc24o0PpXQurZ8YZPgbuXpbj5vPaOnCdBAoGACYc7 + wb3XS4wos3FxhUfcwJbM4b4VKeeHqzfu7pI6cU/3ydiHVitKcVe2bdw3qMPqI9Wc + nvi6e17Tbdq4OCsEJx1OiVwFD9YdO3cOTc6lw/3+hjypvZBRYo+/4jUthbu96E+S + dtOzehGZMmDvN0uSzupSi3ZOgkAAUFpyuIKickMCgYAId0PCRjonO2thn/R0rZ7P + //L852uyzYhXKw5/fjFGhQ6LbaLgIRFaCZ0L2809u0HFnNvJjHv4AKP6j+vFQYYY + qQ+66XnfsA9G/bu4MDS9AX83iahD9IdLXQAy8I19prAbpVumKegPbMnNYNB/TYEc + 3G15AKCXo7jjOUtHY01DCQ== + -----END PRIVATE KEY----- diff --git a/test/minio/1.1.0/ci/snsd-logsearch-https-values.yaml b/test/minio/1.1.0/ci/snsd-logsearch-https-values.yaml new file mode 100644 index 0000000000..33d2e2f591 --- /dev/null +++ b/test/minio/1.1.0/ci/snsd-logsearch-https-values.yaml @@ -0,0 +1,115 @@ +# When inside the versioned minio folder, run: +# helm dependency update +# helm template -f ix_values.yaml -f ci/logsearch-https-values.yaml . + +# Always use a unique hostPath for each test + +minioCreds: + rootUser: minio_test + rootPass: minio_test + +minioNetwork: + certificateID: 1 + +minioStorage: + - type: pvc + mountPath: /data1 + +minioLogging: + logsearch: + enabled: true + diskCapacityGB: 5 + pgData: + type: pvc + pgBackup: + type: emptyDir + emptyDirConfig: + size: "" + medium: "" + +ixCertificates: + "1": + certificate: | + -----BEGIN CERTIFICATE----- + MIIEdjCCA16gAwIBAgIDYFMYMA0GCSqGSIb3DQEBCwUAMGwxDDAKBgNVBAMMA2Fz + ZDELMAkGA1UEBhMCVVMxDTALBgNVBAgMBGFzZGYxCzAJBgNVBAcMAmFmMQ0wCwYD + VQQKDARhc2RmMQwwCgYDVQQLDANhc2QxFjAUBgkqhkiG9w0BCQEWB2FAYS5jb20w + HhcNMjEwODMwMjMyMzU0WhcNMjMxMjAzMjMyMzU0WjBuMQswCQYDVQQDDAJhZDEL + MAkGA1UEBhMCVVMxDTALBgNVBAgMBGFzZGYxDTALBgNVBAcMBGFzZGYxDTALBgNV + BAoMBGFkc2YxDTALBgNVBAsMBGFzZGYxFjAUBgkqhkiG9w0BCQEWB2FAYS5jb20w + ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC7+1xOHRQyOnQTHFcrdasX + Zl0gzutVlA890a1wiQpdD5dOtCLo7+eqVYjqVKo9W8RUIArXWmBu/AbkH7oVFWC1 + P973W1+ArF5sA70f7BZgqRKJTIisuIFIlRETgfnP2pfQmHRZtGaIJRZI4vQCdYgW + 2g0KOvvNcZJCVq1OrhKiNiY1bWCp66DGg0ic6OEkZFHTm745zUNQaf2dNgsxKU0H + PGjVLJI//yrRFAOSBUqgD4c50krnMF7fU/Fqh+UyOu8t6Y/HsySh3urB+Zie331t + AzV6QV39KKxRflNx/yuWrtIEslGTm+xHKoCYJEk/nZ3mX8Y5hG6wWAb7A/FuDVg3 + AgMBAAGjggEdMIIBGTAnBgNVHREEIDAehwTAqAADhwTAqAAFhwTAqAC2hwTAqACB + hwTAqACSMB0GA1UdDgQWBBQ4G2ff4tgZl4vmo4xCfqmJhdqShzAMBgNVHRMBAf8E + AjAAMIGYBgNVHSMEgZAwgY2AFLlYf9L99nxJDcpCM/LT3V5hQ/a3oXCkbjBsMQww + CgYDVQQDDANhc2QxCzAJBgNVBAYTAlVTMQ0wCwYDVQQIDARhc2RmMQswCQYDVQQH + DAJhZjENMAsGA1UECgwEYXNkZjEMMAoGA1UECwwDYXNkMRYwFAYJKoZIhvcNAQkB + FgdhQGEuY29tggNgUxcwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwEwDgYDVR0PAQH/ + BAQDAgWgMA0GCSqGSIb3DQEBCwUAA4IBAQA6FpOInEHB5iVk3FP67GybJ29vHZTD + KQHbQgmg8s4L7qIsA1HQ+DMCbdylpA11x+t/eL/n48BvGw2FNXpN6uykhLHJjbKR + h8yITa2KeD3LjLYhScwIigXmTVYSP3km6s8jRL6UKT9zttnIHyXVpBDya6Q4WTMx + fmfC6O7t1PjQ5ZyVtzizIUP8ah9n4TKdXU4A3QIM6WsJXpHb+vqp1WDWJ7mKFtgj + x5TKv3wcPnktx0zMPfLb5BTSE9rc9djcBG0eIAsPT4FgiatCUChe7VhuMnqskxEz + MymJLoq8+mzucRwFkOkR2EIt1x+Irl2mJVMeBow63rVZfUQBD8h++LqB + -----END CERTIFICATE----- + + -----BEGIN CERTIFICATE----- + MIIEhDCCA2ygAwIBAgIDYFMXMA0GCSqGSIb3DQEBCwUAMGwxDDAKBgNVBAMMA2Fz + ZDELMAkGA1UEBhMCVVMxDTALBgNVBAgMBGFzZGYxCzAJBgNVBAcMAmFmMQ0wCwYD + VQQKDARhc2RmMQwwCgYDVQQLDANhc2QxFjAUBgkqhkiG9w0BCQEWB2FAYS5jb20w + HhcNMjEwODMwMjMyMDQ1WhcNMzEwODI4MjMyMDQ1WjBsMQwwCgYDVQQDDANhc2Qx + CzAJBgNVBAYTAlVTMQ0wCwYDVQQIDARhc2RmMQswCQYDVQQHDAJhZjENMAsGA1UE + CgwEYXNkZjEMMAoGA1UECwwDYXNkMRYwFAYJKoZIhvcNAQkBFgdhQGEuY29tMIIB + IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAq//c0hEEr83CS1pMgsHX50jt + 2MqIbcf63UUNJTiYpUUvUQSFJFc7m/dr+RTZvu97eDCnD5K2qkHHvTPaPZwY+Djf + iy7N641Sz6u/y3Yo3xxs1Aermsfedh48vusJpjbkT2XS44VjbkrpKcWDNVpp3Evd + M7oJotXeUsZ+imiyVCfr4YhoY5gbGh/r+KN9Wf9YKoUyfLLZGwdZkhtX2zIbidsL + Thqi9YTaUHttGinjiBBum234u/CfvKXsfG3yP2gvBGnlvZnM9ktv+lVffYNqlf7H + VmB1bKKk84HtzuW5X76SGAgOG8eHX4x5ZLI1WQUuoQOVRl1I0UCjBtbz8XhwvQID + AQABo4IBLTCCASkwLQYDVR0RBCYwJIcEwKgABYcEwKgAA4cEwKgAkocEwKgAtYcE + wKgAgYcEwKgAtjAdBgNVHQ4EFgQUuVh/0v32fEkNykIz8tPdXmFD9rcwDwYDVR0T + AQH/BAUwAwEB/zCBmAYDVR0jBIGQMIGNgBS5WH/S/fZ8SQ3KQjPy091eYUP2t6Fw + pG4wbDEMMAoGA1UEAwwDYXNkMQswCQYDVQQGEwJVUzENMAsGA1UECAwEYXNkZjEL + MAkGA1UEBwwCYWYxDTALBgNVBAoMBGFzZGYxDDAKBgNVBAsMA2FzZDEWMBQGCSqG + SIb3DQEJARYHYUBhLmNvbYIDYFMXMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEF + BQcDAjAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBAKEocOmVuWlr + zegtKYMe8NhHIkFY9oVn5ym6RHNOJpPH4QF8XYC3Z5+iC5yGh4P/jVe/4I4SF6Ql + PtofU0jNq5vzapt/y+m008eXqPQFmoUOvu+JavoRVcRx2LIP5AgBA1mF56CSREsX + TkuJAA9IUQ8EjnmAoAeKINuPaKxGDuU8BGCMqr/qd564MKNf9XYL+Fb2rlkA0O2d + 2No34DQLgqSmST/LAvPM7Cbp6knYgnKmGr1nETCXasg1cueHLnWWTvps2HiPp2D/ + +Fq0uqcZLu4Mdo0CPs4e5sHRyldEnRSKh0DVLprq9zr/GMipmPLJUsT5Jed3sj0w + M7Y3vwxshpo= + -----END CERTIFICATE----- + privatekey: | + -----BEGIN PRIVATE KEY----- + MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC7+1xOHRQyOnQT + HFcrdasXZl0gzutVlA890a1wiQpdD5dOtCLo7+eqVYjqVKo9W8RUIArXWmBu/Abk + H7oVFWC1P973W1+ArF5sA70f7BZgqRKJTIisuIFIlRETgfnP2pfQmHRZtGaIJRZI + 4vQCdYgW2g0KOvvNcZJCVq1OrhKiNiY1bWCp66DGg0ic6OEkZFHTm745zUNQaf2d + NgsxKU0HPGjVLJI//yrRFAOSBUqgD4c50krnMF7fU/Fqh+UyOu8t6Y/HsySh3urB + +Zie331tAzV6QV39KKxRflNx/yuWrtIEslGTm+xHKoCYJEk/nZ3mX8Y5hG6wWAb7 + A/FuDVg3AgMBAAECggEAapt30rj9DitGTtxAt13pJMEhyYxvvD3WkvmJwguF/Bbu + eW0Ba1c668fMeRCA54FWi1sMqusPS4HUqqUvk+tmyAOsAF4qgD/A4MMSC7uJSVI5 + N/JWhJWyhCY94/FPakiO1nbPbVw41bcqtzU2qvparpME2CtxSCbDiqm7aaag3Kqe + EF0fGSUdZ+TYl9JM05+eIyiX+UY19Fg0OjTHMn8nGpxcNTfDBdQ68TKvdo/dtIKL + PLKzJUNNdM8odC4CvQtfGMqaslwZwXkiOl5VJcW21ncj/Y0ngEMKeD/i65ZoqGdR + 0FKCQYEAGtM2FvJcZQ92Wsw7yj2bK2MSegVUyLK32QKBgQDe8syVCepPzRsfjfxA + 6TZlWcGuTZLhwIx97Ktw3VcQ1f4rLoEYlv0xC2VWBORpzIsJo4I/OLmgp8a+Ga8z + FkVRnq90dV3t4NP9uJlHgcODHnOardC2UUka4olBSCG6zmK4Jxi34lOxhGRkshOo + L4IBeOIB5g+ZrEEXkzfYJHESRQKBgQDX2YhFhGIrT8BAnC5BbXbhm8h6Bhjz8DYL + d+qhVJjef7L/aJxViU0hX9Ba2O8CLK3FZeREFE3hJPiJ4TZSlN4evxs5p+bbNDcA + 0mhRI/o3X4ac6IxdRebyYnCOB/Cu94/MzppcZcotlCekKNike7eorCcX4Qavm7Pu + MUuQ+ifmSwKBgEnchoqZzlbBzMqXb4rRuIO7SL9GU/MWp3TQg7vQmJerTZlgvsQ2 + wYsOC3SECmhCq4117iCj2luvOdihCboTFsQDnn0mpQe6BIF6Ns3J38wAuqv0CcFd + DKsrge1uyD3rQilgSoAhKzkUc24o0PpXQurZ8YZPgbuXpbj5vPaOnCdBAoGACYc7 + wb3XS4wos3FxhUfcwJbM4b4VKeeHqzfu7pI6cU/3ydiHVitKcVe2bdw3qMPqI9Wc + nvi6e17Tbdq4OCsEJx1OiVwFD9YdO3cOTc6lw/3+hjypvZBRYo+/4jUthbu96E+S + dtOzehGZMmDvN0uSzupSi3ZOgkAAUFpyuIKickMCgYAId0PCRjonO2thn/R0rZ7P + //L852uyzYhXKw5/fjFGhQ6LbaLgIRFaCZ0L2809u0HFnNvJjHv4AKP6j+vFQYYY + qQ+66XnfsA9G/bu4MDS9AX83iahD9IdLXQAy8I19prAbpVumKegPbMnNYNB/TYEc + 3G15AKCXo7jjOUtHY01DCQ== + -----END PRIVATE KEY----- diff --git a/test/minio/1.1.0/ci/snsd-logsearch-values.yaml b/test/minio/1.1.0/ci/snsd-logsearch-values.yaml new file mode 100644 index 0000000000..1f3878ee5e --- /dev/null +++ b/test/minio/1.1.0/ci/snsd-logsearch-values.yaml @@ -0,0 +1,25 @@ +# When inside the versioned minio folder, run: +# helm dependency update +# helm template -f ix_values.yaml -f ci/logsearch-values.yaml . + +# Always use a unique hostPath for each test + +minioCreds: + rootUser: minio_test + rootPass: minio_test + +minioStorage: + - type: pvc + mountPath: /data1 + +minioLogging: + logsearch: + enabled: true + diskCapacityGB: 5 + pgData: + type: pvc + pgBackup: + type: emptyDir + emptyDirConfig: + size: "" + medium: "" diff --git a/test/minio/1.1.0/ci/snsd-values.yaml b/test/minio/1.1.0/ci/snsd-values.yaml new file mode 100644 index 0000000000..8b52123616 --- /dev/null +++ b/test/minio/1.1.0/ci/snsd-values.yaml @@ -0,0 +1,17 @@ +# When inside the versioned minio folder, run: +# helm dependency update +# helm template -f ix_values.yaml -f ci/basic-values.yaml . + +# Always use a unique hostPath for each test + +minioCreds: + rootUser: minio_test + rootPass: minio_test + +minioRunAs: + user: 1000 + group: 1000 + +minioStorage: + - type: pvc + mountPath: /data1 diff --git a/test/minio/1.1.0/ix_values.yaml b/test/minio/1.1.0/ix_values.yaml new file mode 100644 index 0000000000..de931fa715 --- /dev/null +++ b/test/minio/1.1.0/ix_values.yaml @@ -0,0 +1,50 @@ +image: + repository: minio/minio + tag: RELEASE.2023-12-07T04-16-00Z + pullPolicy: IfNotPresent + +logsearchImage: + repository: minio/operator + tag: v4.5.8 + pullPolicy: IfNotPresent + +resources: + limits: + cpu: 4000m + memory: 8Gi + +minioCreds: + rootUser: '' + rootPass: '' + +minioRunAs: + user: 568 + group: 568 + +minioNetwork: + apiPort: 30000 + webPort: 30001 + certificateID: null + hostNetwork: true + serverUrl: '' + consoleUrl: '' + +minioMultiMode: [] + +minioStorage: [] + +minioLogging: + anonymous: false + quiet: false + + logsearch: + enabled: false + diskCapacityGB: 5 + pgData: + type: ixVolume + ixVolumeConfig: + datasetName: postgres-data + pgBackup: + type: ixVolume + ixVolumeConfig: + datasetName: postgres-backup diff --git a/test/minio/1.1.0/metadata.yaml b/test/minio/1.1.0/metadata.yaml new file mode 100644 index 0000000000..8f8e56d261 --- /dev/null +++ b/test/minio/1.1.0/metadata.yaml @@ -0,0 +1,18 @@ +runAsContext: + - userName: minio + groupName: minio + gid: 568 + uid: 568 + description: Minio can run as any non-root user. + - userName: logsearch + groupName: logsearch + gid: 568 + uid: 568 + description: Minio's logsearch can run as any non-root user. + - userName: postgres + groupName: postgres + gid: 999 + uid: 999 + description: Postgres runs as a non-root user. +capabilities: [] +hostMounts: [] diff --git a/test/minio/1.1.0/migrations/migrate b/test/minio/1.1.0/migrations/migrate new file mode 100755 index 0000000000..c25c5e64a0 --- /dev/null +++ b/test/minio/1.1.0/migrations/migrate @@ -0,0 +1,63 @@ +#!/usr/bin/python3 +import json +import os +import sys + + +def storage_migrate(storage): + delete_keys = [] + if storage['type'] == 'hostPath': + # Check if the key exists, if not we have already migrated + if not storage.get('hostPath'): + return storage + + storage['hostPathConfig'] = {'hostPath': storage['hostPath']} + delete_keys.append('hostPath') + + elif storage['type'] == 'ixVolume': + # Check if the key exists, if not we have already migrated + if not storage.get('datasetName'): + return storage + + storage['ixVolumeConfig'] = {'datasetName': storage['datasetName']} + delete_keys.append('datasetName') + + # Clean up for some older versions. + if storage.get('hostPath'): + delete_keys.append('hostPath') + + for key in delete_keys: + storage.pop(key, None) + + return storage + + +def migrate(values): + storageKey = 'minioLogging' + storageSubKey = 'logsearch' + storages = ['pgData', 'pgBackup'] + + for storage in storages: + check_val = values.get(storageKey, {}).get(storageSubKey, {}).get(storage, {}) + if not isinstance(check_val, dict) or not check_val: + raise Exception(f'Storage section {storage} is malformed') + + values[storageKey][storageSubKey][storage] = storage_migrate(check_val) + + dataStorageItems = values.get('minioStorage', {}) + for idx, storage in enumerate(dataStorageItems): + if not isinstance(storage, dict) or not storage: + raise Exception(f'Item {idx} in minioStorage is malformed') + + dataStorageItems[idx] = storage_migrate(storage) + + return values + + +if __name__ == '__main__': + if len(sys.argv) != 2: + exit(1) + + if os.path.exists(sys.argv[1]): + with open(sys.argv[1], 'r') as f: + print(json.dumps(migrate(json.loads(f.read())))) diff --git a/test/minio/1.1.0/questions.yaml b/test/minio/1.1.0/questions.yaml new file mode 100644 index 0000000000..c88460f7b6 --- /dev/null +++ b/test/minio/1.1.0/questions.yaml @@ -0,0 +1,512 @@ +groups: + - name: MinIO Credentials + description: Configure Credentials for MinIO + - name: User and Group Configuration + description: Configure User and Group for MinIO + - name: Network Configuration + description: Configure Network for MinIO + - name: Storage Configuration + description: Configure Storage for MinIO + - name: MultiMode Configuration + description: Configure MultiMode for MinIO + - name: MinIO Logging + description: Configure Logging for MinIO + - name: Resources Configuration + description: Configure Resources for MinIO + +portals: + web_portal: + protocols: + - "$kubernetes-resource_configmap_portal_protocol" + host: + - "$kubernetes-resource_configmap_portal_host" + ports: + - "$kubernetes-resource_configmap_portal_port" + path: "$kubernetes-resource_configmap_portal_path" + +questions: + - variable: minioCreds + label: "" + group: MinIO Credentials + schema: + type: dict + attrs: + - variable: rootUser + label: Root User + description: The access key for the root user. + schema: + type: string + min_length: 5 + required: true + - variable: rootPass + label: Root Password + description: The secret key for the root user. + schema: + type: string + required: true + min_length: 8 + private: true + + - variable: minioRunAs + label: "" + group: User and Group Configuration + schema: + type: dict + attrs: + - variable: user + label: User ID + description: | + The user id that MinIO will run as.
+ Can't be changed after initial install. + schema: + type: int + min: 568 + default: 568 + immutable: true + required: true + - variable: group + label: Group ID + description: | + The group id that MinIO will run as.
+ Can't be changed after initial install. + schema: + type: int + min: 568 + default: 568 + immutable: true + required: true + + - variable: minioNetwork + label: "" + group: Network Configuration + schema: + type: dict + attrs: + - variable: apiPort + label: API Port + description: The port for the MinIO API. + schema: + type: int + default: 30000 + min: 9000 + max: 65535 + required: true + - variable: webPort + label: Web Port + description: The port for the MinIO Web UI. + schema: + type: int + default: 30001 + min: 9000 + max: 65535 + required: true + - variable: hostNetwork + label: Host Network + description: | + Bind to the host network. It's recommended to keep this disabled.
+ schema: + type: boolean + default: true + - variable: certificateID + label: Certificate + description: The certificate to use for MinIO + schema: + type: int + "null": true + $ref: + - "definitions/certificate" + - variable: serverUrl + label: MinIO Server URL (API) + description: | + The URL that console will use to reach API
+ For example https://minio1.example.com.

+ schema: + type: string + required: true + - variable: consoleUrl + label: MinIO Browser Redirect URL + description: | + The URL that console will provide as a redirect URL
+ For example https://console.example.com.

+ schema: + type: string + required: true + + - variable: enableMultiMode + label: Enable Multi Mode (SNMD or MNMD) + group: MultiMode Configuration + description: | + For Single Node Multi Drive (SNMD), the entry will look like this:
+ Example Entry - /data{1...4}

+ For Multi Node Multi Drive (MNMD), the entry will look like this:
+ Example Entry - https://minio{1...3}.example.com:30000/data{1...4}

+ Note that each host must use the same port number and the same number of storage items.
+ In both cases /data{1...4} is the directories to be used for MinIO. + You have to add additional storage for each data entry. + schema: + type: boolean + default: false + show_subquestions_if: true + subquestions: + - variable: minioMultiMode + label: Multi Mode (SNMD or MNMD) + group: MultiMode Configuration + schema: + type: list + default: [] + items: + - variable: item + label: "" + schema: + type: string + required: true + + - variable: minioStorage + label: "" + group: Storage Configuration + schema: + type: list + default: [{"type": "ixVolume", "mountPath": "/data1", "datasetName": "data1"}] + empty: false + required: true + items: + - variable: item + label: Storage Item + schema: + type: dict + attrs: + - variable: type + label: Type + description: | + ixVolume: Is dataset created automatically by the system.
+ Host Path: Is a path that already exists on the system. + schema: + type: string + immutable: true + required: true + default: ixVolume + enum: + - value: hostPath + description: Host Path (Path that already exists on the system) + - value: ixVolume + description: ixVolume (Dataset created automatically by the system) + - variable: mountPath + label: Mount Path + description: The path inside the container to mount the storage. + schema: + type: path + required: true + immutable: true + default: /data1 + - variable: ixVolumeConfig + label: ixVolume Configuration + description: The configuration for the ixVolume dataset. + schema: + type: dict + show_if: [["type", "=", "ixVolume"]] + $ref: + - "normalize/ixVolume" + attrs: + - variable: aclEnable + label: Enable ACL + description: Enable ACL for the dataset. + schema: + type: boolean + # Hide ACL for now + hidden: true + default: false + - variable: datasetName + label: Dataset Name + description: The name of the dataset to use for storage. + schema: + type: string + required: true + immutable: true + default: "data1" + - variable: aclEntries + label: ACL Configuration + schema: + type: dict + show_if: [["aclEnable", "=", true]] + attrs: [] + - variable: hostPathConfig + label: Host Path Configuration + schema: + type: dict + show_if: [["type", "=", "hostPath"]] + attrs: + - variable: aclEnable + label: Enable ACL + description: Enable ACL for the dataset. + schema: + type: boolean + # Hide ACL for now + hidden: true + default: false + - variable: acl + label: ACL Configuration + schema: + type: dict + show_if: [["aclEnable", "=", true]] + attrs: [] + $ref: + - "normalize/acl" + - variable: hostPath + label: Host Path + description: The host path to use for storage. + schema: + type: hostpath + show_if: [["aclEnable", "=", false]] + required: true + + - variable: minioLogging + label: "" + group: MinIO Logging + schema: + type: dict + attrs: + - variable: anonymous + label: Anonymous + description: Hides sensitive information from logging. + schema: + type: boolean + default: false + - variable: quiet + label: Quiet + description: Disables startup information. + schema: + type: boolean + default: false + + - variable: logsearch + label: LogSearch Configuration + schema: + type: dict + attrs: + - variable: enabled + label: Enable LogSearch + schema: + type: boolean + default: false + show_subquestions_if: true + subquestions: + - variable: diskCapacityGB + label: Disk Capacity (GB) + description: The disk capacity for LogSearch. + schema: + type: int + default: 5 + required: true + - variable: pgData + label: Postgres Data Storage + description: The path to store Postgres data. + schema: + type: dict + attrs: + - variable: type + label: Type + description: | + ixVolume: Is dataset created automatically by the system.
+ Host Path: Is a path that already exists on the system. + schema: + type: string + required: true + immutable: true + default: ixVolume + enum: + - value: hostPath + description: Host Path (Path that already exists on the system) + - value: ixVolume + description: ixVolume (Dataset created automatically by the system) + - variable: ixVolumeConfig + label: ixVolume Configuration + description: The configuration for the ixVolume dataset. + schema: + type: dict + # Nothing to show for the user + hidden: true + show_if: [["type", "=", "ixVolume"]] + $ref: + - "normalize/ixVolume" + attrs: + - variable: aclEnable + label: Enable ACL + description: Enable ACL for the dataset. + schema: + type: boolean + # Postgres does a CHMOD at startup + # Which fails with ACL + hidden: true + default: false + - variable: datasetName + label: Dataset Name + description: The name of the dataset to use for storage. + schema: + type: string + required: true + immutable: true + hidden: true + default: postgres-data + - variable: aclEntries + label: ACL Configuration + schema: + type: dict + show_if: [["aclEnable", "=", true]] + attrs: [] + - variable: hostPathConfig + label: Host Path Configuration + schema: + type: dict + show_if: [["type", "=", "hostPath"]] + attrs: + - variable: aclEnable + label: Enable ACL + description: Enable ACL for the dataset. + schema: + type: boolean + # Postgres does a CHMOD at startup + # Which fails with ACL + hidden: true + default: false + - variable: acl + label: ACL Configuration + schema: + type: dict + show_if: [["aclEnable", "=", true]] + attrs: [] + $ref: + - "normalize/acl" + - variable: hostPath + label: Host Path + description: The host path to use for storage. + schema: + type: hostpath + show_if: [["aclEnable", "=", false]] + required: true + - variable: pgBackup + label: Postgres Backup Storage + description: The path to store Postgres backups. + schema: + type: dict + attrs: + - variable: type + label: Type + description: | + ixVolume: Is dataset created automatically by the system.
+ Host Path: Is a path that already exists on the system. + schema: + type: string + required: true + immutable: true + default: ixVolume + enum: + - value: hostPath + description: Host Path (Path that already exists on the system) + - value: ixVolume + description: ixVolume (Dataset created automatically by the system) + - variable: ixVolumeConfig + label: ixVolume Configuration + description: The configuration for the ixVolume dataset. + schema: + type: dict + # Nothing to show for the user + hidden: true + show_if: [["type", "=", "ixVolume"]] + $ref: + - "normalize/ixVolume" + attrs: + - variable: aclEnable + label: Enable ACL + description: Enable ACL for the dataset. + schema: + type: boolean + # Postgres does a CHMOD at startup + # Which fails with ACL + hidden: true + default: false + - variable: datasetName + label: Dataset Name + description: The name of the dataset to use for storage. + schema: + type: string + required: true + immutable: true + hidden: true + default: "postgres-backup" + - variable: aclEntries + label: ACL Configuration + schema: + type: dict + show_if: [["aclEnable", "=", true]] + attrs: [] + - variable: hostPathConfig + label: Host Path Configuration + schema: + type: dict + show_if: [["type", "=", "hostPath"]] + attrs: + - variable: aclEnable + label: Enable ACL + description: Enable ACL for the dataset. + schema: + type: boolean + # Postgres does a CHMOD at startup + # Which fails with ACL + hidden: true + default: false + - variable: acl + label: ACL Configuration + schema: + type: dict + show_if: [["aclEnable", "=", true]] + attrs: [] + $ref: + - "normalize/acl" + - variable: hostPath + label: Host Path + description: The host path to use for storage. + schema: + type: hostpath + show_if: [["aclEnable", "=", false]] + required: true + + - variable: resources + label: "" + group: Resources Configuration + schema: + type: dict + attrs: + - variable: limits + label: Limits + schema: + type: dict + attrs: + - variable: cpu + label: CPU + description: CPU limit for MinIO. + schema: + type: string + max_length: 6 + valid_chars: '^(0\.[1-9]|[1-9][0-9]*)(\.[0-9]|m?)$' + valid_chars_error: | + Valid CPU limit formats are
+ - Plain Integer - eg. 1
+ - Float - eg. 0.5
+ - Milicpu - eg. 500m + default: "4000m" + required: true + - variable: memory + label: Memory + description: Memory limit for MinIO. + schema: + type: string + max_length: 12 + valid_chars: '^[1-9][0-9]*([EPTGMK]i?|e[0-9]+)?$' + valid_chars_error: | + Valid Memory limit formats are
+ - Suffixed with E/P/T/G/M/K - eg. 1G
+ - Suffixed with Ei/Pi/Ti/Gi/Mi/Ki - eg. 1Gi
+ - Plain Integer in bytes - eg. 1024
+ - Exponent - eg. 134e6 + default: "8Gi" + required: true diff --git a/test/minio/1.1.0/templates/NOTES.txt b/test/minio/1.1.0/templates/NOTES.txt new file mode 100644 index 0000000000..ba4e01146c --- /dev/null +++ b/test/minio/1.1.0/templates/NOTES.txt @@ -0,0 +1 @@ +{{ include "ix.v1.common.lib.chart.notes" $ }} diff --git a/test/minio/1.1.0/templates/_configuration.tpl b/test/minio/1.1.0/templates/_configuration.tpl new file mode 100644 index 0000000000..c3584dd385 --- /dev/null +++ b/test/minio/1.1.0/templates/_configuration.tpl @@ -0,0 +1,61 @@ +{{- define "minio.configuration" -}} + + {{/* Validation */}} + {{ include "minio.validation" $ }} + + {{ $config := fromJson (include "minio.prepare.config" $) }} + +{{/* Secrets */}} +secret: + minio-creds: + enabled: true + data: + MINIO_ROOT_USER: {{ .Values.minioCreds.rootUser }} + MINIO_ROOT_PASSWORD: {{ .Values.minioCreds.rootPass }} + MINIO_VOLUMES: {{ $config.volumes }} + {{ with .Values.minioNetwork.serverUrl }} + MINIO_SERVER_URL: {{ . | quote }} + {{ end }} + {{ with .Values.minioNetwork.consoleUrl }} + MINIO_BROWSER_REDIRECT_URL: {{ . | quote }} + {{ end }} + {{ if .Values.minioLogging.logsearch.enabled }} + MINIO_AUDIT_WEBHOOK_ENABLE_ix_logsearch: "on" + MINIO_AUDIT_WEBHOOK_ENDPOINT_ix_logsearch: {{ $config.webhookURL }} + MINIO_LOG_QUERY_AUTH_TOKEN: {{ $config.queryToken }} + MINIO_LOG_QUERY_URL: {{ $config.logQueryURL }} + {{ end }} + + # Always create the logsearch and postgres secret, even if logsearch is disabled. + # Because autogenerated passwords are stored in the secret, and disabling logsearch after + # the secret is created will cause the passwords to be lost (if the secret is conditionally rendered). + logsearch-creds: + enabled: true + data: + LOGSEARCH_PG_CONN_STR: {{ $config.postgresURL }} + LOGSEARCH_AUDIT_AUTH_TOKEN: {{ $config.auditToken }} + MINIO_LOG_QUERY_AUTH_TOKEN: {{ $config.queryToken }} + {{ if .Values.minioLogging.logsearch.enabled }} + LOGSEARCH_DISK_CAPACITY_GB: {{ $config.diskCapacity | quote }} + {{ end }} + + postgres-creds: + enabled: true + data: + POSTGRES_PASSWORD: {{ $config.dbPass }} + POSTGRES_USER: {{ $config.dbUser }} + POSTGRES_DB: {{ $config.dbName }} + POSTGRES_HOST: {{ $config.dbHost }} + POSTGRES_URL: {{ $config.postgresURL }} + +{{/* MinIO Certificate */}} +{{ if .Values.minioNetwork.certificateID }} +scaleCertificate: + minio-cert: + enabled: true + labels: {} + annotations: {} + id: {{ .Values.minioNetwork.certificateID }} +{{ end }} + +{{- end -}} diff --git a/test/minio/1.1.0/templates/_helpers.tpl b/test/minio/1.1.0/templates/_helpers.tpl new file mode 100644 index 0000000000..baf8f29064 --- /dev/null +++ b/test/minio/1.1.0/templates/_helpers.tpl @@ -0,0 +1,115 @@ +{{/* Scheme */}} +{{- define "minio.scheme" -}} + {{- $scheme := "http" -}} + {{- if .Values.minioNetwork.certificateID -}} + {{- $scheme = "https" -}} + {{- end -}} + + {{- $scheme -}} +{{- end -}} + +{{- define "minio.hostnetwork" -}} + {{- $hostNet := .Values.minioNetwork.hostNetwork -}} + + {{- range $entry := .Values.minioMultiMode -}} + {{/* + Only if multi mode has urls set hostnetwork, + Multi Mode can be used for single node, multi disk setup + */}} + {{- if contains "://" $entry -}} + {{- $hostNet = true -}} + {{- end -}} + + {{- end -}} + {{- $hostNet -}} +{{- end -}} + +{{/* Validation */}} +{{- define "minio.validation" -}} + {{- if not .Values.minioCreds.rootUser -}} + {{- fail "Expected non-empty " -}} + {{- end -}} + + {{- if not .Values.minioCreds.rootPass -}} + {{- fail "Expected non-empty " -}} + {{- end -}} + + {{- if not .Values.minioStorage -}} + {{- fail "Expected at least 1 storage item added" -}} + {{- end -}} + + {{- if and (ne (len .Values.minioStorage) 1) (not .Values.minioMultiMode) -}} + {{- fail "Expected Multi Mode to be enabled, when more than 1 storage mountPaths added" -}} + {{- end -}} + + {{- $notAllowedKeys := (list "server") -}} {{/* Extend if needed */}} + {{- range $item := .Values.minioMultiMode -}} + {{- if (mustHas $item $notAllowedKeys) -}} + {{- fail (printf "Key [%v] is not allowed as a Multi Mode argument" $item) -}} + {{- end -}} + + {{- if hasPrefix "/" $item -}} + {{- if or (contains "{" $item) (contains "}" $item) -}} + {{- if not (contains "..." $item) -}} + {{- fail "Expected Multi Mode Item to have 3 dots when its a path with expansion eg [/some_path{1...4}]" -}} + {{- end -}} + {{- end -}} + {{- end -}} + {{- end -}} + + {{- $mountPaths := list -}} + {{- range $item := .Values.minioStorage -}} + {{- $mountPaths = mustAppend $mountPaths $item.mountPath -}} + {{- end -}} + + {{- if not (deepEqual ($mountPaths) (uniq $mountPaths)) -}} + {{- fail (printf "Expected mountPaths to be unique, but got [%v]" (join ", " $mountPaths)) -}} + {{- end -}} +{{- end -}} + +{{/* Config preparation */}} +{{- define "minio.prepare.config" -}} + {{/* Prepare logsearch related config, shared across different configmaps */}} + {{- $config := dict -}} + + {{- $fullname := (include "ix.v1.common.lib.chart.names.fullname" $) -}} + + {{- if .Values.minioLogging.logsearch.enabled -}} + {{- $_ := set $config "diskCapacity" (required "Expected non-empty " .Values.minioLogging.logsearch.diskCapacityGB) -}} + {{- end -}} + + {{- $_ := set $config "dbUser" "logsearch" -}} + {{- $_ := set $config "dbName" "logsearch" -}} + + {{- $_ := set $config "dbPass" (randAlphaNum 32) -}} + {{- with (lookup "v1" "Secret" .Release.Namespace (printf "%s-postgres-creds" $fullname)) -}} + {{- $_ := set $config "dbPass" ((index .data "POSTGRES_PASSWORD") | b64dec) -}} + {{- end -}} + + {{- $_ := set $config "auditToken" (randAlphaNum 32) -}} + {{- with (lookup "v1" "Secret" .Release.Namespace (printf "%s-logsearch-creds" $fullname)) -}} + {{- $_ := set $config "auditToken" ((index .data "LOGSEARCH_AUDIT_AUTH_TOKEN") | b64dec) -}} + {{- end -}} + + {{- $_ := set $config "queryToken" (randAlphaNum 32) -}} + {{- with (lookup "v1" "Secret" .Release.Namespace (printf "%s-logsearch-creds" $fullname)) -}} + {{- $_ := set $config "queryToken" ((index .data "MINIO_LOG_QUERY_AUTH_TOKEN") | b64dec) -}} + {{- end -}} + + {{- $_ := set $config "dbHost" (printf "%s-postgres" $fullname ) -}} + {{- $_ := set $config "logQueryURL" (printf "http://%s-logsearch:8080" $fullname) -}} + {{- $_ := set $config "webhookURL" (printf "%s/api/ingest?token=%v" $config.logQueryURL $config.auditToken) -}} + {{- $_ := set $config "postgresURL" (printf "postgres://%s:%s@%s:5432/%s?sslmode=disable" $config.dbUser $config.dbPass $config.dbHost $config.dbName) -}} + + {{/* When no multi mode, use the first storage entry */}} + {{- $_ := set $config "volumes" (.Values.minioStorage | first).mountPath -}} + {{- if .Values.minioMultiMode -}} + {{- $_ := set $config "volumes" (join " " .Values.minioMultiMode) -}} + {{- end -}} + + {{- if not $config.volumes -}} + {{- fail "ERROR: Volumes can't be empty" -}} + {{- end -}} + + {{- $config | toJson -}} +{{- end -}} diff --git a/test/minio/1.1.0/templates/_logsearch.tpl b/test/minio/1.1.0/templates/_logsearch.tpl new file mode 100644 index 0000000000..f7c3ada148 --- /dev/null +++ b/test/minio/1.1.0/templates/_logsearch.tpl @@ -0,0 +1,51 @@ +{{- define "logsearch.workload" -}} +workload: + logsearch: + enabled: true + type: Deployment + podSpec: + containers: + logsearch: + enabled: true + primary: true + imageSelector: logsearchImage + securityContext: + runAsUser: {{ .Values.minioRunAs.user }} + runAsGroup: {{ .Values.minioRunAs.group }} + envFrom: + - secretRef: + name: logsearch-creds + command: /logsearchapi + probes: + liveness: + enabled: true + type: http + port: 8080 + path: /status + readiness: + enabled: true + type: http + port: 8080 + path: /status + startup: + enabled: true + type: http + port: 8080 + path: /status + initContainers: + {{- include "ix.v1.common.app.postgresWait" (dict "name" "postgres-wait" + "secretName" "postgres-creds") | nindent 8 }} + +{{/* Service */}} +service: + logsearch: + enabled: true + type: ClusterIP + targetSelector: logsearch + ports: + logsearch: + enabled: true + primary: true + port: 8080 + targetSelector: logsearch +{{- end -}} diff --git a/test/minio/1.1.0/templates/_minio.tpl b/test/minio/1.1.0/templates/_minio.tpl new file mode 100644 index 0000000000..e9e5b3903c --- /dev/null +++ b/test/minio/1.1.0/templates/_minio.tpl @@ -0,0 +1,145 @@ +{{- define "minio.workload" -}} +workload: + minio: + enabled: true + primary: true + type: Deployment + podSpec: + hostNetwork: {{ include "minio.hostnetwork" $ }} + containers: + minio: + enabled: true + primary: true + imageSelector: image + securityContext: + runAsUser: {{ .Values.minioRunAs.user }} + runAsGroup: {{ .Values.minioRunAs.group }} + envFrom: + - secretRef: + name: minio-creds + args: + - server + - "--address" + - {{ printf ":%v" .Values.minioNetwork.apiPort | quote }} + - "--console-address" + - {{ printf ":%v" .Values.minioNetwork.webPort | quote }} + {{- if .Values.minioNetwork.certificateID }} + - "--certs-dir" + - "/.minio/certs" + {{- end -}} + {{- if .Values.minioLogging.anonymous }} + - "--anonymous" + {{- end -}} + {{- if .Values.minioLogging.quiet }} + - "--quiet" + {{- end }} + probes: + liveness: + enabled: true + type: {{ include "minio.scheme" $ }} + port: "{{ .Values.minioNetwork.apiPort }}" + path: /minio/health/live + readiness: + enabled: true + type: {{ include "minio.scheme" $ }} + port: "{{ .Values.minioNetwork.apiPort }}" + path: /minio/health/live + startup: + enabled: true + type: {{ include "minio.scheme" $ }} + port: "{{ .Values.minioNetwork.apiPort }}" + path: /minio/health/live + initContainers: + {{- include "ix.v1.common.app.permissions" (dict "containerName" "01-permissions" + "UID" .Values.minioRunAs.user + "GID" .Values.minioRunAs.group + "type" "install") | nindent 8 -}} + {{- if .Values.minioLogging.logsearch.enabled }} + logsearch-wait: + enabled: true + type: init + imageSelector: bashImage + resources: + limits: + cpu: 500m + memory: 256Mi + envFrom: + - secretRef: + name: minio-creds + command: bash + args: + - -c + - | + echo "Pinging Logsearch API for readiness..." + until wget --spider --quiet --timeout=3 --tries=1 ${MINIO_LOG_QUERY_URL}/status; do + echo "Waiting for Logsearch API (${MINIO_LOG_QUERY_URL}/status) to be ready..." + sleep 2 + done + echo "Logsearch API is ready" + {{- end }} + +{{/* Service */}} +service: + minio: + enabled: true + primary: true + type: NodePort + targetSelector: minio + ports: + api: + enabled: true + primary: true + port: {{ .Values.minioNetwork.apiPort }} + nodePort: {{ .Values.minioNetwork.apiPort }} + targetSelector: minio + webui: + enabled: true + port: {{ .Values.minioNetwork.webPort }} + nodePort: {{ .Values.minioNetwork.webPort }} + targetSelector: minio + +{{/* Persistence */}} +persistence: + {{- range $idx, $storage := .Values.minioStorage }} + {{ printf "data%v" (int $idx) }}: + enabled: true + {{- include "minio.storage.ci.migration" (dict "storage" $storage) }} + {{- include "ix.v1.common.app.storageOptions" (dict "storage" $storage) | nindent 4 }} + targetSelector: + minio: + minio: + mountPath: {{ $storage.mountPath }} + {{- if and (eq $storage.type "ixVolume") (not ($storage.ixVolumeConfig | default dict).aclEnable) }} + 01-permissions: + mountPath: /mnt/directories{{ $storage.mountPath }} + {{- end }} + {{- end }} + # Minio writes temporary files to this directory. Adding this as an emptyDir, + # So we don't have to set readOnlyRootFilesystem to false + tempdir: + enabled: true + type: emptyDir + targetSelector: + minio: + minio: + mountPath: /.minio + {{- if .Values.minioNetwork.certificateID }} + cert: + enabled: true + type: secret + objectName: minio-cert + defaultMode: "0600" + items: + - key: tls.key + path: private.key + - key: tls.crt + path: public.crt + - key: tls.crt + path: CAs/public.crt + targetSelector: + minio: + minio: + mountPath: /.minio/certs + readOnly: true + {{- end -}} +{{- end -}} diff --git a/test/minio/1.1.0/templates/_portal.tpl b/test/minio/1.1.0/templates/_portal.tpl new file mode 100644 index 0000000000..25d25a25ed --- /dev/null +++ b/test/minio/1.1.0/templates/_portal.tpl @@ -0,0 +1,20 @@ +{{- define "minio.portal" -}} +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: portal +data: + {{- $url := urlParse .Values.minioNetwork.consoleUrl -}} + {{- $protocol := $url.scheme -}} + {{- $host := $url.hostname -}} + {{- $port := $url.host | replace $host "" | replace ":" "" -}} + {{/* If user used SCALE certificate, then force https */}} + {{- if eq "https" (include "minio.scheme" $) -}} + {{- $protocol = "https" -}} + {{- end }} + path: "/" + port: {{ $port | default .Values.minioNetwork.webPort | quote }} + protocol: {{ $protocol | default "http" }} + host: {{ $host | default "$node_ip" }} +{{- end -}} diff --git a/test/minio/1.1.0/templates/_postgres.tpl b/test/minio/1.1.0/templates/_postgres.tpl new file mode 100644 index 0000000000..3dbde1286d --- /dev/null +++ b/test/minio/1.1.0/templates/_postgres.tpl @@ -0,0 +1,20 @@ +{{- define "postgres.workload" -}} +workload: +{{- include "ix.v1.common.app.postgres" (dict "secretName" "postgres-creds" + "resources" .Values.resources + "ixChartContext" .Values.ixChartContext) | nindent 2 }} + +{{/* Service */}} +service: + {{- include "ix.v1.common.app.postgresService" $ | nindent 2 }} + +{{- include "minio.storage.ci.migration" (dict "storage" .Values.minioLogging.logsearch.pgData) }} +{{- include "minio.storage.ci.migration" (dict "storage" .Values.minioLogging.logsearch.pgBackup) }} + +{{/* Persistence */}} +persistence: + {{- include "ix.v1.common.app.postgresPersistence" + (dict "pgData" .Values.minioLogging.logsearch.pgData + "pgBackup" .Values.minioLogging.logsearch.pgBackup + ) | nindent 2 }} +{{- end -}} diff --git a/test/minio/1.1.0/templates/common.yaml b/test/minio/1.1.0/templates/common.yaml new file mode 100644 index 0000000000..ec440ea1c9 --- /dev/null +++ b/test/minio/1.1.0/templates/common.yaml @@ -0,0 +1,25 @@ +{{- include "ix.v1.common.loader.init" . -}} + +{{/* TODO: Remove on the next version bump, eg 1.1.0+ */}} +{{- define "minio.storage.ci.migration" -}} + {{- $storage := .storage -}} + + {{- if $storage.hostPath -}} + {{- $_ := set $storage "hostPathConfig" dict -}} + {{- $_ := set $storage.hostPathConfig "hostPath" $storage.hostPath -}} + {{- end -}} +{{- end -}} + +{{/* Merge the templates with Values */}} +{{- $_ := mustMergeOverwrite .Values (include "minio.configuration" $ | fromYaml) -}} + +{{- $_ := mustMergeOverwrite .Values (include "minio.workload" $ | fromYaml) -}} +{{- if .Values.minioLogging.logsearch.enabled -}} + {{- $_ := mustMergeOverwrite .Values (include "logsearch.workload" $ | fromYaml) -}} + {{- $_ := mustMergeOverwrite .Values (include "postgres.workload" $ | fromYaml) -}} +{{- end -}} + +{{/* Create the configmap for portal manually*/}} +{{- include "minio.portal" $ -}} + +{{- include "ix.v1.common.loader.apply" . -}} diff --git a/test/minio/1.1.0/to_keep_versions.md b/test/minio/1.1.0/to_keep_versions.md new file mode 100644 index 0000000000..6d11261176 --- /dev/null +++ b/test/minio/1.1.0/to_keep_versions.md @@ -0,0 +1,3 @@ +# 1.0.24 + +This version is kept in order to be able to test the storage section migration diff --git a/test/minio/1.1.0/upgrade_strategy_disable b/test/minio/1.1.0/upgrade_strategy_disable new file mode 100755 index 0000000000..0209796a7c --- /dev/null +++ b/test/minio/1.1.0/upgrade_strategy_disable @@ -0,0 +1,62 @@ +#!/usr/bin/python3 +import json +import re +import sys + +from catalog_update.upgrade_strategy import semantic_versioning +from catalog_update.upgrade_strategy import datetime_versioning + + +ENUMS = { + 'image': { + 'RE_STABLE_VERSION': re.compile(r'RELEASE.\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2}}Z'), + 'STRIP_TEXT': 'RELEASE.', + 'function': datetime_versioning, + 'function_arg': '%Y-%m-%dT%H-%M-%SZ' + }, + 'logsearchImage': { + 'RE_STABLE_VERSION': re.compile(r'v\d+\.\d+\.\d+'), + 'STRIP_TEXT': 'v', + 'function': semantic_versioning + }, +} + + +def newer_mapping(image_tags): + + output = { + "tags": {}, + "app_version": "" + } + + for key in image_tags.keys(): + STRIP_TEXT = ENUMS[key].get('STRIP_TEXT', None) if key in ENUMS else None + RE_STABLE_VERSION = ENUMS[key].get('RE_STABLE_VERSION', None) if key in ENUMS else None + VERSION_FUNCTION = ENUMS[key].get('function', None) if key in ENUMS else None + + if (STRIP_TEXT is None) or (RE_STABLE_VERSION is None) or (VERSION_FUNCTION is None): + continue + + tags = {t.strip(STRIP_TEXT): t for t in image_tags[key] if RE_STABLE_VERSION.fullmatch(t)} + if ENUMS[key].get('function_arg', None): + version = VERSION_FUNCTION(list(tags), ENUMS[key].get('function_arg')) + else: + version = VERSION_FUNCTION(list(tags)) + if not version: + continue + + if key == 'image': + output['app_version'] = version + + output['tags'][key] = tags[version] + + return output + + +if __name__ == '__main__': + try: + versions_json = json.loads(sys.stdin.read()) + except ValueError: + raise ValueError('Invalid json specified') + + print(json.dumps(newer_mapping(versions_json)))