From a24b5957049d00af2c5b37f253c099c8fd5f0e11 Mon Sep 17 00:00:00 2001 From: Aidan Hilt Date: Wed, 9 Oct 2024 17:30:03 -0400 Subject: [PATCH 01/11] First commit of netpolicies, now that it's working locally, let's break it in unfunded --- .pre-commit-config.yaml | 42 +- .secrets.baseline | 954 ++++++++++-------- helm/ambassador/Chart.yaml | 2 +- helm/ambassador/README.md | 4 +- helm/arborist/Chart.yaml | 2 +- helm/arborist/README.md | 6 +- helm/arborist/templates/netpolicy.yaml | 1 + helm/arborist/values.yaml | 9 +- helm/argo-wrapper/Chart.yaml | 2 +- helm/argo-wrapper/README.md | 7 +- helm/argo-wrapper/templates/netpolicy.yaml | 5 + helm/argo-wrapper/values.yaml | 47 +- helm/audit/Chart.yaml | 2 +- helm/audit/README.md | 9 +- helm/audit/templates/netpolicy.yaml | 9 + helm/audit/values.yaml | 49 +- helm/aws-es-proxy/Chart.yaml | 2 +- helm/aws-es-proxy/README.md | 7 +- helm/aws-es-proxy/templates/netpolicy.yaml | 5 + helm/aws-es-proxy/values.yaml | 22 +- helm/common/Chart.yaml | 2 +- helm/common/README.md | 6 +- .../common/templates/_netpolicy_templates.tpl | 66 ++ helm/common/values.yaml | 4 +- helm/dicom-server/Chart.yaml | 2 +- helm/dicom-server/README.md | 4 +- helm/dicom-server/templates/netpolicy.yaml | 1 + helm/dicom-viewer/Chart.yaml | 2 +- helm/dicom-viewer/README.md | 4 +- helm/etl/Chart.yaml | 2 +- helm/etl/README.md | 4 +- helm/fence/Chart.yaml | 2 +- helm/fence/README.md | 6 +- helm/fence/templates/netpolicy.yaml | 1 + helm/fence/values.yaml | 365 ++++--- helm/frontend-framework/Chart.yaml | 2 +- helm/frontend-framework/README.md | 8 +- helm/frontend-framework/values.yaml | 37 +- helm/gen3/Chart.yaml | 222 ++-- helm/gen3/README.md | 9 +- helm/gen3/values.yaml | 63 +- helm/guppy/Chart.yaml | 2 +- helm/guppy/README.md | 6 +- helm/guppy/values.yaml | 42 +- helm/hatchery/Chart.yaml | 2 +- helm/hatchery/README.md | 7 +- helm/hatchery/values.yaml | 78 +- helm/indexd/Chart.yaml | 2 +- helm/indexd/README.md | 9 +- helm/indexd/templates/netpolicy.yaml | 9 + helm/indexd/values.yaml | 56 +- helm/manifestservice/Chart.yaml | 2 +- helm/manifestservice/README.md | 4 +- helm/metadata/Chart.yaml | 2 +- helm/metadata/README.md | 6 +- helm/metadata/templates/netpolicy.yaml | 1 + helm/metadata/values.yaml | 33 +- helm/neuvector/Chart.yaml | 2 +- helm/neuvector/README.md | 4 +- helm/peregrine/Chart.yaml | 2 +- helm/peregrine/README.md | 9 +- helm/peregrine/templates/netpolicy.yaml | 9 + helm/peregrine/values.yaml | 31 +- helm/pidgin/Chart.yaml | 2 +- helm/pidgin/README.md | 6 +- helm/pidgin/values.yaml | 32 +- helm/portal/Chart.yaml | 2 +- helm/portal/README.md | 6 +- helm/portal/values.yaml | 47 +- helm/requestor/Chart.yaml | 2 +- helm/requestor/README.md | 6 +- helm/requestor/templates/netpolicy.yaml | 1 + helm/requestor/values.yaml | 32 +- helm/revproxy/Chart.yaml | 2 +- helm/revproxy/README.md | 9 +- helm/revproxy/templates/netpolicy.yaml | 59 ++ helm/revproxy/values.yaml | 25 +- helm/sheepdog/Chart.yaml | 2 +- helm/sheepdog/README.md | 6 +- helm/sheepdog/templates/netpolicy.yaml | 1 + helm/sheepdog/values.yaml | 34 +- helm/sower/Chart.yaml | 2 +- helm/sower/README.md | 9 +- helm/sower/templates/netpolicy.yaml | 20 + helm/sower/values.yaml | 238 ++--- helm/ssjdispatcher/Chart.yaml | 2 +- helm/ssjdispatcher/README.md | 6 +- helm/ssjdispatcher/templates/netpolicy.yaml | 14 + helm/ssjdispatcher/values.yaml | 35 +- helm/wts/Chart.yaml | 2 +- helm/wts/README.md | 6 +- helm/wts/values.yaml | 10 +- wip/gen3-network-policies/.helmignore | 23 + wip/gen3-network-policies/Chart.yaml | 9 + .../templates/_helpers.tpl | 62 ++ .../templates/allow_nothing_netpolicy.yaml | 11 + .../templates/allowdns_netpolicy.yaml | 19 + .../templates/argo_workflows_netpolicy.yaml | 35 + .../templates/argocd_netpolicy.yaml | 34 + .../templates/auth_netpolicy.yaml | 27 + .../dev_elasticsearch_netpolicy.yaml | 29 + .../templates/dev_kube_api_netpolicy.yaml | 18 + .../templates/dev_postgres_netpolicy.yaml | 29 + .../templates/external_egress_netpolicy.yaml | 22 + .../templates/gen3job_netpolicy.yaml | 26 + .../templates/jh_netpolicy.yaml | 42 + .../templates/linklocal_netpolicy.yaml | 14 + .../public_service_egress_netpolicy.yaml | 19 + .../templates/s3_netpolicy.yaml | 12 + wip/gen3-network-policies/values.yaml | 29 + 110 files changed, 2165 insertions(+), 1229 deletions(-) create mode 100644 helm/arborist/templates/netpolicy.yaml create mode 100644 helm/argo-wrapper/templates/netpolicy.yaml create mode 100644 helm/audit/templates/netpolicy.yaml create mode 100644 helm/aws-es-proxy/templates/netpolicy.yaml create mode 100644 helm/common/templates/_netpolicy_templates.tpl create mode 100644 helm/dicom-server/templates/netpolicy.yaml create mode 100644 helm/fence/templates/netpolicy.yaml create mode 100644 helm/indexd/templates/netpolicy.yaml create mode 100644 helm/metadata/templates/netpolicy.yaml create mode 100644 helm/peregrine/templates/netpolicy.yaml create mode 100644 helm/requestor/templates/netpolicy.yaml create mode 100644 helm/revproxy/templates/netpolicy.yaml create mode 100644 helm/sheepdog/templates/netpolicy.yaml create mode 100644 helm/sower/templates/netpolicy.yaml create mode 100644 helm/ssjdispatcher/templates/netpolicy.yaml create mode 100644 wip/gen3-network-policies/.helmignore create mode 100644 wip/gen3-network-policies/Chart.yaml create mode 100644 wip/gen3-network-policies/templates/_helpers.tpl create mode 100644 wip/gen3-network-policies/templates/allow_nothing_netpolicy.yaml create mode 100644 wip/gen3-network-policies/templates/allowdns_netpolicy.yaml create mode 100644 wip/gen3-network-policies/templates/argo_workflows_netpolicy.yaml create mode 100644 wip/gen3-network-policies/templates/argocd_netpolicy.yaml create mode 100644 wip/gen3-network-policies/templates/auth_netpolicy.yaml create mode 100644 wip/gen3-network-policies/templates/dev_elasticsearch_netpolicy.yaml create mode 100644 wip/gen3-network-policies/templates/dev_kube_api_netpolicy.yaml create mode 100644 wip/gen3-network-policies/templates/dev_postgres_netpolicy.yaml create mode 100644 wip/gen3-network-policies/templates/external_egress_netpolicy.yaml create mode 100644 wip/gen3-network-policies/templates/gen3job_netpolicy.yaml create mode 100644 wip/gen3-network-policies/templates/jh_netpolicy.yaml create mode 100644 wip/gen3-network-policies/templates/linklocal_netpolicy.yaml create mode 100644 wip/gen3-network-policies/templates/public_service_egress_netpolicy.yaml create mode 100644 wip/gen3-network-policies/templates/s3_netpolicy.yaml create mode 100644 wip/gen3-network-policies/values.yaml diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3e2d2565..a993cb61 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: git@github.com:Yelp/detect-secrets - rev: v0.13.1 + rev: v1.5.0 hooks: - id: detect-secrets args: ["--baseline", ".secrets.baseline"] @@ -9,28 +9,28 @@ repos: hooks: - id: no-commit-to-branch args: [--branch, develop, --branch, master, --pattern, release/.*] - + # - repo: https://github.com/gruntwork-io/pre-commit # rev: v0.1.17 # Get the latest from: https://github.com/gruntwork-io/pre-commit/releases # hooks: # - id: helmlint - - repo: local - hooks: - - id: helm-docs - args: ["-c", "helm"] - description: Uses 'helm-docs' to create documentation from the Helm chart's 'values.yaml' file, and inserts the result into a corresponding 'README.md' file. - entry: git-hook/helm-docs.sh - language: script - name: Helm Docs - require_serial: true - - - repo: local - hooks: - - id: helm-chart-bump - args: [] - description: Updates the .Chart.yaml with updates version if there are changes since master branch. This is to ensure we bump our charts for updates. - entry: git-hook/helm-bump.sh - language: script - name: Helm Docs - require_serial: true \ No newline at end of file + - repo: local + hooks: + - id: helm-docs + args: ["-c", "helm"] + description: Uses 'helm-docs' to create documentation from the Helm chart's 'values.yaml' file, and inserts the result into a corresponding 'README.md' file. + entry: git-hook/helm-docs.sh + language: script + name: Helm Docs + require_serial: true + + - repo: local + hooks: + - id: helm-chart-bump + args: [] + description: Updates the .Chart.yaml with updates version if there are changes since master branch. This is to ensure we bump our charts for updates. + entry: git-hook/helm-bump.sh + language: script + name: Helm Docs + require_serial: true diff --git a/.secrets.baseline b/.secrets.baseline index c0929635..28da4aa2 100644 --- a/.secrets.baseline +++ b/.secrets.baseline @@ -1,19 +1,18 @@ { - "exclude": { - "files": "^.secrets.baseline$", - "lines": null - }, - "generated_at": "2024-09-09T20:23:45Z", + "version": "1.5.0", "plugins_used": [ + { + "name": "ArtifactoryDetector" + }, { "name": "AWSKeyDetector" }, { - "name": "ArtifactoryDetector" + "name": "AzureStorageKeyDetector" }, { - "base64_limit": 4.5, - "name": "Base64HighEntropyString" + "name": "Base64HighEntropyString", + "limit": 4.5 }, { "name": "BasicAuthDetector" @@ -22,8 +21,17 @@ "name": "CloudantDetector" }, { - "hex_limit": 3, - "name": "HexHighEntropyString" + "name": "DiscordBotTokenDetector" + }, + { + "name": "GitHubTokenDetector" + }, + { + "name": "GitLabTokenDetector" + }, + { + "name": "HexHighEntropyString", + "limit": 3.0 }, { "name": "IbmCloudIamDetector" @@ -31,719 +39,799 @@ { "name": "IbmCosHmacDetector" }, + { + "name": "IPPublicDetector" + }, { "name": "JwtTokenDetector" }, { - "keyword_exclude": null, - "name": "KeywordDetector" + "name": "KeywordDetector", + "keyword_exclude": "" }, { "name": "MailchimpDetector" }, + { + "name": "NpmDetector" + }, + { + "name": "OpenAIDetector" + }, { "name": "PrivateKeyDetector" }, + { + "name": "PypiTokenDetector" + }, + { + "name": "SendGridDetector" + }, { "name": "SlackDetector" }, { "name": "SoftlayerDetector" }, + { + "name": "SquareOAuthDetector" + }, { "name": "StripeDetector" }, + { + "name": "TelegramBotTokenDetector" + }, { "name": "TwilioKeyDetector" } ], + "filters_used": [ + { + "path": "detect_secrets.filters.allowlist.is_line_allowlisted" + }, + { + "path": "detect_secrets.filters.common.is_ignored_due_to_verification_policies", + "min_level": 2 + }, + { + "path": "detect_secrets.filters.heuristic.is_indirect_reference" + }, + { + "path": "detect_secrets.filters.heuristic.is_likely_id_string" + }, + { + "path": "detect_secrets.filters.heuristic.is_lock_file" + }, + { + "path": "detect_secrets.filters.heuristic.is_not_alphanumeric_string" + }, + { + "path": "detect_secrets.filters.heuristic.is_potential_uuid" + }, + { + "path": "detect_secrets.filters.heuristic.is_prefixed_with_dollar_sign" + }, + { + "path": "detect_secrets.filters.heuristic.is_sequential_string" + }, + { + "path": "detect_secrets.filters.heuristic.is_swagger_file" + }, + { + "path": "detect_secrets.filters.heuristic.is_templated_secret" + } + ], "results": { "README.md": [ { + "type": "Secret Keyword", + "filename": "README.md", "hashed_secret": "64ab0c1d3edc1c8c166351207b840ac7b2a90523", - "is_secret": false, "is_verified": false, - "line_number": 59, - "type": "Secret Keyword" + "line_number": 59 } ], "docs/CONFIGURATION.md": [ { + "type": "Secret Keyword", + "filename": "docs/CONFIGURATION.md", "hashed_secret": "64ab0c1d3edc1c8c166351207b840ac7b2a90523", - "is_secret": true, - "is_verified": false, - "line_number": 135, - "type": "Secret Keyword" - }, - { - "hashed_secret": "9b5925ea817163740dfb287a9894e8ab3aba2c18", - "is_secret": true, "is_verified": false, - "line_number": 301, - "type": "Secret Keyword" + "line_number": 135 } ], - "docs/PREREQUISITES.md": [ + "examples/gke_dev_values.yaml": [ { - "hashed_secret": "ac0fedaac180de6bd70a97b711692a92dade479e", - "is_secret": false, + "type": "Secret Keyword", + "filename": "examples/gke_dev_values.yaml", + "hashed_secret": "75cb4c02576c9abae38fadc84bc832f2af203f3e", "is_verified": false, - "line_number": 92, - "type": "Secret Keyword" + "line_number": 13 + }, + { + "type": "Secret Keyword", + "filename": "examples/gke_dev_values.yaml", + "hashed_secret": "519a59c1d9d1e3f501f0c3696dddfd409c9fc7f6", + "is_verified": false, + "line_number": 54 } ], - "docs/databases.md": [ + "examples/gke_values.yaml": [ { - "hashed_secret": "de469a49b80aa4bb9aed52a9eda64dea425dff69", - "is_secret": true, + "type": "Secret Keyword", + "filename": "examples/gke_values.yaml", + "hashed_secret": "75cb4c02576c9abae38fadc84bc832f2af203f3e", "is_verified": false, - "line_number": 22, - "type": "Secret Keyword" + "line_number": 14 }, { - "hashed_secret": "ac0fedaac180de6bd70a97b711692a92dade479e", - "is_secret": false, + "type": "Secret Keyword", + "filename": "examples/gke_values.yaml", + "hashed_secret": "519a59c1d9d1e3f501f0c3696dddfd409c9fc7f6", "is_verified": false, - "line_number": 38, - "type": "Secret Keyword" + "line_number": 78 } ], - "docs/kubernetes-in-docker.md": [ + "helm/audit/templates/deployment.yaml": [ { - "hashed_secret": "5320294d100314ce19330d99abada8c26c4993a3", - "is_secret": false, + "type": "Secret Keyword", + "filename": "helm/audit/templates/deployment.yaml", + "hashed_secret": "42cde1c58c36d8bb5804a076e55ac6ec07ef99fc", "is_verified": false, - "line_number": 96, - "type": "Secret Keyword" + "line_number": 31 } ], - "examples/gke_dev_values.yaml": [ + "helm/audit/templates/external-secret.yaml": [ { - "hashed_secret": "75cb4c02576c9abae38fadc84bc832f2af203f3e", - "is_secret": false, + "type": "Secret Keyword", + "filename": "helm/audit/templates/external-secret.yaml", + "hashed_secret": "ec18a21018e2c2d9642b3777def1f591a7eb7031", "is_verified": false, - "line_number": 13, - "type": "Secret Keyword" + "line_number": 15 } ], - "examples/gke_values.yaml": [ + "helm/aws-es-proxy/templates/external-secrets.yaml": [ { - "hashed_secret": "75cb4c02576c9abae38fadc84bc832f2af203f3e", - "is_secret": true, + "type": "Secret Keyword", + "filename": "helm/aws-es-proxy/templates/external-secrets.yaml", + "hashed_secret": "d506bd5213c46bd49e16c634754ad70113408252", "is_verified": false, - "line_number": 14, - "type": "Secret Keyword" + "line_number": 15 } ], - "helm/arborist/README.md": [ + "helm/common/templates/_generate_test_data.tpl": [ { - "hashed_secret": "d84ce25b0f9bc2cc263006ae39453efb22cc2900", - "is_secret": false, + "type": "Secret Keyword", + "filename": "helm/common/templates/_generate_test_data.tpl", + "hashed_secret": "dbd5f43594a152b52261c8e21520a3989823fe55", "is_verified": false, - "line_number": 51, - "type": "Secret Keyword" + "line_number": 30 }, { - "hashed_secret": "f09dd6e359833a12f48c4c4255d6e87a6e55cfe9", - "is_secret": false, + "type": "Secret Keyword", + "filename": "helm/common/templates/_generate_test_data.tpl", + "hashed_secret": "694cfd0a009a42055e975de9111b2f3c6e8a3634", "is_verified": false, - "line_number": 70, - "type": "Secret Keyword" - } - ], - "helm/audit/README.md": [ - { - "hashed_secret": "a04a85e28ae4f699c0f8d014ad41160c9b9206f0", - "is_secret": false, - "is_verified": false, - "line_number": 36, - "type": "Secret Keyword" + "line_number": 33 }, { - "hashed_secret": "d84ce25b0f9bc2cc263006ae39453efb22cc2900", - "is_secret": false, + "type": "Secret Keyword", + "filename": "helm/common/templates/_generate_test_data.tpl", + "hashed_secret": "1c062eaac9e6fa0766377d3cfc3e4a88982fecdb", "is_verified": false, - "line_number": 61, - "type": "Secret Keyword" + "line_number": 39 }, { - "hashed_secret": "f09dd6e359833a12f48c4c4255d6e87a6e55cfe9", - "is_secret": false, - "is_verified": false, - "line_number": 82, - "type": "Secret Keyword" - } - ], - "helm/common/README.md": [ - { - "hashed_secret": "d84ce25b0f9bc2cc263006ae39453efb22cc2900", - "is_secret": false, + "type": "Secret Keyword", + "filename": "helm/common/templates/_generate_test_data.tpl", + "hashed_secret": "4b09a441cef18c75560f6c3caeafc96f2163c3fd", "is_verified": false, - "line_number": 25, - "type": "Secret Keyword" - } - ], - "helm/common/templates/_postgres_secrets.tpl": [ - { - "hashed_secret": "07b87392697bbdd9d97f6cd887f901820a0150df", - "is_secret": false, - "is_verified": false, - "line_number": 34, - "type": "Secret Keyword" + "line_number": 43 }, { - "hashed_secret": "e343239977fa87adac52528619fc6bf2e1a82ee7", - "is_secret": false, + "type": "Secret Keyword", + "filename": "helm/common/templates/_generate_test_data.tpl", + "hashed_secret": "98f5a68541a6d981bf5825f23dffe6a0b150e457", "is_verified": false, - "line_number": 62, - "type": "Secret Keyword" + "line_number": 46 } ], "helm/dicom-server/README.md": [ { - "hashed_secret": "b47233f6f28e9716c72d5eba0278edea3a24baad", - "is_secret": false, + "type": "Secret Keyword", + "filename": "helm/dicom-server/README.md", + "hashed_secret": "afc848c316af1a89d49826c5ae9d00ed769415f3", "is_verified": false, - "line_number": 35, - "type": "Secret Keyword" + "line_number": 35 }, { - "hashed_secret": "3f6d5580af2ddf647ca25346aa6ec9c434577d05", - "is_secret": false, + "type": "Secret Keyword", + "filename": "helm/dicom-server/README.md", + "hashed_secret": "706168ac2565a93cceffe2202ac45d3d31c075fb", "is_verified": false, - "line_number": 51, - "type": "Secret Keyword" + "line_number": 51 } ], "helm/dicom-server/values.yaml": [ { - "hashed_secret": "afc848c316af1a89d49826c5ae9d00ed769415f3", - "is_secret": false, - "is_verified": false, - "line_number": 81, - "type": "Secret Keyword" - } - ], - "helm/fence/README.md": [ - { - "hashed_secret": "7f57cb0116aa983d9844a39f6da9244cf98036b1", - "is_secret": false, + "type": "Secret Keyword", + "filename": "helm/dicom-server/values.yaml", + "hashed_secret": "706168ac2565a93cceffe2202ac45d3d31c075fb", "is_verified": false, - "line_number": 90, - "type": "Secret Keyword" + "line_number": 38 }, { - "hashed_secret": "b266a6d0f00bb36f6b98134bf4cec71f2d7943a3", - "is_secret": false, - "is_verified": false, - "line_number": 100, - "type": "Secret Keyword" - }, - { - "hashed_secret": "d84ce25b0f9bc2cc263006ae39453efb22cc2900", - "is_secret": false, - "is_verified": false, - "line_number": 124, - "type": "Secret Keyword" - }, - { - "hashed_secret": "f09dd6e359833a12f48c4c4255d6e87a6e55cfe9", - "is_secret": false, + "type": "Secret Keyword", + "filename": "helm/dicom-server/values.yaml", + "hashed_secret": "afc848c316af1a89d49826c5ae9d00ed769415f3", "is_verified": false, - "line_number": 152, - "type": "Secret Keyword" - }, + "line_number": 81 + } + ], + "helm/etl/templates/etl-job.yaml": [ { - "hashed_secret": "5c5a68077af6fa84424411537dda76467f993a83", - "is_secret": false, + "type": "Secret Keyword", + "filename": "helm/etl/templates/etl-job.yaml", + "hashed_secret": "c3b140ae268f3d8bfa93290e59013c359b82121a", "is_verified": false, - "line_number": 198, - "type": "Secret Keyword" + "line_number": 42 } ], - "helm/fence/fence-secret/config_helper.py": [ + "helm/fence/README.md": [ { - "hashed_secret": "bf21a9e8fbc5a3846fb05b4fa0859e0917b2202f", - "is_secret": false, + "type": "Secret Keyword", + "filename": "helm/fence/README.md", + "hashed_secret": "dbd5f43594a152b52261c8e21520a3989823fe55", "is_verified": false, - "line_number": 66, - "type": "Basic Auth Credentials" + "line_number": 198 } ], "helm/fence/fence-secret/fence_settings.py": [ { - "hashed_secret": "3ef0fb8a603abdc0b6caac44a23fdc6792f77ddf", - "is_secret": false, - "is_verified": false, - "line_number": 6, - "type": "Basic Auth Credentials" - }, - { - "hashed_secret": "b60d121b438a380c343d5ec3c2037564b82ffef3", - "is_secret": false, - "is_verified": false, - "line_number": 58, - "type": "Secret Keyword" - }, - { + "type": "Basic Auth Credentials", + "filename": "helm/fence/fence-secret/fence_settings.py", "hashed_secret": "347cd9c53ff77d41a7b22aa56c7b4efaf54658e3", - "is_secret": false, "is_verified": false, - "line_number": 80, - "type": "Basic Auth Credentials" + "line_number": 80 } ], - "helm/fence/templates/fence-creds.yaml": [ + "helm/fence/templates/external-secret.yaml": [ { - "hashed_secret": "c2dae5a3c7ce218639b38d8a0256f02fe81d439e", - "is_secret": false, + "type": "Secret Keyword", + "filename": "helm/fence/templates/external-secret.yaml", + "hashed_secret": "5008414000b5273eb326fe4ce333571a228ae703", "is_verified": false, - "line_number": 11, - "type": "Secret Keyword" + "line_number": 15 }, { - "hashed_secret": "1f5e25be9b575e9f5d39c82dfd1d9f4d73f1975c", - "is_secret": false, + "type": "Secret Keyword", + "filename": "helm/fence/templates/external-secret.yaml", + "hashed_secret": "0b637d0a797a9293bbfcdca533e876d78d78f558", "is_verified": false, - "line_number": 14, - "type": "Secret Keyword" + "line_number": 33 }, { - "hashed_secret": "8db3b325254b6389ca194d829d2fc923dc0a945d", - "is_secret": false, + "type": "Secret Keyword", + "filename": "helm/fence/templates/external-secret.yaml", + "hashed_secret": "996aa6966ca452e6f14c52713bef2df482334834", "is_verified": false, - "line_number": 15, - "type": "Secret Keyword" - } - ], - "helm/fence/values.yaml": [ + "line_number": 51 + }, { - "hashed_secret": "5d07e1b80e448a213b392049888111e1779a52db", - "is_secret": false, + "type": "Secret Keyword", + "filename": "helm/fence/templates/external-secret.yaml", + "hashed_secret": "5b23ec09bab9f7aabb800f2ee6fcd23fbf5b090e", "is_verified": false, - "line_number": 1956, - "type": "Secret Keyword" + "line_number": 69 } ], - "helm/frontend-framework/README.md": [ + "helm/fence/templates/usersync-cron.yaml": [ { - "hashed_secret": "2546383b95bb44732e9be6a877fd476c0442fdab", - "is_secret": false, + "type": "Secret Keyword", + "filename": "helm/fence/templates/usersync-cron.yaml", + "hashed_secret": "4b09a441cef18c75560f6c3caeafc96f2163c3fd", "is_verified": false, - "line_number": 48, - "type": "Secret Keyword" + "line_number": 41 }, { - "hashed_secret": "d84ce25b0f9bc2cc263006ae39453efb22cc2900", - "is_secret": false, + "type": "Secret Keyword", + "filename": "helm/fence/templates/usersync-cron.yaml", + "hashed_secret": "694cfd0a009a42055e975de9111b2f3c6e8a3634", "is_verified": false, - "line_number": 50, - "type": "Secret Keyword" - } - ], - "helm/gen3/README.md": [ - { - "hashed_secret": "7422c958ec5a8e5f87c9e81cdf426ef0e193332c", - "is_secret": false, - "is_verified": false, - "line_number": 83, - "type": "Secret Keyword" + "line_number": 44 }, { - "hashed_secret": "1740c48fa3141d4851b14f97e3bc0f46f7670672", - "is_secret": false, + "type": "Secret Keyword", + "filename": "helm/fence/templates/usersync-cron.yaml", + "hashed_secret": "7e7478a28dcc3695a083b66b47243b050c813e2d", "is_verified": false, - "line_number": 121, - "type": "Secret Keyword" - } - ], - "helm/gen3/values.yaml": [ + "line_number": 51 + }, { - "hashed_secret": "9b5925ea817163740dfb287a9894e8ab3aba2c18", - "is_secret": false, + "type": "Secret Keyword", + "filename": "helm/fence/templates/usersync-cron.yaml", + "hashed_secret": "2f57bb00fcb93481c2be444e3e9f322b6cb5fadb", "is_verified": false, - "line_number": 198, - "type": "Secret Keyword" + "line_number": 54 } ], - "helm/guppy/README.md": [ + "helm/fence/templates/useryaml-job.yaml": [ { - "hashed_secret": "d84ce25b0f9bc2cc263006ae39453efb22cc2900", - "is_secret": false, + "type": "Secret Keyword", + "filename": "helm/fence/templates/useryaml-job.yaml", + "hashed_secret": "4b09a441cef18c75560f6c3caeafc96f2163c3fd", "is_verified": false, - "line_number": 57, - "type": "Secret Keyword" + "line_number": 24 } ], - "helm/hatchery/README.md": [ + "helm/fence/values.yaml": [ { - "hashed_secret": "d84ce25b0f9bc2cc263006ae39453efb22cc2900", - "is_secret": false, + "type": "Secret Keyword", + "filename": "helm/fence/values.yaml", + "hashed_secret": "dbd5f43594a152b52261c8e21520a3989823fe55", "is_verified": false, - "line_number": 44, - "type": "Secret Keyword" + "line_number": 342 }, { - "hashed_secret": "e94cc2a86b04ad4ddc98fcbf91ed236437939d47", - "is_secret": false, + "type": "Secret Keyword", + "filename": "helm/fence/values.yaml", + "hashed_secret": "1c062eaac9e6fa0766377d3cfc3e4a88982fecdb", "is_verified": false, - "line_number": 52, - "type": "Secret Keyword" - } - ], - "helm/hatchery/values.yaml": [ + "line_number": 345 + }, { - "hashed_secret": "9b5925ea817163740dfb287a9894e8ab3aba2c18", - "is_secret": false, + "type": "Secret Keyword", + "filename": "helm/fence/values.yaml", + "hashed_secret": "694cfd0a009a42055e975de9111b2f3c6e8a3634", "is_verified": false, - "line_number": 190, - "type": "Secret Keyword" - } - ], - "helm/indexd/README.md": [ + "line_number": 349 + }, { - "hashed_secret": "167402961a8c8a8b3764e865e865efa9ada95369", - "is_secret": false, + "type": "Secret Keyword", + "filename": "helm/fence/values.yaml", + "hashed_secret": "4b09a441cef18c75560f6c3caeafc96f2163c3fd", "is_verified": false, - "line_number": 27, - "type": "Secret Keyword" + "line_number": 359 }, { - "hashed_secret": "d84ce25b0f9bc2cc263006ae39453efb22cc2900", - "is_secret": false, + "type": "Secret Keyword", + "filename": "helm/fence/values.yaml", + "hashed_secret": "7e7478a28dcc3695a083b66b47243b050c813e2d", "is_verified": false, - "line_number": 51, - "type": "Secret Keyword" + "line_number": 362 }, { - "hashed_secret": "f09dd6e359833a12f48c4c4255d6e87a6e55cfe9", - "is_secret": false, + "type": "Secret Keyword", + "filename": "helm/fence/values.yaml", + "hashed_secret": "2f57bb00fcb93481c2be444e3e9f322b6cb5fadb", "is_verified": false, - "line_number": 71, - "type": "Secret Keyword" + "line_number": 365 }, { - "hashed_secret": "1cc98556e7b1353c7bd08344f9190808b0d3d6d4", - "is_secret": true, + "type": "Secret Keyword", + "filename": "helm/fence/values.yaml", + "hashed_secret": "98f5a68541a6d981bf5825f23dffe6a0b150e457", "is_verified": false, - "line_number": 105, - "type": "Secret Keyword" + "line_number": 368 } ], - "helm/indexd/indexd-settings/local_settings.py": [ + "helm/indexd/README.md": [ { - "hashed_secret": "0a0d18c85e096611b5685b62bc60ec534d19bacc", - "is_secret": false, + "type": "Secret Keyword", + "filename": "helm/indexd/README.md", + "hashed_secret": "cdf42fb619b22c6e64d7fed302b81099c3894a1f", "is_verified": false, - "line_number": 60, - "type": "Basic Auth Credentials" + "line_number": 108 } ], - "helm/manifestservice/README.md": [ + "helm/indexd/values.yaml": [ { - "hashed_secret": "cc524de4657898e872ff46e0a9256f4e186cdfe6", - "is_secret": false, + "type": "Secret Keyword", + "filename": "helm/indexd/values.yaml", + "hashed_secret": "cdf42fb619b22c6e64d7fed302b81099c3894a1f", "is_verified": false, - "line_number": 33, - "type": "Secret Keyword" - }, + "line_number": 242 + } + ], + "helm/manifestservice/README.md": [ { - "hashed_secret": "611f2e9064b518afdb23f201321f39029dd28917", - "is_secret": false, + "type": "Secret Keyword", + "filename": "helm/manifestservice/README.md", + "hashed_secret": "3da2c49c267b6c58401bbf05e379b38d20434f78", "is_verified": false, - "line_number": 83, - "type": "Secret Keyword" + "line_number": 83 } ], - "helm/manifestservice/templates/manifestservice-creds.yaml": [ + "helm/manifestservice/templates/external-secret.yaml": [ { - "hashed_secret": "d2e2ab0f407e4ee3cf2ab87d61c31b25a74085e5", - "is_secret": false, + "type": "Secret Keyword", + "filename": "helm/manifestservice/templates/external-secret.yaml", + "hashed_secret": "c5fd3201494e82cf94e6a681cdc535b306134e1a", "is_verified": false, - "line_number": 13, - "type": "Secret Keyword" + "line_number": 15 } ], - "helm/metadata/README.md": [ + "helm/manifestservice/values.yaml": [ { - "hashed_secret": "cbdb7939a61698c9c866ea614399ef7eb7770c68", - "is_secret": false, + "type": "Secret Keyword", + "filename": "helm/manifestservice/values.yaml", + "hashed_secret": "3da2c49c267b6c58401bbf05e379b38d20434f78", "is_verified": false, - "line_number": 46, - "type": "Secret Keyword" - }, + "line_number": 124 + } + ], + "helm/metadata/templates/deployment.yaml": [ { - "hashed_secret": "d84ce25b0f9bc2cc263006ae39453efb22cc2900", - "is_secret": false, + "type": "Secret Keyword", + "filename": "helm/metadata/templates/deployment.yaml", + "hashed_secret": "e14f65c8ca7f3b27a0f0f5463569954841e162c9", "is_verified": false, - "line_number": 71, - "type": "Secret Keyword" + "line_number": 41 }, { - "hashed_secret": "f09dd6e359833a12f48c4c4255d6e87a6e55cfe9", - "is_secret": false, + "type": "Secret Keyword", + "filename": "helm/metadata/templates/deployment.yaml", + "hashed_secret": "c27babf45eb0ed87329e69c7d47dba611e859c5d", "is_verified": false, - "line_number": 90, - "type": "Secret Keyword" + "line_number": 44 } ], - "helm/peregrine/README.md": [ + "helm/metadata/templates/external-secret.yaml": [ { - "hashed_secret": "d84ce25b0f9bc2cc263006ae39453efb22cc2900", - "is_secret": false, + "type": "Secret Keyword", + "filename": "helm/metadata/templates/external-secret.yaml", + "hashed_secret": "5e67ba7a34c60ad18bf31c4dd9e2bd0ff3821bf3", "is_verified": false, - "line_number": 51, - "type": "Secret Keyword" + "line_number": 15 }, { - "hashed_secret": "f09dd6e359833a12f48c4c4255d6e87a6e55cfe9", - "is_secret": false, + "type": "Secret Keyword", + "filename": "helm/metadata/templates/external-secret.yaml", + "hashed_secret": "952db9f900701ea5433801c67349403ee8e52f3c", "is_verified": false, - "line_number": 68, - "type": "Secret Keyword" + "line_number": 20 }, { - "hashed_secret": "7d4e263f1ae83868444f5327219830493a7d1486", - "is_secret": false, + "type": "Secret Keyword", + "filename": "helm/metadata/templates/external-secret.yaml", + "hashed_secret": "13c3c351f8514d003c3358851164caa0ad48e764", "is_verified": false, - "line_number": 100, - "type": "Secret Keyword" + "line_number": 25 } ], - "helm/peregrine/peregrine-secret/config_helper.py": [ + "helm/peregrine/README.md": [ { - "hashed_secret": "bf21a9e8fbc5a3846fb05b4fa0859e0917b2202f", - "is_secret": false, + "type": "Secret Keyword", + "filename": "helm/peregrine/README.md", + "hashed_secret": "6131c35d7eebdbc17a314bef8aac75b87323cff3", "is_verified": false, - "line_number": 66, - "type": "Basic Auth Credentials" + "line_number": 103 } ], "helm/peregrine/peregrine-secret/settings.py": [ { + "type": "Basic Auth Credentials", + "filename": "helm/peregrine/peregrine-secret/settings.py", "hashed_secret": "347cd9c53ff77d41a7b22aa56c7b4efaf54658e3", - "is_secret": false, "is_verified": false, - "line_number": 45, - "type": "Basic Auth Credentials" + "line_number": 45 } ], - "helm/pidgin/README.md": [ + "helm/peregrine/values.yaml": [ { - "hashed_secret": "d84ce25b0f9bc2cc263006ae39453efb22cc2900", - "is_secret": false, + "type": "Secret Keyword", + "filename": "helm/peregrine/values.yaml", + "hashed_secret": "6131c35d7eebdbc17a314bef8aac75b87323cff3", "is_verified": false, - "line_number": 54, - "type": "Secret Keyword" - }, - { - "hashed_secret": "abb751db44bcfd1bb9d4ad53e40138422abd739e", - "is_secret": false, - "is_verified": false, - "line_number": 66, - "type": "Secret Keyword" + "line_number": 217 } ], "helm/portal/README.md": [ { + "type": "Base64 High Entropy String", + "filename": "helm/portal/README.md", "hashed_secret": "eb9739c6625f06b4ab73035223366dda6262ae77", - "is_secret": false, "is_verified": false, - "line_number": 35, - "type": "Base64 High Entropy String" + "line_number": 34 }, { + "type": "Base64 High Entropy String", + "filename": "helm/portal/README.md", "hashed_secret": "08eeb737b239bdb7362a875b90e22c10b8826b20", - "is_secret": false, "is_verified": false, - "line_number": 39, - "type": "Base64 High Entropy String" + "line_number": 39 + } + ], + "helm/portal/templates/deployment.yaml": [ + { + "type": "Secret Keyword", + "filename": "helm/portal/templates/deployment.yaml", + "hashed_secret": "5c5a8e158ad2d8544f73cd5422072d414f497faa", + "is_verified": false, + "line_number": 43 }, { - "hashed_secret": "d84ce25b0f9bc2cc263006ae39453efb22cc2900", - "is_secret": false, + "type": "Secret Keyword", + "filename": "helm/portal/templates/deployment.yaml", + "hashed_secret": "619551216e129bbc5322678abf9c9210c0327cfb", "is_verified": false, - "line_number": 58, - "type": "Secret Keyword" + "line_number": 46 } ], "helm/portal/values.yaml": [ { + "type": "Base64 High Entropy String", + "filename": "helm/portal/values.yaml", "hashed_secret": "08eeb737b239bdb7362a875b90e22c10b8826b20", "is_verified": false, - "line_number": 472, - "type": "Base64 High Entropy String" + "line_number": 473 }, { + "type": "Base64 High Entropy String", + "filename": "helm/portal/values.yaml", "hashed_secret": "eb9739c6625f06b4ab73035223366dda6262ae77", "is_verified": false, - "line_number": 475, - "type": "Base64 High Entropy String" + "line_number": 475 } ], - "helm/requestor/README.md": [ + "helm/requestor/templates/deployment.yaml": [ { - "hashed_secret": "d84ce25b0f9bc2cc263006ae39453efb22cc2900", - "is_secret": false, + "type": "Secret Keyword", + "filename": "helm/requestor/templates/deployment.yaml", + "hashed_secret": "15debe4170aa5b89858d939f4c0644307ae7789b", "is_verified": false, - "line_number": 60, - "type": "Secret Keyword" - }, + "line_number": 41 + } + ], + "helm/revproxy/README.md": [ { - "hashed_secret": "f09dd6e359833a12f48c4c4255d6e87a6e55cfe9", - "is_secret": false, + "type": "Secret Keyword", + "filename": "helm/revproxy/README.md", + "hashed_secret": "ceb2f7587bfc3eaec308915205979156e0d4dfb6", "is_verified": false, - "line_number": 84, - "type": "Secret Keyword" + "line_number": 94 } ], - "helm/revproxy/README.md": [ + "helm/revproxy/gen3.nginx.conf/indexd-service.conf": [ { - "hashed_secret": "d84ce25b0f9bc2cc263006ae39453efb22cc2900", - "is_secret": false, + "type": "Secret Keyword", + "filename": "helm/revproxy/gen3.nginx.conf/indexd-service.conf", + "hashed_secret": "f89523833036f85fed37ce3ebf25492189bc9397", "is_verified": false, - "line_number": 46, - "type": "Secret Keyword" - }, + "line_number": 41 + } + ], + "helm/revproxy/gen3.nginx.conf/metadata-service.conf": [ { - "hashed_secret": "abb751db44bcfd1bb9d4ad53e40138422abd739e", - "is_secret": false, + "type": "Secret Keyword", + "filename": "helm/revproxy/gen3.nginx.conf/metadata-service.conf", + "hashed_secret": "18c0871af26eb9875c0f840b13211f097c133fd2", "is_verified": false, - "line_number": 74, - "type": "Secret Keyword" + "line_number": 24 } ], "helm/revproxy/nginx/helpers.js": [ { + "type": "Base64 High Entropy String", + "filename": "helm/revproxy/nginx/helpers.js", "hashed_secret": "1d278d3c888d1a2fa7eed622bfc02927ce4049af", - "is_secret": false, "is_verified": false, - "line_number": 10, - "type": "Base64 High Entropy String" + "line_number": 10 } ], - "helm/sheepdog/README.md": [ - { - "hashed_secret": "d84ce25b0f9bc2cc263006ae39453efb22cc2900", - "is_secret": false, - "is_verified": false, - "line_number": 60, - "type": "Secret Keyword" - }, + "helm/revproxy/templates/ingress_dev.yaml": [ { - "hashed_secret": "f09dd6e359833a12f48c4c4255d6e87a6e55cfe9", - "is_secret": false, + "type": "Secret Keyword", + "filename": "helm/revproxy/templates/ingress_dev.yaml", + "hashed_secret": "519a59c1d9d1e3f501f0c3696dddfd409c9fc7f6", "is_verified": false, - "line_number": 76, - "type": "Secret Keyword" + "line_number": 9 } ], - "helm/sheepdog/sheepdog-secret/config_helper.py": [ + "helm/revproxy/values.yaml": [ { - "hashed_secret": "bf21a9e8fbc5a3846fb05b4fa0859e0917b2202f", - "is_secret": false, + "type": "Secret Keyword", + "filename": "helm/revproxy/values.yaml", + "hashed_secret": "ceb2f7587bfc3eaec308915205979156e0d4dfb6", "is_verified": false, - "line_number": 66, - "type": "Basic Auth Credentials" + "line_number": 239 } ], "helm/sheepdog/sheepdog-secret/settings.py": [ { + "type": "Basic Auth Credentials", + "filename": "helm/sheepdog/sheepdog-secret/settings.py", "hashed_secret": "347cd9c53ff77d41a7b22aa56c7b4efaf54658e3", - "is_secret": false, "is_verified": false, - "line_number": 38, - "type": "Basic Auth Credentials" + "line_number": 38 } ], - "helm/sower/README.md": [ + "helm/sheepdog/templates/deployment.yaml": [ { - "hashed_secret": "3d4368cd822c4a36144c2bcc8cb8e90b63c7e5fe", - "is_secret": false, + "type": "Secret Keyword", + "filename": "helm/sheepdog/templates/deployment.yaml", + "hashed_secret": "ec9c944c51e87322de8d22e3ca9e2be1ad8fee0d", "is_verified": false, - "line_number": 34, - "type": "Secret Keyword" - }, + "line_number": 45 + } + ], + "helm/sower/templates/external-secret.yaml": [ { - "hashed_secret": "d84ce25b0f9bc2cc263006ae39453efb22cc2900", - "is_secret": false, + "type": "Secret Keyword", + "filename": "helm/sower/templates/external-secret.yaml", + "hashed_secret": "c5fd3201494e82cf94e6a681cdc535b306134e1a", "is_verified": false, - "line_number": 57, - "type": "Secret Keyword" + "line_number": 15 } ], - "helm/sower/templates/pelican-creds.yaml": [ + "helm/sower/values.yaml": [ { - "hashed_secret": "d2e2ab0f407e4ee3cf2ab87d61c31b25a74085e5", - "is_secret": false, + "type": "Secret Keyword", + "filename": "helm/sower/values.yaml", + "hashed_secret": "0447a636536df0264b2000403fbefd69f603ceb1", "is_verified": false, - "line_number": 14, - "type": "Secret Keyword" + "line_number": 275 } ], "helm/ssjdispatcher/README.md": [ { - "hashed_secret": "d84ce25b0f9bc2cc263006ae39453efb22cc2900", - "is_secret": false, + "type": "Secret Keyword", + "filename": "helm/ssjdispatcher/README.md", + "hashed_secret": "13d9ed7e3d69f1b6330dff80bc4658931708eddc", "is_verified": false, - "line_number": 54, - "type": "Secret Keyword" + "line_number": 93 }, { - "hashed_secret": "0c86d58792b32e1d12af733a0614837ff9002014", - "is_secret": false, + "type": "Secret Keyword", + "filename": "helm/ssjdispatcher/README.md", + "hashed_secret": "7f932449df74fc78573fea502df8a484aef3f69d", "is_verified": false, - "line_number": 110, - "type": "Secret Keyword" + "line_number": 110 } ], - "helm/ssjdispatcher/templates/ssjdispatcher-secret.yaml": [ + "helm/ssjdispatcher/values.yaml": [ { - "hashed_secret": "d2e2ab0f407e4ee3cf2ab87d61c31b25a74085e5", - "is_secret": false, + "type": "Secret Keyword", + "filename": "helm/ssjdispatcher/values.yaml", + "hashed_secret": "7f932449df74fc78573fea502df8a484aef3f69d", "is_verified": false, - "line_number": 23, - "type": "Secret Keyword" - } - ], - "helm/ssjdispatcher/values.yaml": [ + "line_number": 151 + }, { + "type": "Secret Keyword", + "filename": "helm/ssjdispatcher/values.yaml", "hashed_secret": "13d9ed7e3d69f1b6330dff80bc4658931708eddc", - "is_secret": false, "is_verified": false, - "line_number": 219, - "type": "Secret Keyword" + "line_number": 210 } ], - "helm/wts/README.md": [ + "helm/wts/templates/deployment.yaml": [ { - "hashed_secret": "d84ce25b0f9bc2cc263006ae39453efb22cc2900", - "is_secret": false, + "type": "Secret Keyword", + "filename": "helm/wts/templates/deployment.yaml", + "hashed_secret": "5de687ae886f19c3cb68d4980e3f2e77cca3db9e", "is_verified": false, - "line_number": 49, - "type": "Secret Keyword" - }, + "line_number": 55 + } + ], + "helm/wts/templates/wts-oidc.yaml": [ { - "hashed_secret": "f09dd6e359833a12f48c4c4255d6e87a6e55cfe9", - "is_secret": false, + "type": "Secret Keyword", + "filename": "helm/wts/templates/wts-oidc.yaml", + "hashed_secret": "4b09a441cef18c75560f6c3caeafc96f2163c3fd", "is_verified": false, - "line_number": 71, - "type": "Secret Keyword" + "line_number": 16 } ], "skaffold.yaml": [ { + "type": "Secret Keyword", + "filename": "skaffold.yaml", "hashed_secret": "b60d121b438a380c343d5ec3c2037564b82ffef3", - "is_secret": false, "is_verified": false, - "line_number": 30, - "type": "Secret Keyword" + "line_number": 30 + } + ], + "wip/cogwheel/values.yaml": [ + { + "type": "Secret Keyword", + "filename": "wip/cogwheel/values.yaml", + "hashed_secret": "09b772df628fd10bca646b6a877eb661122210ab", + "is_verified": false, + "line_number": 88 + } + ], + "wip/gen3-test-data-job/templates/_jobs.tpl": [ + { + "type": "Secret Keyword", + "filename": "wip/gen3-test-data-job/templates/_jobs.tpl", + "hashed_secret": "dbd5f43594a152b52261c8e21520a3989823fe55", + "is_verified": false, + "line_number": 30 + }, + { + "type": "Secret Keyword", + "filename": "wip/gen3-test-data-job/templates/_jobs.tpl", + "hashed_secret": "694cfd0a009a42055e975de9111b2f3c6e8a3634", + "is_verified": false, + "line_number": 33 + }, + { + "type": "Secret Keyword", + "filename": "wip/gen3-test-data-job/templates/_jobs.tpl", + "hashed_secret": "1c062eaac9e6fa0766377d3cfc3e4a88982fecdb", + "is_verified": false, + "line_number": 39 + }, + { + "type": "Secret Keyword", + "filename": "wip/gen3-test-data-job/templates/_jobs.tpl", + "hashed_secret": "4b09a441cef18c75560f6c3caeafc96f2163c3fd", + "is_verified": false, + "line_number": 43 + }, + { + "type": "Secret Keyword", + "filename": "wip/gen3-test-data-job/templates/_jobs.tpl", + "hashed_secret": "98f5a68541a6d981bf5825f23dffe6a0b150e457", + "is_verified": false, + "line_number": 46 + } + ], + "wip/gen3-test-data-job/templates/jobs.yaml": [ + { + "type": "Secret Keyword", + "filename": "wip/gen3-test-data-job/templates/jobs.yaml", + "hashed_secret": "dbd5f43594a152b52261c8e21520a3989823fe55", + "is_verified": false, + "line_number": 25 + }, + { + "type": "Secret Keyword", + "filename": "wip/gen3-test-data-job/templates/jobs.yaml", + "hashed_secret": "694cfd0a009a42055e975de9111b2f3c6e8a3634", + "is_verified": false, + "line_number": 28 + }, + { + "type": "Secret Keyword", + "filename": "wip/gen3-test-data-job/templates/jobs.yaml", + "hashed_secret": "1c062eaac9e6fa0766377d3cfc3e4a88982fecdb", + "is_verified": false, + "line_number": 34 + }, + { + "type": "Secret Keyword", + "filename": "wip/gen3-test-data-job/templates/jobs.yaml", + "hashed_secret": "4b09a441cef18c75560f6c3caeafc96f2163c3fd", + "is_verified": false, + "line_number": 38 + }, + { + "type": "Secret Keyword", + "filename": "wip/gen3-test-data-job/templates/jobs.yaml", + "hashed_secret": "98f5a68541a6d981bf5825f23dffe6a0b150e457", + "is_verified": false, + "line_number": 41 + } + ], + "wip/terraform-runner-job/templates/jobs.yaml": [ + { + "type": "Secret Keyword", + "filename": "wip/terraform-runner-job/templates/jobs.yaml", + "hashed_secret": "46e720b52d3e01656ece610aa0e3da76399efeee", + "is_verified": false, + "line_number": 16 + }, + { + "type": "Secret Keyword", + "filename": "wip/terraform-runner-job/templates/jobs.yaml", + "hashed_secret": "8a2826a1835e0ae675154a3db30fbe7a40218d69", + "is_verified": false, + "line_number": 19 } ] }, - "version": "0.13.1", - "word_list": { - "file": null, - "hash": null - } + "generated_at": "2024-10-09T21:29:00Z" } diff --git a/helm/ambassador/Chart.yaml b/helm/ambassador/Chart.yaml index 7ff947a9..cfcde763 100644 --- a/helm/ambassador/Chart.yaml +++ b/helm/ambassador/Chart.yaml @@ -15,7 +15,7 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.12 +version: 0.1.13 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to diff --git a/helm/ambassador/README.md b/helm/ambassador/README.md index cc66f836..18e39969 100644 --- a/helm/ambassador/README.md +++ b/helm/ambassador/README.md @@ -1,6 +1,6 @@ # ambassador -![Version: 0.1.12](https://img.shields.io/badge/Version-0.1.12-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 1.4.2](https://img.shields.io/badge/AppVersion-1.4.2-informational?style=flat-square) +![Version: 0.1.13](https://img.shields.io/badge/Version-0.1.13-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 1.4.2](https://img.shields.io/badge/AppVersion-1.4.2-informational?style=flat-square) A Helm chart for deploying ambassador for gen3 @@ -57,3 +57,5 @@ A Helm chart for deploying ambassador for gen3 | tolerations | list | `[]` | Tolerations to use for the deployment. | | userNamespace | string | `"jupyter-pods"` | Namespace to use for user resources. | +---------------------------------------------- +Autogenerated from chart metadata using [helm-docs v1.13.1](https://github.com/norwoodj/helm-docs/releases/v1.13.1) diff --git a/helm/arborist/Chart.yaml b/helm/arborist/Chart.yaml index 555c11fa..54028cca 100644 --- a/helm/arborist/Chart.yaml +++ b/helm/arborist/Chart.yaml @@ -15,7 +15,7 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.12 +version: 0.1.13 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to diff --git a/helm/arborist/README.md b/helm/arborist/README.md index 87670b6c..787b51a0 100644 --- a/helm/arborist/README.md +++ b/helm/arborist/README.md @@ -1,6 +1,6 @@ # arborist -![Version: 0.1.12](https://img.shields.io/badge/Version-0.1.12-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) +![Version: 0.1.13](https://img.shields.io/badge/Version-0.1.13-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) A Helm chart for gen3 arborist @@ -43,7 +43,7 @@ A Helm chart for gen3 arborist | global.kubeBucket | string | `"kube-gen3"` | S3 bucket name for Kubernetes manifest files. | | global.logsBucket | string | `"logs-gen3"` | S3 bucket name for log files. | | global.minAvialable | int | `1` | The minimum amount of pods that are available at all times if the PDB is deployed. | -| global.netPolicy | bool | `true` | Whether network policies are enabled. | +| global.netPolicy | bool | `{"enabled":true}` | Whether network policies are enabled. | | global.pdb | bool | `false` | If the service will be deployed with a Pod Disruption Budget. Note- you need to have more than 2 replicas for the pdb to be deployed. | | global.portalApp | string | `"gitops"` | Portal application name. | | global.postgres.dbCreate | bool | `true` | Whether the database should be created. | @@ -102,3 +102,5 @@ A Helm chart for gen3 arborist | volumeMounts | list | `[]` | Volume mounts to attach to the container | | volumes | list | `[]` | Volumes to attach to the pod | +---------------------------------------------- +Autogenerated from chart metadata using [helm-docs v1.13.1](https://github.com/norwoodj/helm-docs/releases/v1.13.1) diff --git a/helm/arborist/templates/netpolicy.yaml b/helm/arborist/templates/netpolicy.yaml new file mode 100644 index 00000000..70a5c3b5 --- /dev/null +++ b/helm/arborist/templates/netpolicy.yaml @@ -0,0 +1 @@ +{{ include "common.db_netpolicy" . }} \ No newline at end of file diff --git a/helm/arborist/values.yaml b/helm/arborist/values.yaml index f49035ef..03603f3c 100644 --- a/helm/arborist/values.yaml +++ b/helm/arborist/values.yaml @@ -2,7 +2,6 @@ # This is a YAML-formatted file. # Declare variables to be passed into your templates. - # Global configuration global: # -- (map) AWS configuration @@ -50,7 +49,8 @@ global: # -- (string) Access level for tiers. acceptable values for `tier_access_level` are: `libre`, `regular` and `private`. If omitted, by default common will be treated as `private` tierAccessLevel: libre # -- (bool) Whether network policies are enabled. - netPolicy: true + netPolicy: + enabled: true # -- (int) Number of dispatcher jobs. dispatcherJobNum: "10" # -- (bool) If the service will be deployed with a Pod Disruption Budget. Note- you need to have more than 2 replicas for the pdb to be deployed. @@ -103,7 +103,6 @@ postgresql: # -- (bool) Option to persist the dbs data. enabled: false - # -- (int) Number of replicas for the deployment. replicaCount: 1 @@ -144,7 +143,8 @@ podSecurityContext: # fsGroup: 2000 # -- (map) Security context to apply to the container -securityContext: {} +securityContext: + {} # -- (map) Linux capabilities to drop # capabilities: @@ -216,7 +216,6 @@ env: - name: JWKS_ENDPOINT value: "http://fence-service/.well-known/jwks" - # Values to determine the labels that are used for the deployment, pod, etc. # -- (string) Valid options are "production" or "dev". If invalid option is set- the value will default to "dev". release: "production" diff --git a/helm/argo-wrapper/Chart.yaml b/helm/argo-wrapper/Chart.yaml index b43e8925..6d9e37ae 100644 --- a/helm/argo-wrapper/Chart.yaml +++ b/helm/argo-wrapper/Chart.yaml @@ -15,7 +15,7 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.8 +version: 0.1.9 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to diff --git a/helm/argo-wrapper/README.md b/helm/argo-wrapper/README.md index 0507e7fc..87a4de2b 100644 --- a/helm/argo-wrapper/README.md +++ b/helm/argo-wrapper/README.md @@ -1,6 +1,6 @@ # argo-wrapper -![Version: 0.1.8](https://img.shields.io/badge/Version-0.1.8-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) +![Version: 0.1.9](https://img.shields.io/badge/Version-0.1.9-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) A Helm chart for gen3 Argo Wrapper Service @@ -39,6 +39,9 @@ A Helm chart for gen3 Argo Wrapper Service | indexdAdminUser | string | `"fence"` | Admin user for Indexd. | | internalS3Bucket | string | `"argo-internal-bucket"` | Name of the internal Argo bucket for Argo artifacts (does not allow pre-signed URLs). | | metricsEnabled | bool | `false` | Whether Metrics are enabled. | +| netPolicy | map | `{"egressApps":["argo-wrapper"],"ingressApps":["argo-wrapper"]}` | Configuration for network policies created by this chart. Only relevant if "global.netPolicy.enabled" is set to true | +| netPolicy.egressApps | array | `["argo-wrapper"]` | List of apps that this app requires egress to | +| netPolicy.ingressApps | array | `["argo-wrapper"]` | List of app labels that require ingress to this service | | partOf | string | `"Apps-Tab"` | Label to help organize pods and their use. Any value is valid, but use "_" or "-" to divide words. | | podAnnotations | map | `{"gen3.io/network-ingress":"argo-wrapper"}` | Annotations to add to the pod. | | pvc | string | `"test-pvc"` | PVC for Argo. | @@ -61,3 +64,5 @@ A Helm chart for gen3 Argo Wrapper Service | volumeMounts | list | `[{"mountPath":"/argo.json","name":"argo-config","readOnly":true,"subPath":"argo.json"}]` | Volumes to mount to the pod. | | volumes | list | `[{"configMap":{"items":[{"key":"argo.json","path":"argo.json"}],"name":"manifest-argo"},"name":"argo-config"}]` | Volumes to attach to the pod. | +---------------------------------------------- +Autogenerated from chart metadata using [helm-docs v1.13.1](https://github.com/norwoodj/helm-docs/releases/v1.13.1) diff --git a/helm/argo-wrapper/templates/netpolicy.yaml b/helm/argo-wrapper/templates/netpolicy.yaml new file mode 100644 index 00000000..0a469d51 --- /dev/null +++ b/helm/argo-wrapper/templates/netpolicy.yaml @@ -0,0 +1,5 @@ +{{ include "common.ingress_netpolicy" . }} + +--- + +{{ include "common.egress_netpolicy" . }} \ No newline at end of file diff --git a/helm/argo-wrapper/values.yaml b/helm/argo-wrapper/values.yaml index e0045f6d..535f8034 100644 --- a/helm/argo-wrapper/values.yaml +++ b/helm/argo-wrapper/values.yaml @@ -2,7 +2,6 @@ # This is a YAML-formatted file. # Declare variables to be passed into your templates. - # Global configuration global: # -- (string) Environment name. This should be the same as vpcname if you're doing an AWS deployment. Currently this is being used to share ALB's if you have multiple namespaces. Might be used other places too. @@ -17,7 +16,7 @@ metricsEnabled: false # Deployment # -- (map) Annotations to add to the pod. -podAnnotations: {"gen3.io/network-ingress": "argo-wrapper"} +podAnnotations: { "gen3.io/network-ingress": "argo-wrapper" } # -- (map) Configuration for autoscaling the number of replicas autoscaling: @@ -52,20 +51,20 @@ affinity: podAntiAffinity: # -- (map) Option for scheduling to be required or preferred. preferredDuringSchedulingIgnoredDuringExecution: - # -- (int) Weight value for preferred scheduling. - - weight: 100 - podAffinityTerm: - labelSelector: - matchExpressions: - # -- (list) Label key for match expression. - - key: app - # -- (string) Operation type for the match expression. - operator: In - # -- (list) Value for the match expression key. - values: - - argo-wrapper - # -- (string) Value for topology key label. - topologyKey: "kubernetes.io/hostname" + # -- (int) Weight value for preferred scheduling. + - weight: 100 + podAffinityTerm: + labelSelector: + matchExpressions: + # -- (list) Label key for match expression. + - key: app + # -- (string) Operation type for the match expression. + operator: In + # -- (list) Value for the match expression key. + values: + - argo-wrapper + # -- (string) Value for topology key label. + topologyKey: "kubernetes.io/hostname" # -- (list) Volumes to attach to the pod. volumes: @@ -108,12 +107,22 @@ service: # -- (int) The port number that the service exposes. port: 8000 +# -- (map) Configuration for network policies created by this chart. Only relevant if "global.netPolicy.enabled" is set to true +netPolicy: + # -- (array) List of app labels that require ingress to this service + ingressApps: + - argo-wrapper + + # -- (array) List of apps that this app requires egress to + egressApps: + - argo-wrapper + # Configmap # -- (list) The workflow scaling groups to be used by Argo. scalingGroups: -- user1: "workflow1" -- user2: "workflow2" -- user3: "workflow3" + - user1: "workflow1" + - user2: "workflow2" + - user3: "workflow3" # -- (string) S3 bucket name for Argo artifacts (allows pre-signed URLs). s3Bucket: "argo-artifact-downloadable" # -- (string) Name of the internal Argo bucket for Argo artifacts (does not allow pre-signed URLs). diff --git a/helm/audit/Chart.yaml b/helm/audit/Chart.yaml index 4112d571..b77dc25f 100644 --- a/helm/audit/Chart.yaml +++ b/helm/audit/Chart.yaml @@ -15,7 +15,7 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.13 +version: 0.1.14 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to diff --git a/helm/audit/README.md b/helm/audit/README.md index c840cd72..46ecc76f 100644 --- a/helm/audit/README.md +++ b/helm/audit/README.md @@ -1,6 +1,6 @@ # audit -![Version: 0.1.13](https://img.shields.io/badge/Version-0.1.13-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) +![Version: 0.1.14](https://img.shields.io/badge/Version-0.1.14-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) A Helm chart for Kubernetes @@ -53,7 +53,7 @@ A Helm chart for Kubernetes | global.kubeBucket | string | `"kube-gen3"` | S3 bucket name for Kubernetes manifest files. | | global.logsBucket | string | `"logs-gen3"` | S3 bucket name for log files. | | global.minAvialable | int | `1` | The minimum amount of pods that are available at all times if the PDB is deployed. | -| global.netPolicy | bool | `true` | Whether network policies are enabled. | +| global.netPolicy | bool | `{"enabled":true}` | Whether network policies are enabled. | | global.pdb | bool | `false` | If the service will be deployed with a Pod Disruption Budget. Note- you need to have more than 2 replicas for the pdb to be deployed. | | global.portalApp | string | `"gitops"` | Portal application name. | | global.postgres.dbCreate | bool | `true` | Whether the database should be created. | @@ -75,6 +75,9 @@ A Helm chart for Kubernetes | initVolumeMounts | list | `[]` | Volumes to mount to the init container. | | metricsEnabled | bool | `false` | Whether Metrics are enabled. | | nameOverride | string | `""` | Override the name of the chart. This can be used to provide a unique name for a chart | +| netPolicy | map | `{"egressApps":["fence","presigned-url-fence"],"ingressApps":["fence","presigned-url-fence"]}` | Configuration for network policies created by this chart. Only relevant if "global.netPolicy.enabled" is set to true | +| netPolicy.egressApps | array | `["fence","presigned-url-fence"]` | List of apps that this app requires egress to | +| netPolicy.ingressApps | array | `["fence","presigned-url-fence"]` | List of app labels that require ingress to this service | | nodeSelector | map | `{}` | Node Selector for the pods | | partOf | string | `"Logging"` | Label to help organize pods and their use. Any value is valid, but use "_" or "-" to divide words. | | podAnnotations | map | `{}` | Annotations to add to the pod | @@ -120,3 +123,5 @@ A Helm chart for Kubernetes | volumeMounts | list | `[]` | Volumes to mount to the container. | | volumes | list | `[]` | Volumes to attach to the container. | +---------------------------------------------- +Autogenerated from chart metadata using [helm-docs v1.13.1](https://github.com/norwoodj/helm-docs/releases/v1.13.1) diff --git a/helm/audit/templates/netpolicy.yaml b/helm/audit/templates/netpolicy.yaml new file mode 100644 index 00000000..93949e3a --- /dev/null +++ b/helm/audit/templates/netpolicy.yaml @@ -0,0 +1,9 @@ +{{ include "common.db_netpolicy" . }} + +--- + +{{ include "common.ingress_netpolicy" . }} + +--- + +{{ include "common.egress_netpolicy" . }} \ No newline at end of file diff --git a/helm/audit/values.yaml b/helm/audit/values.yaml index 4e58d5aa..6c62b1e5 100644 --- a/helm/audit/values.yaml +++ b/helm/audit/values.yaml @@ -49,7 +49,8 @@ global: # -- (string) Access level for tiers. acceptable values for `tier_access_level` are: `libre`, `regular` and `private`. If omitted, by default common will be treated as `private` tierAccessLevel: libre # -- (bool) Whether network policies are enabled. - netPolicy: true + netPolicy: + enabled: true # -- (int) Number of dispatcher jobs. dispatcherJobNum: "10" # -- (bool) If the service will be deployed with a Pod Disruption Budget. Note- you need to have more than 2 replicas for the pdb to be deployed. @@ -148,7 +149,8 @@ podAnnotations: {} podSecurityContext: {} # -- (map) Security context for the containers in the pod -securityContext: {} +securityContext: + {} # capabilities: # drop: @@ -164,6 +166,17 @@ service: # -- (int) Port on which the service is exposed port: 80 +# -- (map) Configuration for network policies created by this chart. Only relevant if "global.netPolicy.enabled" is set to true +netPolicy: + # -- (array) List of app labels that require ingress to this service + ingressApps: + - fence + - presigned-url-fence + # -- (array) List of apps that this app requires egress to + egressApps: + - fence + - presigned-url-fence + # -- (map) Resource requests and limits for the containers in the pod resources: # -- (map) The amount of resources that the container requests @@ -191,7 +204,6 @@ autoscaling: targetCPUUtilizationPercentage: 80 # targetMemoryUtilizationPercentage: 80 - # -- (map) Node Selector for the pods nodeSelector: {} @@ -203,20 +215,20 @@ affinity: podAntiAffinity: # -- (map) Option for scheduling to be required or preferred. preferredDuringSchedulingIgnoredDuringExecution: - # -- (int) Weight value for preferred scheduling. - - weight: 100 - podAffinityTerm: - labelSelector: - matchExpressions: - # -- (list) Label key for match expression. - - key: app - # -- (string) Operation type for the match expression. - operator: In - # -- (list) Value for the match expression key. - values: - - audit - # -- (string) Value for topology key label. - topologyKey: "kubernetes.io/hostname" + # -- (int) Weight value for preferred scheduling. + - weight: 100 + podAffinityTerm: + labelSelector: + matchExpressions: + # -- (list) Label key for match expression. + - key: app + # -- (string) Operation type for the match expression. + operator: In + # -- (list) Value for the match expression key. + values: + - audit + # -- (string) Value for topology key label. + topologyKey: "kubernetes.io/hostname" # -- (list) Environment variables to pass to the container env: @@ -253,7 +265,8 @@ server: # -- (string) The URL for the SQS queue. url: "http://sqs.com" # -- (map) AWS credentials to access SQS queue. - AWS_CREDENTIALS: {} + AWS_CREDENTIALS: + {} # cred1: # aws_access_key_id: # aws_secret_access_key: diff --git a/helm/aws-es-proxy/Chart.yaml b/helm/aws-es-proxy/Chart.yaml index 4b3e15e7..57991f51 100644 --- a/helm/aws-es-proxy/Chart.yaml +++ b/helm/aws-es-proxy/Chart.yaml @@ -15,7 +15,7 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.10 +version: 0.1.11 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to diff --git a/helm/aws-es-proxy/README.md b/helm/aws-es-proxy/README.md index 27fe4289..df8ba4ef 100644 --- a/helm/aws-es-proxy/README.md +++ b/helm/aws-es-proxy/README.md @@ -1,6 +1,6 @@ # aws-es-proxy -![Version: 0.1.10](https://img.shields.io/badge/Version-0.1.10-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) +![Version: 0.1.11](https://img.shields.io/badge/Version-0.1.11-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) A Helm chart for AWS ES Proxy Service for gen3 @@ -39,6 +39,9 @@ A Helm chart for AWS ES Proxy Service for gen3 | image.repository | string | `"quay.io/cdis/aws-es-proxy"` | Docker repository. | | image.tag | string | `""` | Overrides the image tag whose default is the chart appVersion. | | metricsEnabled | bool | `false` | Whether Metrics are enabled. | +| netPolicy | map | `{"egressApps":["arranger","arranger-server","arranger-dashboard","guppy","metadata","spark","tube"],"ingressApps":["arranger","arranger-server","arranger-dashboard","guppy","metadata","spark","tube"]}` | Configuration for network policies created by this chart. Only relevant if "global.netPolicy.enabled" is set to true | +| netPolicy.egressApps | array | `["arranger","arranger-server","arranger-dashboard","guppy","metadata","spark","tube"]` | List of apps that this app requires egress to | +| netPolicy.ingressApps | array | `["arranger","arranger-server","arranger-dashboard","guppy","metadata","spark","tube"]` | List of app labels that require ingress to this service | | partOf | string | `"Explorer-Tab"` | Label to help organize pods and their use. Any value is valid, but use "_" or "-" to divide words. | | podAnnotations | map | `nil` | Annotations to add to the pod | | ports | list | `[{"containerPort":9200}]` | List of container ports | @@ -64,3 +67,5 @@ A Helm chart for AWS ES Proxy Service for gen3 | volumeMounts | list | `[{"mountPath":"/root/.aws","name":"credentials","readOnly":true}]` | Volumes to mount to the pod. | | volumes | list | `nil` | Volumes to attach to the pod | +---------------------------------------------- +Autogenerated from chart metadata using [helm-docs v1.13.1](https://github.com/norwoodj/helm-docs/releases/v1.13.1) diff --git a/helm/aws-es-proxy/templates/netpolicy.yaml b/helm/aws-es-proxy/templates/netpolicy.yaml new file mode 100644 index 00000000..0a469d51 --- /dev/null +++ b/helm/aws-es-proxy/templates/netpolicy.yaml @@ -0,0 +1,5 @@ +{{ include "common.ingress_netpolicy" . }} + +--- + +{{ include "common.egress_netpolicy" . }} \ No newline at end of file diff --git a/helm/aws-es-proxy/values.yaml b/helm/aws-es-proxy/values.yaml index b053eb5e..fd2686ec 100644 --- a/helm/aws-es-proxy/values.yaml +++ b/helm/aws-es-proxy/values.yaml @@ -2,7 +2,6 @@ # This is a YAML-formatted file. # Declare variables to be passed into your templates. - # Global configuration global: # -- (map) AWS configuration @@ -117,6 +116,27 @@ service: # -- (int) The port number that the service exposes. port: 9200 +# -- (map) Configuration for network policies created by this chart. Only relevant if "global.netPolicy.enabled" is set to true +netPolicy: + # -- (array) List of app labels that require ingress to this service + ingressApps: + - arranger + - arranger-server + - arranger-dashboard + - guppy + - metadata + - spark + - tube + # -- (array) List of apps that this app requires egress to + egressApps: + - arranger + - arranger-server + - arranger-dashboard + - guppy + - metadata + - spark + - tube + # Values to determine the labels that are used for the deployment, pod, etc. # -- (string) Valid options are "production" or "dev". If invalid option is set- the value will default to "dev". release: "production" diff --git a/helm/common/Chart.yaml b/helm/common/Chart.yaml index 428238e2..1e8308c6 100644 --- a/helm/common/Chart.yaml +++ b/helm/common/Chart.yaml @@ -15,7 +15,7 @@ type: library # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.14 +version: 0.1.15 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to diff --git a/helm/common/README.md b/helm/common/README.md index 6888a8c4..1ff085b1 100644 --- a/helm/common/README.md +++ b/helm/common/README.md @@ -1,6 +1,6 @@ # common -![Version: 0.1.14](https://img.shields.io/badge/Version-0.1.14-informational?style=flat-square) ![Type: library](https://img.shields.io/badge/Type-library-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) +![Version: 0.1.15](https://img.shields.io/badge/Version-0.1.15-informational?style=flat-square) ![Type: library](https://img.shields.io/badge/Type-library-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) A Helm chart for provisioning databases in gen3 @@ -18,7 +18,7 @@ A Helm chart for provisioning databases in gen3 | global.hostname | string | `"localhost"` | Hostname for the deployment. | | global.kubeBucket | string | `"kube-gen3"` | S3 bucket name for Kubernetes manifest files. | | global.logsBucket | string | `"logs-gen3"` | S3 bucket name for log files. | -| global.netPolicy | bool | `true` | Whether network policies are enabled. | +| global.netPolicy | bool | `{"enabled":true}` | Whether network policies are enabled. | | global.portalApp | string | `"gitops"` | Portal application name. | | global.postgres.dbCreate | bool | `true` | Whether the database should be created. | | global.postgres.externalSecret | string | `""` | Name of external secret. Disabled if empty | @@ -31,3 +31,5 @@ A Helm chart for provisioning databases in gen3 | global.revproxyArn | string | `"arn:aws:acm:us-east-1:123456:certificate"` | ARN of the reverse proxy certificate. | | global.tierAccessLevel | string | `"libre"` | Access level for tiers. acceptable values for `tier_access_level` are: `libre`, `regular` and `private`. If omitted, by default common will be treated as `private` | +---------------------------------------------- +Autogenerated from chart metadata using [helm-docs v1.13.1](https://github.com/norwoodj/helm-docs/releases/v1.13.1) diff --git a/helm/common/templates/_netpolicy_templates.tpl b/helm/common/templates/_netpolicy_templates.tpl new file mode 100644 index 00000000..267134f1 --- /dev/null +++ b/helm/common/templates/_netpolicy_templates.tpl @@ -0,0 +1,66 @@ +{{/* + Templates for network policies that can be used by various subcharts +*/}} + +{{ define "common.db_netpolicy" -}} + {{- if .Values.global.netPolicy.enabled }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ .Chart.Name }}-db-netpolicy +spec: + egress: + - to: + - ipBlock: + cidr: {{ .Values.global.netPolicy.dbSubnet }} + podSelector: + matchLabels: + app: {{ .Chart.Name }} + policyTypes: + - Egress + {{- end }} +{{- end }} + +{{ define "common.ingress_netpolicy" -}} + {{- if .Values.global.netPolicy.enabled }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ .Chart.Name }}-ingress-netpolicy +spec: + podSelector: + matchLabels: + app: {{ .Chart.Name }} + ingress: + - from: + - podSelector: + matchExpressions: + - key: app + operator: In + values: {{ toYaml .Values.netPolicy.ingressApps | nindent 12 }} + policyTypes: + - Ingress + {{- end }} +{{- end }} + +{{ define "common.egress_netpolicy" -}} + {{- if .Values.global.netPolicy.enabled }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ .Chart.Name }}-egress-netpolicy +spec: + podSelector: + matchExpressions: + - key: app + operator: In + values: {{ toYaml .Values.netPolicy.ingressApps | nindent 6 }} + egress: + - to: + - podSelector: + matchLabels: + app: {{ .Chart.Name }} + policyTypes: + - Egress + {{- end }} +{{- end }} \ No newline at end of file diff --git a/helm/common/values.yaml b/helm/common/values.yaml index 51b8616b..19feb2e4 100644 --- a/helm/common/values.yaml +++ b/helm/common/values.yaml @@ -2,7 +2,6 @@ # This is a YAML-formatted file. # Declare variables to be passed into your templates. - # Global configuration global: # -- (map) AWS configuration @@ -46,7 +45,8 @@ global: # -- (string) Access level for tiers. acceptable values for `tier_access_level` are: `libre`, `regular` and `private`. If omitted, by default common will be treated as `private` tierAccessLevel: libre # -- (bool) Whether network policies are enabled. - netPolicy: true + netPolicy: + enabled: true # -- (int) Number of dispatcher jobs. dispatcherJobNum: "10" # -- (bool) Whether Datadog is enabled. diff --git a/helm/dicom-server/Chart.yaml b/helm/dicom-server/Chart.yaml index 9737e96a..9a765b5f 100644 --- a/helm/dicom-server/Chart.yaml +++ b/helm/dicom-server/Chart.yaml @@ -15,7 +15,7 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.9 +version: 0.1.10 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to diff --git a/helm/dicom-server/README.md b/helm/dicom-server/README.md index 644f3d32..bee47187 100644 --- a/helm/dicom-server/README.md +++ b/helm/dicom-server/README.md @@ -1,6 +1,6 @@ # dicom-server -![Version: 0.1.9](https://img.shields.io/badge/Version-0.1.9-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) +![Version: 0.1.10](https://img.shields.io/badge/Version-0.1.10-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) A Helm chart for gen3 Dicom Server @@ -50,3 +50,5 @@ A Helm chart for gen3 Dicom Server | volumeMounts | list | `[{"mountPath":"/etc/orthanc/orthanc_config_overwrites.json","name":"config-volume-g3auto","readOnly":true,"subPath":"orthanc_config_overwrites.json"}]` | Volumes to mount to the pod. | | volumes | list | `[{"name":"config-volume-g3auto","secret":{"secretName":"orthanc-g3auto"}}]` | Volumes to attach to the pod. | +---------------------------------------------- +Autogenerated from chart metadata using [helm-docs v1.13.1](https://github.com/norwoodj/helm-docs/releases/v1.13.1) diff --git a/helm/dicom-server/templates/netpolicy.yaml b/helm/dicom-server/templates/netpolicy.yaml new file mode 100644 index 00000000..70a5c3b5 --- /dev/null +++ b/helm/dicom-server/templates/netpolicy.yaml @@ -0,0 +1 @@ +{{ include "common.db_netpolicy" . }} \ No newline at end of file diff --git a/helm/dicom-viewer/Chart.yaml b/helm/dicom-viewer/Chart.yaml index f14ad58e..e8c989c5 100644 --- a/helm/dicom-viewer/Chart.yaml +++ b/helm/dicom-viewer/Chart.yaml @@ -15,7 +15,7 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.9 +version: 0.1.10 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to diff --git a/helm/dicom-viewer/README.md b/helm/dicom-viewer/README.md index 141f8c65..845b6984 100644 --- a/helm/dicom-viewer/README.md +++ b/helm/dicom-viewer/README.md @@ -1,6 +1,6 @@ # dicom-viewer -![Version: 0.1.9](https://img.shields.io/badge/Version-0.1.9-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) +![Version: 0.1.10](https://img.shields.io/badge/Version-0.1.10-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) A Helm chart for gen3 Dicom Viewer @@ -37,3 +37,5 @@ A Helm chart for gen3 Dicom Viewer | service.port | int | `80` | The port number that the service exposes. | | service.type | string | `"ClusterIP"` | Type of service. Valid values are "ClusterIP", "NodePort", "LoadBalancer", "ExternalName". | +---------------------------------------------- +Autogenerated from chart metadata using [helm-docs v1.13.1](https://github.com/norwoodj/helm-docs/releases/v1.13.1) diff --git a/helm/etl/Chart.yaml b/helm/etl/Chart.yaml index c5b08a7b..3a862865 100644 --- a/helm/etl/Chart.yaml +++ b/helm/etl/Chart.yaml @@ -15,7 +15,7 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.1 +version: 0.1.2 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to diff --git a/helm/etl/README.md b/helm/etl/README.md index faa4d2f2..9d7a43ee 100644 --- a/helm/etl/README.md +++ b/helm/etl/README.md @@ -1,6 +1,6 @@ # etl -![Version: 0.1.1](https://img.shields.io/badge/Version-0.1.1-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) +![Version: 0.1.2](https://img.shields.io/badge/Version-0.1.2-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) A Helm chart for gen3 etl @@ -103,3 +103,5 @@ A Helm chart for gen3 etl | resources.tube.requests.cpu | string | `0.3` | The amount of CPU requested | | resources.tube.requests.memory | string | `"128Mi"` | The amount of memory requested | +---------------------------------------------- +Autogenerated from chart metadata using [helm-docs v1.13.1](https://github.com/norwoodj/helm-docs/releases/v1.13.1) diff --git a/helm/fence/Chart.yaml b/helm/fence/Chart.yaml index b591966e..f69ccd11 100644 --- a/helm/fence/Chart.yaml +++ b/helm/fence/Chart.yaml @@ -15,7 +15,7 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.23 +version: 0.1.24 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to diff --git a/helm/fence/README.md b/helm/fence/README.md index 3a5f4b18..0344e81c 100644 --- a/helm/fence/README.md +++ b/helm/fence/README.md @@ -1,6 +1,6 @@ # fence -![Version: 0.1.23](https://img.shields.io/badge/Version-0.1.23-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) +![Version: 0.1.24](https://img.shields.io/badge/Version-0.1.24-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) A Helm chart for gen3 Fence @@ -116,7 +116,7 @@ A Helm chart for gen3 Fence | global.kubeBucket | string | `"kube-gen3"` | S3 bucket name for Kubernetes manifest files. | | global.logsBucket | string | `"logs-gen3"` | S3 bucket name for log files. | | global.minAvialable | int | `1` | The minimum amount of pods that are available at all times if the PDB is deployed. | -| global.netPolicy | bool | `true` | Whether network policies are enabled. | +| global.netPolicy | bool | `{"enabled":true}` | Whether network policies are enabled. | | global.pdb | bool | `false` | If the service will be deployed with a Pod Disruption Budget. Note- you need to have more than 2 replicas for the pdb to be deployed. | | global.portalApp | string | `"gitops"` | Portal application name. | | global.postgres.dbCreate | bool | `true` | Whether the database should be created. | @@ -197,3 +197,5 @@ A Helm chart for gen3 Fence | volumeMounts | list | `[{"mountPath":"/var/www/fence/local_settings.py","name":"old-config-volume","readOnly":true,"subPath":"local_settings.py"},{"mountPath":"/var/www/fence/fence_credentials.json","name":"json-secret-volume","readOnly":true,"subPath":"fence_credentials.json"},{"mountPath":"/var/www/fence/creds.json","name":"creds-volume","readOnly":true,"subPath":"creds.json"},{"mountPath":"/var/www/fence/config_helper.py","name":"config-helper","readOnly":true,"subPath":"config_helper.py"},{"mountPath":"/fence/fence/static/img/logo.svg","name":"logo-volume","readOnly":true,"subPath":"logo.svg"},{"mountPath":"/fence/fence/static/privacy_policy.md","name":"privacy-policy","readOnly":true,"subPath":"privacy_policy.md"},{"mountPath":"/var/www/fence/fence-config-secret.yaml","name":"config-volume","readOnly":true,"subPath":"fence-config.yaml"},{"mountPath":"/var/www/fence/yaml_merge.py","name":"yaml-merge","readOnly":true,"subPath":"yaml_merge.py"},{"mountPath":"/var/www/fence/fence_google_app_creds_secret.json","name":"fence-google-app-creds-secret-volume","readOnly":true,"subPath":"fence_google_app_creds_secret.json"},{"mountPath":"/var/www/fence/fence_google_storage_creds_secret.json","name":"fence-google-storage-creds-secret-volume","readOnly":true,"subPath":"fence_google_storage_creds_secret.json"},{"mountPath":"/fence/keys/key/jwt_private_key.pem","name":"fence-jwt-keys","readOnly":true,"subPath":"jwt_private_key.pem"},{"mountPath":"/var/www/fence/fence-config-public.yaml","name":"config-volume-public","readOnly":true,"subPath":"fence-config-public.yaml"}]` | Volumes to mount to the container. | | volumes | list | `[{"name":"old-config-volume","secret":{"secretName":"fence-secret"}},{"name":"json-secret-volume","secret":{"optional":true,"secretName":"fence-json-secret"}},{"name":"creds-volume","secret":{"secretName":"fence-creds"}},{"configMap":{"name":"config-helper","optional":true},"name":"config-helper"},{"configMap":{"name":"logo-config"},"name":"logo-volume"},{"name":"config-volume","secret":{"secretName":"fence-config"}},{"name":"fence-google-app-creds-secret-volume","secret":{"secretName":"fence-google-app-creds-secret"}},{"name":"fence-google-storage-creds-secret-volume","secret":{"secretName":"fence-google-storage-creds-secret"}},{"name":"fence-jwt-keys","secret":{"secretName":"fence-jwt-keys"}},{"configMap":{"name":"privacy-policy"},"name":"privacy-policy"},{"configMap":{"name":"fence-yaml-merge","optional":false},"name":"yaml-merge"},{"configMap":{"name":"manifest-fence","optional":true},"name":"config-volume-public"}]` | Volumes to attach to the container. | +---------------------------------------------- +Autogenerated from chart metadata using [helm-docs v1.13.1](https://github.com/norwoodj/helm-docs/releases/v1.13.1) diff --git a/helm/fence/templates/netpolicy.yaml b/helm/fence/templates/netpolicy.yaml new file mode 100644 index 00000000..70a5c3b5 --- /dev/null +++ b/helm/fence/templates/netpolicy.yaml @@ -0,0 +1 @@ +{{ include "common.db_netpolicy" . }} \ No newline at end of file diff --git a/helm/fence/values.yaml b/helm/fence/values.yaml index 026811a7..7b6a4d7d 100644 --- a/helm/fence/values.yaml +++ b/helm/fence/values.yaml @@ -2,7 +2,6 @@ # This is a YAML-formatted file. # Declare variables to be passed into your templates. - # Global configuration global: # -- (map) AWS configuration @@ -62,7 +61,8 @@ global: # -- (int) Only relevant if tireAccessLevel is set to "regular". Summary charts below this limit will not appear for aggregated data. tierAccessLimit: "1000" # -- (bool) Whether network policies are enabled. - netPolicy: true + netPolicy: + enabled: true # -- (int) Number of dispatcher jobs. dispatcherJobNum: "10" # -- (bool) If the service will be deployed with a Pod Disruption Budget. Note- you need to have more than 2 replicas for the pdb to be deployed. @@ -193,7 +193,8 @@ podSecurityContext: fsGroup: 101 # -- (map) Security context for the containers in the pod -securityContext: {} +securityContext: + {} # capabilities: # drop: # - ALL @@ -223,7 +224,6 @@ resources: # -- (string) The maximum amount of memory the container can use memory: 2Gi - # -- (map) Configuration for autoscaling the number of replicas autoscaling: # -- (bool) Whether autoscaling is enabled @@ -259,20 +259,20 @@ affinity: podAntiAffinity: # -- (map) Option for scheduling to be required or preferred. preferredDuringSchedulingIgnoredDuringExecution: - # -- (int) Weight value for preferred scheduling. - - weight: 100 - podAffinityTerm: - labelSelector: - matchExpressions: - # -- (list) Label key for match expression. - - key: app - # -- (string) Operation type for the match expression. - operator: In - # -- (list) Value for the match expression key. - values: - - fence - # -- (string) Value for topology key label. - topologyKey: "kubernetes.io/hostname" + # -- (int) Weight value for preferred scheduling. + - weight: 100 + podAffinityTerm: + labelSelector: + matchExpressions: + # -- (list) Label key for match expression. + - key: app + # -- (string) Operation type for the match expression. + operator: In + # -- (list) Value for the match expression key. + values: + - fence + # -- (string) Value for topology key label. + topologyKey: "kubernetes.io/hostname" # -- (list) Environment variables to pass to the container env: @@ -1392,7 +1392,7 @@ FENCE_CONFIG_PUBLIC: {} # -- (map) Private configuration settings for Fence app FENCE_CONFIG: # -- (string) Name of the Fence app - APP_NAME: 'Gen3 Data Commons' + APP_NAME: "Gen3 Data Commons" # -- (string) A URL-safe base64-encoded 32-byte key for encrypting keys in db # in python you can use the following script to generate one: @@ -1440,7 +1440,7 @@ FENCE_CONFIG: ENABLE_CSRF_PROTECTION: true # -- (str) signing key for WTForms to sign CSRF tokens with - WTF_CSRF_SECRET_KEY: '{{ENCRYPTION_KEY}}' + WTF_CSRF_SECRET_KEY: "{{ENCRYPTION_KEY}}" # -- (bool) fence (at the moment) attempts a migration on startup. setting this to false will disable that # WARNING: ONLY set to false if you do NOT want to automatically migrate your database. @@ -1450,7 +1450,6 @@ FENCE_CONFIG: # NOTE: We are working to improve the migration process in the near future ENABLE_DB_MIGRATION: true - # -- (dict) Configurations for OpenID Connect (OIDC) authentication # - Fully configure at least one client so login works # - WARNING: Be careful changing the *_ALLOWED_SCOPES as you can break basic @@ -1458,32 +1457,32 @@ FENCE_CONFIG: OPENID_CONNECT: # any OIDC IDP that does not differ from the generic implementation can be # configured without code changes - generic_oidc_idp: # choose a unique ID and replace this key + generic_oidc_idp: # choose a unique ID and replace this key # -- (str) Optional; display name for this IDP - name: 'some_idp' + name: "some_idp" # -- (str) Client ID - client_id: '' + client_id: "" # -- (str) Client secret - client_secret: '' + client_secret: "" # -- (str) Redirect URL for this IDP - redirect_url: '{{BASE_URL}}/login/some_idp/login' # replace IDP name + redirect_url: "{{BASE_URL}}/login/some_idp/login" # replace IDP name # use `discovery` to configure IDPs that do not expose a discovery # endpoint. One of `discovery_url` or `discovery` should be configured # -- (str) URL of the OIDC discovery endpoint for the IDP - discovery_url: 'https://server.com/.well-known/openid-configuration' + discovery_url: "https://server.com/.well-known/openid-configuration" discovery: # -- (str) Authorization endpoint URL - authorization_endpoint: '' + authorization_endpoint: "" # -- (str) Token endpoint URL - token_endpoint: '' + token_endpoint: "" # -- (str) JSON Web Key Set (JWKS) URI - jwks_uri: '' + jwks_uri: "" # -- (str) Optional; claims field to get the user_id from (default "sub") - user_id_field: '' + user_id_field: "" # -- (str) Optional; claims field to get the user email from (default "email") - email_field: '' + email_field: "" # -- (str) Optional; default is "openid" - scope: '' + scope: "" # These Google values must be obtained from Google's Cloud Console # Follow: https://developers.google.com/identity/protocols/OpenIDConnect # @@ -1493,24 +1492,24 @@ FENCE_CONFIG: # -- (dict) Configuration for Google authentication provider google: # -- (str) URL of the OIDC discovery endpoint for Google - discovery_url: 'https://accounts.google.com/.well-known/openid-configuration' + discovery_url: "https://accounts.google.com/.well-known/openid-configuration" # -- (str) Client ID - client_id: '' + client_id: "" # -- (str) Client secret - client_secret: '' + client_secret: "" # -- (str) The allowed redirect back to fence, should not need to change - redirect_url: '{{BASE_URL}}/login/google/login/' + redirect_url: "{{BASE_URL}}/login/google/login/" # -- (str) The scope to request from Google (default "openid email") - scope: 'openid email' + scope: "openid email" # if mock is true, will fake a successful login response from Google in /login/google # NOTE: this will also modify the behavior of /link/google endpoints # WARNING: DO NOT ENABLE IN PRODUCTION (for testing purposes only) # will login as the username set in cookie DEV_LOGIN_COOKIE_NAME or default provided # here # -- (str) Optional; defaults to '{{MOCK_GOOGLE_AUTH}}' for backwards compatibility with older cfg files - mock: '' + mock: "" # -- (str) Optional; defaults to 'test@example.com' - mock_default_user: 'test@example.com' + mock_default_user: "test@example.com" # -- (dict): Contains multi-tenant Fence configuration # Support for multi-tenant fence (another fence is this fence's IDP) @@ -1520,40 +1519,40 @@ FENCE_CONFIG: # -- (str): Root URL for the other fence # this api_base_url should be the root url for the OTHER fence # something like: https://example.com - api_base_url: '' + api_base_url: "" # -- (str): ID of the client of this fence on the other fence # this client_id and client_secret should be obtained by registering THIS fence as # a new client of the OTHER fence - client_id: '' + client_id: "" # -- (str): Secret of the client of this fence on the other fence - client_secret: '' + client_secret: "" # -- dict: Additional client parameters client_kwargs: # -- (str): Space-separated string of scopes # openid is required to use OIDC flow - scope: 'openid' + scope: "openid" # -- (str): The URL to which the other fence will redirect after logging in - redirect_uri: '{{BASE_URL}}/login/fence/login' + redirect_uri: "{{BASE_URL}}/login/fence/login" # -- (str): URL for authorization endpoint of the other fence # The next 3 should not need to be changed if the provider is following # Oauth2 endpoint naming conventions - authorize_url: '{{api_base_url}}/oauth2/authorize' + authorize_url: "{{api_base_url}}/oauth2/authorize" # -- (str): URL for access token endpoint of the other fence - access_token_url: '{{api_base_url}}/oauth2/token' + access_token_url: "{{api_base_url}}/oauth2/token" # -- (str): URL for refresh token endpoint of the other fence - refresh_token_url: '{{api_base_url}}/oauth2/token' + refresh_token_url: "{{api_base_url}}/oauth2/token" # -- (str): Name of the provider for consent screens # Custom name to display for consent screens. If not provided, will use `fence`. # If the other fence is using NIH Login, you should make name: `NIH Login` - name: '' + name: "" # -- (bool): Whether to mock a successful login response for testing purposes # if mock is true, will fake a successful login response for login @@ -1561,72 +1560,72 @@ FENCE_CONFIG: mock: false # -- (str): Default user for mock login - mock_default_user: 'test@example.com' + mock_default_user: "test@example.com" # -- (str): URL of the shibboleth discovery endpoint if needed for InCommon login # this is needed to enable InCommon login, if some LOGIN_OPTIONS are configured with idp=fence and a list of shib_idps: - shibboleth_discovery_url: 'https://login.bionimbus.org/Shibboleth.sso/DiscoFeed' + shibboleth_discovery_url: "https://login.bionimbus.org/Shibboleth.sso/DiscoFeed" orcid: - discovery_url: 'https://orcid.org/.well-known/openid-configuration' - client_id: '' - client_secret: '' + discovery_url: "https://orcid.org/.well-known/openid-configuration" + client_id: "" + client_secret: "" # make sure you put the FULL url for this deployment in the allowed redirects in # ORCID.org. DO NOT include {{BASE_URL}} at ORCID.org, you need to actually put the # full url - redirect_url: '{{BASE_URL}}/login/orcid/login/' - scope: 'openid' + redirect_url: "{{BASE_URL}}/login/orcid/login/" + scope: "openid" # if mock is true, will fake a successful login response for login # WARNING: DO NOT ENABLE IN PRODUCTION (for testing purposes only) mock: false - mock_default_user: '0000-0002-2601-8132' + mock_default_user: "0000-0002-2601-8132" ras: - discovery_url: 'https://sts.nih.gov/.well-known/openid-configuration' - client_id: '' - client_secret: '' - redirect_url: '{{BASE_URL}}/login/ras/callback' - scope: 'openid email profile ga4gh_passport_v1' + discovery_url: "https://sts.nih.gov/.well-known/openid-configuration" + client_id: "" + client_secret: "" + redirect_url: "{{BASE_URL}}/login/ras/callback" + scope: "openid email profile ga4gh_passport_v1" # if mock is true, will fake a successful login response for login # WARNING: DO NOT ENABLE IN PRODUCTION (for testing purposes only) mock: false - mock_default_user: 'test@example.com' + mock_default_user: "test@example.com" # Create a client in Azure here: # https://portal.azure.com/#blade/Microsoft_AAD_IAM/ActiveDirectoryMenuBlade/RegisteredAppsPreview # Currently supports organizational account only, so when registering a new App in # Azure, make sure to select the `Accounts in any organizational directory` for # supported account types. microsoft: - discovery_url: 'https://login.microsoftonline.com/organizations/v2.0/.well-known/openid-configuration' + discovery_url: "https://login.microsoftonline.com/organizations/v2.0/.well-known/openid-configuration" # after registering a new appl, client_id can be found as # "APPLICATION (CLIENT) ID" in Microsoft Azure - client_id: '' + client_id: "" # You have a generate a secret in Azure for this app, there should be a # "Certificates & secrets" section where you can create a "New client secret" - client_secret: '' + client_secret: "" # make sure you put the FULL url for this deployment in the allowed redirects in # your app in Azure. DO NOT include {{BASE_URL}} in Azure, you need to actually put the # full url - redirect_url: '{{BASE_URL}}/login/microsoft/login/' - scope: 'openid email' + redirect_url: "{{BASE_URL}}/login/microsoft/login/" + scope: "openid email" # if mock is true, will fake a successful login response for login # WARNING: DO NOT ENABLE IN PRODUCTION (for testing purposes only) mock: false - mock_default_user: 'test@example.com' + mock_default_user: "test@example.com" # For information on configuring an Okta tenant as an OIDC IdP refer to Okta documentation at: # https://developer.okta.com/docs/reference/api/oidc/#2-okta-as-the-identity-platform-for-your-app-or-api okta: - discovery_url: '' - client_id: '' - client_secret: '' - redirect_url: '{{BASE_URL}}/login/okta/login/' - scope: 'openid email' + discovery_url: "" + client_id: "" + client_secret: "" + redirect_url: "{{BASE_URL}}/login/okta/login/" + scope: "openid email" cognito: # You must create a user pool in order to have a discovery url - discovery_url: 'https://cognito-idp.{REGION}.amazonaws.com/{USER-POOL-ID}/.well-known/openid-configuration' - client_id: '' - client_secret: '' - redirect_url: '{{BASE_URL}}/login/cognito/login/' - scope: 'openid email' + discovery_url: "https://cognito-idp.{REGION}.amazonaws.com/{USER-POOL-ID}/.well-known/openid-configuration" + client_id: "" + client_secret: "" + redirect_url: "{{BASE_URL}}/login/cognito/login/" + scope: "openid email" # In the case where Cognito is being used solely as an intermediary to a single IdP, # and that IdP is a SAML IdP with no 'email_verified' outgoing claim, but it is safe # to assume all emails from this SAML IdP are in fact verified, we may set this to True @@ -1634,28 +1633,28 @@ FENCE_CONFIG: # CILogon subscribers can create and manage OIDC clients using COmanage Registry. # Free tier users may request OIDC clients at https://cilogon.org/oauth2/register cilogon: - discovery_url: 'https://cilogon.org/.well-known/openid-configuration' - client_id: '' - client_secret: '' + discovery_url: "https://cilogon.org/.well-known/openid-configuration" + client_id: "" + client_secret: "" # When registering the Callback URLs for your CILogon OIDC client be # sure to include the FULL url for this deployment, including the https:// scheme # and server FQDN. - redirect_url: '{{BASE_URL}}/login/cilogon/login/' - scope: 'openid email profile' + redirect_url: "{{BASE_URL}}/login/cilogon/login/" + scope: "openid email profile" # if mock is true, will fake a successful login response for login # WARNING: DO NOT ENABLE IN PRODUCTION (for testing purposes only) mock: false - mock_default_user: 'http://cilogon.org/serverT/users/64703' + mock_default_user: "http://cilogon.org/serverT/users/64703" synapse: - discovery_url: '' - client_id: '' - client_secret: '' - redirect_url: '' - scope: 'openid' + discovery_url: "" + client_id: "" + client_secret: "" + redirect_url: "" + scope: "openid" shibboleth: - client_id: '' - client_secret: '' - redirect_url: '{{BASE_URL}}/login/shib/login' + client_id: "" + client_secret: "" + redirect_url: "{{BASE_URL}}/login/shib/login" # these are the *possible* scopes a client can be given, NOT scopes that are # given to all clients. You can be more restrictive during client creation @@ -1669,7 +1668,6 @@ FENCE_CONFIG: - "google_link" - "ga4gh_passport_v1" - # -- (list) these are the scopes that CAN be included in a user's own access_token USER_ALLOWED_SCOPES: - "fence" @@ -1682,7 +1680,6 @@ FENCE_CONFIG: - "google_link" - "ga4gh_passport_v1" - # -- (list) these are the scopes that a browser session can create for a user (very similar to USER_ALLOWED_SCOPES, as the session will actually create access_tokens for an actively logged in user) SESSION_ALLOWED_SCOPES: - "openid" @@ -1715,15 +1712,15 @@ FENCE_CONFIG: # be used by the frontend to display secondary buttons differently). # -- (list) List of enabled login options (used by data-portal to display login buttons). LOGIN_OPTIONS: - - name: 'Login from Google' - desc: 'description' + - name: "Login from Google" + desc: "description" idp: google # -- (string) Default login provider. - must be configured in LOGIN_OPTIONS and OPENID_CONNECT - - if several options in LOGIN_OPTIONS are defined for this IDP, will default to the first one DEFAULT_LOGIN_IDP: google # -- (string) Default login URL: DEPRECATED and replaced by LOGIN_OPTIONS + DEFAULT_LOGIN_IDP configs - DEFAULT_LOGIN_URL: '{{BASE_URL}}/login/google' + DEFAULT_LOGIN_URL: "{{BASE_URL}}/login/google" # `LOGIN_REDIRECT_WHITELIST` is a list of extra whitelisted URLs which can be redirected # to by the `/login/*` endpoints. Fence automatically populates this with the redirect @@ -1735,7 +1732,6 @@ FENCE_CONFIG: ### DEPRECATED and replaced by OPENID_CONNECT + LOGIN_OPTIONS configs ENABLED_IDENTITY_PROVIDERS: {} - # ////////////////////////////////////////////////////////////////////////////////////// # LIBRARY CONFIGURATION (authlib & flask) # - Already contains reasonable defaults @@ -1743,16 +1739,15 @@ FENCE_CONFIG: # authlib-specific configs for OIDC flow and JWTs # NOTE: the OAUTH2_JWT_KEY cfg gets set automatically by fence if keys are setup # correctly - OAUTH2_JWT_ALG: 'RS256' + OAUTH2_JWT_ALG: "RS256" OAUTH2_JWT_ENABLED: true - OAUTH2_JWT_ISS: '{{BASE_URL}}' - OAUTH2_PROVIDER_ERROR_URI: '/api/oauth2/errors' + OAUTH2_JWT_ISS: "{{BASE_URL}}" + OAUTH2_PROVIDER_ERROR_URI: "/api/oauth2/errors" # used for flask, "path mounted under by the application / web server" # since we deploy as microservices, fence is typically under {{base}}/user # this is also why our BASE_URL default ends in /user - APPLICATION_ROOT: '/user' - + APPLICATION_ROOT: "/user" # ////////////////////////////////////////////////////////////////////////////////////// # Tokens, Lifetimes, & Expirations @@ -1850,9 +1845,9 @@ FENCE_CONFIG: # - Contains defaults for using NIH's Login. # ////////////////////////////////////////////////////////////////////////////////////// # assumes shibboleth is deployed under {{BASE_URL}}/shibboleth - SHIBBOLETH_HEADER: 'persistent_id' - SSO_URL: 'https://auth.nih.gov/affwebservices/public/saml2sso?SPID={{BASE_URL}}/shibboleth&RelayState=' - ITRUST_GLOBAL_LOGOUT: 'https://auth.nih.gov/siteminderagent/smlogout.asp?mode=nih&AppReturnUrl=' + SHIBBOLETH_HEADER: "persistent_id" + SSO_URL: "https://auth.nih.gov/affwebservices/public/saml2sso?SPID={{BASE_URL}}/shibboleth&RelayState=" + ITRUST_GLOBAL_LOGOUT: "https://auth.nih.gov/siteminderagent/smlogout.asp?mode=nih&AppReturnUrl=" # ////////////////////////////////////////////////////////////////////////////////////// # dbGaP USER SYNCING SUPPORT @@ -1865,13 +1860,13 @@ FENCE_CONFIG: # fence's README for more information dbGaP: - info: - host: '' - username: '' - password: '' + host: "" + username: "" + password: "" port: 22 - proxy: '' - protocol: 'sftp' - decrypt_key: '' + proxy: "" + protocol: "sftp" + decrypt_key: "" # parse out the consent from the dbgap accession number such that something # like "phs000123.v1.p1.c2" becomes "phs000123.c2". # @@ -1891,7 +1886,7 @@ FENCE_CONFIG: # subsequently gives access to an Arborist resource representing this common area # as well) study_common_exchange_areas: - 'example': 'test_common_exchange_area' + "example": "test_common_exchange_area" # 'studyX': 'test_common_exchange_area' # 'studyY': 'test_common_exchange_area' # 'studyZ': 'test_common_exchange_area' @@ -1899,8 +1894,8 @@ FENCE_CONFIG: # actual data lives in. For example, `studyX` data may exist in multiple organizations, so # we need to know how to map authorization to all orgs resources study_to_resource_namespaces: - '_default': ['/'] - 'test_common_exchange_area': ['/dbgap/'] + "_default": ["/"] + "test_common_exchange_area": ["/dbgap/"] # above are for default support and exchange area support # below are further examples # @@ -1915,7 +1910,7 @@ FENCE_CONFIG: # Will NOT MATCH forms like: phs000123 # # WARNING: Do not change this without consulting the code that uses it - DBGAP_ACCESSION_WITH_CONSENT_REGEX: '(?Pphs[0-9]+)(.(?Pv[0-9]+)){0,1}(.(?Pp[0-9]+)){0,1}.(?Pc[0-9]+)' + DBGAP_ACCESSION_WITH_CONSENT_REGEX: "(?Pphs[0-9]+)(.(?Pv[0-9]+)){0,1}(.(?Pp[0-9]+)){0,1}.(?Pc[0-9]+)" # ////////////////////////////////////////////////////////////////////////////////////// # STORAGE BACKENDS AND CREDENTIALS @@ -1993,7 +1988,7 @@ FENCE_CONFIG: # `DATA_UPLOAD_BUCKET` specifies an S3 bucket to which data files are uploaded, # using the `/data/upload` endpoint. This must be one of the first keys under # `S3_BUCKETS` (since these are the buckets fence has credentials for). - DATA_UPLOAD_BUCKET: 'bucket1' + DATA_UPLOAD_BUCKET: "bucket1" # ////////////////////////////////////////////////////////////////////////////////////// # PROXY @@ -2015,9 +2010,9 @@ FENCE_CONFIG: INDEXD: http://indexd-service # this is the username which fence uses to make authenticated requests to indexd - INDEXD_USERNAME: 'fence' + INDEXD_USERNAME: "fence" # this is the password which fence uses to make authenticated requests to indexd - INDEXD_PASSWORD: '' + INDEXD_PASSWORD: "" # ////////////////////////////////////////////////////////////////////////////////////// # AZURE STORAGE BLOB CONFIGURATION @@ -2031,13 +2026,13 @@ FENCE_CONFIG: # AZ_BLOB_CONTAINER_URL: 'https://storageaccount.blob.core.windows.net/container/' # this is the container used for uploading, and should match the storage account # used in the connection string for AZ_BLOB_CREDENTIALS - AZ_BLOB_CONTAINER_URL: 'https://myfakeblob.blob.core.windows.net/my-fake-container/' + AZ_BLOB_CONTAINER_URL: "https://myfakeblob.blob.core.windows.net/my-fake-container/" # url where authz microservice is running ARBORIST: http://arborist-service # url where the audit-service is running - AUDIT_SERVICE: 'http://audit-service' + AUDIT_SERVICE: "http://audit-service" ENABLE_AUDIT_LOGS: presigned_url: false login: false @@ -2060,20 +2055,20 @@ FENCE_CONFIG: # Setting this up allows fence to create buckets, manage Google groups, etc. # See directions here for setting up cirrus: https://github.com/uc-cdis/cirrus CIRRUS_CFG: - GOOGLE_API_KEY: '' - GOOGLE_PROJECT_ID: '' - GOOGLE_APPLICATION_CREDENTIALS: '' - GOOGLE_STORAGE_CREDS: '' - GOOGLE_ADMIN_EMAIL: '' - GOOGLE_IDENTITY_DOMAIN: '' - GOOGLE_CLOUD_IDENTITY_ADMIN_EMAIL: '' + GOOGLE_API_KEY: "" + GOOGLE_PROJECT_ID: "" + GOOGLE_APPLICATION_CREDENTIALS: "" + GOOGLE_STORAGE_CREDS: "" + GOOGLE_ADMIN_EMAIL: "" + GOOGLE_IDENTITY_DOMAIN: "" + GOOGLE_CLOUD_IDENTITY_ADMIN_EMAIL: "" # Prefix to namespace Google Groups on a single Cloud Identity (see cirrus # setup for more info on Cloud Identity) # # NOTE: Make this short! Less than 8 characters if possible. Google has # length restrictions on group names. - GOOGLE_GROUP_PREFIX: '' + GOOGLE_GROUP_PREFIX: "" # Prefix to namespace Google Service Accounts in a single Google Cloud Platform Project. # This is primarily to support multiple instances of fence references the same Google @@ -2081,7 +2076,7 @@ FENCE_CONFIG: # # NOTE: Make this short! Less than 8 characters if possible. Google has # length restrictions on service account names. - GOOGLE_SERVICE_ACCOUNT_PREFIX: '' + GOOGLE_SERVICE_ACCOUNT_PREFIX: "" # A Google Project identitifier representing the default project to bill to for # accessing Google Requester Pays buckets (for signed urls and/or temporary service account @@ -2120,17 +2115,17 @@ FENCE_CONFIG: # # NOTE: Example in comments below GUN_MAIL: - 'datacommons.io': - smtp_hostname: 'smtp.mailgun.org' - api_key: '' - default_login: 'postmaster@mailgun.example.com' - api_url: 'https://api.mailgun.net/v3/mailgun.example.com' - smtp_password: '' + "datacommons.io": + smtp_hostname: "smtp.mailgun.org" + api_key: "" + default_login: "postmaster@mailgun.example.com" + api_url: "https://api.mailgun.net/v3/mailgun.example.com" + smtp_password: "" # For emails regarding users certificates - EMAIL_SERVER: 'localhost' - SEND_FROM: 'example@gmail.com' - SEND_TO: 'example@gmail.com' + EMAIL_SERVER: "localhost" + SEND_FROM: "example@gmail.com" + SEND_TO: "example@gmail.com" # ////////////////////////////////////////////////////////////////////////////////////// # DATA ACCESS: GOOGLE LINKING & SERVICE ACCOUNT REGISTRATION @@ -2161,9 +2156,9 @@ FENCE_CONFIG: REMOVE_SERVICE_ACCOUNT_EMAIL_NOTIFICATION: enable: false # this domain MUST exist in GUN_MAIL config - domain: 'example.com' - from: 'do-not-reply@example.com' - subject: 'User service account removal notification' + domain: "example.com" + from: "do-not-reply@example.com" + subject: "User service account removal notification" # the {} gets replaced dynamically in the Python code to be the Project ID content: > Service accounts were removed from access control data because some users or @@ -2174,13 +2169,13 @@ FENCE_CONFIG: # # WARNING: This is NOT a bcc so the email is visible to the end-user admin: - - 'admin@example.edu' + - "admin@example.edu" PROBLEM_USER_EMAIL_NOTIFICATION: # this domain MUST exist in GUN_MAIL config - domain: 'example.com' - from: 'do-not-reply@example.com' - subject: 'Account access error notification' + domain: "example.com" + from: "do-not-reply@example.com" + subject: "Account access error notification" # the {} gets replaced dynamically in the Python code to be the Project ID content: > The Data Commons Framework utilizes dbGaP for data access authorization. @@ -2192,55 +2187,55 @@ FENCE_CONFIG: # # WARNING: This is NOT a bcc so the email is visible to the end-user admin: - - 'admin@example.edu' + - "admin@example.edu" # Service account email domains that represent a service account that Google owns. # These are usually created when a sepcific GCP service is enabled. # This is used for Service Account Validation for Data Access. GOOGLE_MANAGED_SERVICE_ACCOUNT_DOMAINS: - - 'dataflow-service-producer-prod.iam.gserviceaccount.com' - - 'cloudbuild.gserviceaccount.com' - - 'cloud-ml.google.com.iam.gserviceaccount.com' - - 'container-engine-robot.iam.gserviceaccount.com' - - 'dataflow-service-producer-prod.iam.gserviceaccount.com' - - 'sourcerepo-service-accounts.iam.gserviceaccount.com' - - 'dataproc-accounts.iam.gserviceaccount.com' - - 'gae-api-prod.google.com.iam.gserviceaccount.com' - - 'genomics-api.google.com.iam.gserviceaccount.com' - - 'containerregistry.iam.gserviceaccount.com' - - 'container-analysis.iam.gserviceaccount.com' - - 'cloudservices.gserviceaccount.com' - - 'stackdriver-service.iam.gserviceaccount.com' - - 'appspot.gserviceaccount.com' - - 'partnercontent.gserviceaccount.com' - - 'trifacta-gcloud-prod.iam.gserviceaccount.com' - - 'gcf-admin-robot.iam.gserviceaccount.com' - - 'compute-system.iam.gserviceaccount.com' - - 'gcp-sa-websecurityscanner.iam.gserviceaccount.com' - - 'storage-transfer-service.iam.gserviceaccount.com' - - 'firebase-sa-management.iam.gserviceaccount.com' - - 'firebase-rules.iam.gserviceaccount.com' - - 'gcp-sa-cloudbuild.iam.gserviceaccount.com' - - 'gcp-sa-automl.iam.gserviceaccount.com' - - 'gcp-sa-datalabeling.iam.gserviceaccount.com' - - 'gcp-sa-cloudscheduler.iam.gserviceaccount.com' + - "dataflow-service-producer-prod.iam.gserviceaccount.com" + - "cloudbuild.gserviceaccount.com" + - "cloud-ml.google.com.iam.gserviceaccount.com" + - "container-engine-robot.iam.gserviceaccount.com" + - "dataflow-service-producer-prod.iam.gserviceaccount.com" + - "sourcerepo-service-accounts.iam.gserviceaccount.com" + - "dataproc-accounts.iam.gserviceaccount.com" + - "gae-api-prod.google.com.iam.gserviceaccount.com" + - "genomics-api.google.com.iam.gserviceaccount.com" + - "containerregistry.iam.gserviceaccount.com" + - "container-analysis.iam.gserviceaccount.com" + - "cloudservices.gserviceaccount.com" + - "stackdriver-service.iam.gserviceaccount.com" + - "appspot.gserviceaccount.com" + - "partnercontent.gserviceaccount.com" + - "trifacta-gcloud-prod.iam.gserviceaccount.com" + - "gcf-admin-robot.iam.gserviceaccount.com" + - "compute-system.iam.gserviceaccount.com" + - "gcp-sa-websecurityscanner.iam.gserviceaccount.com" + - "storage-transfer-service.iam.gserviceaccount.com" + - "firebase-sa-management.iam.gserviceaccount.com" + - "firebase-rules.iam.gserviceaccount.com" + - "gcp-sa-cloudbuild.iam.gserviceaccount.com" + - "gcp-sa-automl.iam.gserviceaccount.com" + - "gcp-sa-datalabeling.iam.gserviceaccount.com" + - "gcp-sa-cloudscheduler.iam.gserviceaccount.com" # The types of service accounts that are allowed to be registered at # /google/service_accounts endpoints ALLOWED_USER_SERVICE_ACCOUNT_DOMAINS: # compute engine default service account - - 'developer.gserviceaccount.com' + - "developer.gserviceaccount.com" # app engine default service account - - 'appspot.gserviceaccount.com' + - "appspot.gserviceaccount.com" # user-managed service account - - 'iam.gserviceaccount.com' + - "iam.gserviceaccount.com" # Synapse integration and DREAM challenge mapping. Team is from Synapse, and group is # providing the actual permission in Arborist. User will be added to the group for TTL # seconds if the team matches. - DREAM_CHALLENGE_TEAM: 'DREAM' - DREAM_CHALLENGE_GROUP: 'DREAM' - SYNAPSE_URI: 'https://repo-prod.prod.sagebase.org/auth/v1' + DREAM_CHALLENGE_TEAM: "DREAM" + DREAM_CHALLENGE_GROUP: "DREAM" + SYNAPSE_URI: "https://repo-prod.prod.sagebase.org/auth/v1" SYNAPSE_JWKS_URI: # deprecated, use the discovery_url in the OPENID_CONNECT block for the synapse client SYNAPSE_DISCOVERY_URL: @@ -2255,14 +2250,14 @@ FENCE_CONFIG: # If user registers, add them to configured Arborist group; idea is that the Arborist group # will have access to download data. REGISTER_USERS_ON: false - REGISTERED_USERS_GROUP: '' + REGISTERED_USERS_GROUP: "" # RAS refresh_tokens expire in 15 days RAS_REFRESH_EXPIRATION: 1296000 # List of JWT issuers from which Fence will accept GA4GH visas GA4GH_VISA_ISSUER_ALLOWLIST: - - '{{BASE_URL}}' - - 'https://sts.nih.gov' - - 'https://stsstg.nih.gov' + - "{{BASE_URL}}" + - "https://sts.nih.gov" + - "https://stsstg.nih.gov" # Number of projects that can be registered to a Google Service Accont SERVICE_ACCOUNT_LIMIT: 6 @@ -2278,4 +2273,4 @@ FENCE_CONFIG: fallback_to_dbgap_sftp: false visa_types: ras: ["https://ras.nih.gov/visas/v1", "https://ras.nih.gov/visas/v1.1"] - RAS_USERINFO_ENDPOINT: '/openid/connect/v1.1/userinfo' + RAS_USERINFO_ENDPOINT: "/openid/connect/v1.1/userinfo" diff --git a/helm/frontend-framework/Chart.yaml b/helm/frontend-framework/Chart.yaml index 38c7a43d..bf47a659 100644 --- a/helm/frontend-framework/Chart.yaml +++ b/helm/frontend-framework/Chart.yaml @@ -15,7 +15,7 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.3 +version: 0.1.4 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to diff --git a/helm/frontend-framework/README.md b/helm/frontend-framework/README.md index 9c86f89c..58c02661 100644 --- a/helm/frontend-framework/README.md +++ b/helm/frontend-framework/README.md @@ -1,6 +1,6 @@ # frontend-framework -![Version: 0.1.3](https://img.shields.io/badge/Version-0.1.3-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: develop](https://img.shields.io/badge/AppVersion-develop-informational?style=flat-square) +![Version: 0.1.4](https://img.shields.io/badge/Version-0.1.4-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: develop](https://img.shields.io/badge/AppVersion-develop-informational?style=flat-square) A Helm chart for the gen3 frontend framework @@ -31,7 +31,7 @@ A Helm chart for the gen3 frontend framework | criticalService | string | `"true"` | Valid options are "true" or "false". If invalid option is set- the value will default to "false". | | env | list | `[]` | List of environment variables to add to the deployment. | | fullnameOverride | string | `""` | Override the full name of the deployment. | -| global | map | `{"aws":{"awsAccessKeyId":null,"awsSecretAccessKey":null,"enabled":false},"dev":true,"dictionaryUrl":"https://s3.amazonaws.com/dictionary-artifacts/datadictionary/develop/schema.json","dispatcherJobNum":10,"environment":"default","hostname":"localhost","kubeBucket":"kube-gen3","logsBucket":"logs-gen3","netPolicy":true,"portalApp":"gitops","postgres":{"dbCreate":true,"master":{"host":null,"password":null,"port":"5432","username":"postgres"}},"publicDataSets":true,"revproxyArn":"arn:aws:acm:us-east-1:123456:certificate","syncFromDbgap":false,"tierAccessLevel":"libre","userYamlS3Path":"s3://cdis-gen3-users/test/user.yaml"}` | Global configuration options. | +| global | map | `{"aws":{"awsAccessKeyId":null,"awsSecretAccessKey":null,"enabled":false},"dev":true,"dictionaryUrl":"https://s3.amazonaws.com/dictionary-artifacts/datadictionary/develop/schema.json","dispatcherJobNum":10,"environment":"default","hostname":"localhost","kubeBucket":"kube-gen3","logsBucket":"logs-gen3","netPolicy":{"enabled":true},"portalApp":"gitops","postgres":{"dbCreate":true,"master":{"host":null,"password":null,"port":"5432","username":"postgres"}},"publicDataSets":true,"revproxyArn":"arn:aws:acm:us-east-1:123456:certificate","syncFromDbgap":false,"tierAccessLevel":"libre","userYamlS3Path":"s3://cdis-gen3-users/test/user.yaml"}` | Global configuration options. | | global.aws | map | `{"awsAccessKeyId":null,"awsSecretAccessKey":null,"enabled":false}` | AWS configuration | | global.aws.awsAccessKeyId | string | `nil` | Credentials for AWS stuff. | | global.aws.awsSecretAccessKey | string | `nil` | Credentials for AWS stuff. | @@ -43,7 +43,7 @@ A Helm chart for the gen3 frontend framework | global.hostname | string | `"localhost"` | Hostname for the deployment. | | global.kubeBucket | string | `"kube-gen3"` | S3 bucket name for Kubernetes manifest files. | | global.logsBucket | string | `"logs-gen3"` | S3 bucket name for log files. | -| global.netPolicy | bool | `true` | Whether network policies are enabled. | +| global.netPolicy | bool | `{"enabled":true}` | Whether network policies are enabled. | | global.portalApp | string | `"gitops"` | Portal application name. | | global.postgres | map | `{"dbCreate":true,"master":{"host":null,"password":null,"port":"5432","username":"postgres"}}` | Postgres database configuration. | | global.postgres.dbCreate | bool | `true` | Whether the database should be created. | @@ -91,3 +91,5 @@ A Helm chart for the gen3 frontend framework | strategy.rollingUpdate.maxUnavailable | int | `"25%"` | Maximum amount of pods that can be unavailable during the update. | | tolerations | list | `[]` | Tolerations to apply to the pod | +---------------------------------------------- +Autogenerated from chart metadata using [helm-docs v1.13.1](https://github.com/norwoodj/helm-docs/releases/v1.13.1) diff --git a/helm/frontend-framework/values.yaml b/helm/frontend-framework/values.yaml index 02f8d7b7..73e9105b 100644 --- a/helm/frontend-framework/values.yaml +++ b/helm/frontend-framework/values.yaml @@ -50,7 +50,8 @@ global: # -- (string) Access level for tiers. acceptable values for `tier_access_level` are: `libre`, `regular` and `private`. If omitted, by default common will be treated as `private`. tierAccessLevel: libre # -- (bool) Whether network policies are enabled. - netPolicy: true + netPolicy: + enabled: true # -- (int) Number of dispatcher jobs. dispatcherJobNum: 10 @@ -92,11 +93,13 @@ serviceAccount: podAnnotations: {} # -- (map) Security context to apply to the pod -podSecurityContext: {} +podSecurityContext: + {} # fsGroup: 2000 # -- (map) Security context to apply to the container -securityContext: {} +securityContext: + {} # capabilities: # drop: # - ALL @@ -149,20 +152,20 @@ affinity: podAntiAffinity: # -- (map) Option for scheduling to be required or preferred. preferredDuringSchedulingIgnoredDuringExecution: - # -- (int) Weight value for preferred scheduling. - - weight: 100 - podAffinityTerm: - labelSelector: - matchExpressions: - # -- (list) Label key for match expression. - - key: app - # -- (string) Operation type for the match expression. - operator: In - # -- (list) Value for the match expression key. - values: - - frontend-framework - # -- (string) Value for topology key label. - topologyKey: "kubernetes.io/hostname" + # -- (int) Weight value for preferred scheduling. + - weight: 100 + podAffinityTerm: + labelSelector: + matchExpressions: + # -- (list) Label key for match expression. + - key: app + # -- (string) Operation type for the match expression. + operator: In + # -- (list) Value for the match expression key. + values: + - frontend-framework + # -- (string) Value for topology key label. + topologyKey: "kubernetes.io/hostname" # -- (bool) Automount the default service account token automountServiceAccountToken: false diff --git a/helm/gen3/Chart.yaml b/helm/gen3/Chart.yaml index 0534061a..4b15d822 100644 --- a/helm/gen3/Chart.yaml +++ b/helm/gen3/Chart.yaml @@ -4,116 +4,120 @@ description: Helm chart to deploy Gen3 Data Commons # Dependencies dependencies: -- name: ambassador - version: 0.1.12 - repository: "file://../ambassador" - condition: ambassador.enabled -- name: arborist - version: 0.1.12 - repository: "file://../arborist" - condition: arborist.enabled -- name: argo-wrapper - version: 0.1.8 - repository: "file://../argo-wrapper" - condition: argo-wrapper.enabled -- name: audit - version: 0.1.13 - repository: "file://../audit" - condition: audit.enabled -- name: aws-es-proxy - version: 0.1.10 - repository: "file://../aws-es-proxy" - condition: aws-es-proxy.enabled -- name: common - version: 0.1.14 - repository: file://../common -- name: etl - version: 0.1.1 - repository: file://../etl - condition: etl.enabled -- name: frontend-framework - version: 0.1.3 - repository: "file://../frontend-framework" - condition: frontend-framework.enabled -- name: fence - version: 0.1.23 - repository: "file://../fence" - condition: fence.enabled -- name: guppy - version: 0.1.13 - repository: "file://../guppy" - condition: guppy.enabled -- name: hatchery - version: 0.1.10 - repository: "file://../hatchery" - condition: hatchery.enabled -- name: indexd - version: 0.1.15 - repository: "file://../indexd" - condition: indexd.enabled -- name: manifestservice - version: 0.1.15 - repository: "file://../manifestservice" - condition: manifestservice.enabled -- name: metadata - version: 0.1.13 - repository: "file://../metadata" - condition: metadata.enabled -- name: peregrine - version: 0.1.14 - repository: "file://../peregrine" - condition: peregrine.enabled -- name: pidgin - version: 0.1.11 - repository: "file://../pidgin" - condition: pidgin.enabled -- name: portal - version: 0.1.17 - repository: "file://../portal" - condition: portal.enabled -- name: requestor - version: 0.1.12 - repository: "file://../requestor" - condition: requestor.enabled -- name: revproxy - version: 0.1.17 - repository: "file://../revproxy" - condition: revproxy.enabled -- name: sheepdog - version: 0.1.15 - repository: "file://../sheepdog" - condition: sheepdog.enabled -- name: ssjdispatcher - version: 0.1.11 - repository: "file://../ssjdispatcher" - condition: ssjdispatcher.enabled -- name: sower - version: 0.1.13 - condition: sower.enabled - repository: "file://../sower" -- name: wts - version: 0.1.14 - repository: "file://../wts" - condition: wts.enabled + - name: ambassador + version: 0.1.12 + repository: "file://../ambassador" + condition: ambassador.enabled + - name: arborist + version: 0.1.12 + repository: "file://../arborist" + condition: arborist.enabled + - name: argo-wrapper + version: 0.1.8 + repository: "file://../argo-wrapper" + condition: argo-wrapper.enabled + - name: audit + version: 0.1.13 + repository: "file://../audit" + condition: audit.enabled + - name: aws-es-proxy + version: 0.1.10 + repository: "file://../aws-es-proxy" + condition: aws-es-proxy.enabled + - name: common + version: 0.1.14 + repository: file://../common + - name: etl + version: 0.1.1 + repository: file://../etl + condition: etl.enabled + - name: frontend-framework + version: 0.1.3 + repository: "file://../frontend-framework" + condition: frontend-framework.enabled + - name: fence + version: 0.1.23 + repository: "file://../fence" + condition: fence.enabled + - name: guppy + version: 0.1.13 + repository: "file://../guppy" + condition: guppy.enabled + - name: hatchery + version: 0.1.10 + repository: "file://../hatchery" + condition: hatchery.enabled + - name: indexd + version: 0.1.15 + repository: "file://../indexd" + condition: indexd.enabled + - name: manifestservice + version: 0.1.15 + repository: "file://../manifestservice" + condition: manifestservice.enabled + - name: metadata + version: 0.1.13 + repository: "file://../metadata" + condition: metadata.enabled + - name: peregrine + version: 0.1.14 + repository: "file://../peregrine" + condition: peregrine.enabled + - name: pidgin + version: 0.1.11 + repository: "file://../pidgin" + condition: pidgin.enabled + - name: portal + version: 0.1.17 + repository: "file://../portal" + condition: portal.enabled + - name: requestor + version: 0.1.12 + repository: "file://../requestor" + condition: requestor.enabled + - name: revproxy + version: 0.1.17 + repository: "file://../revproxy" + condition: revproxy.enabled + - name: sheepdog + version: 0.1.15 + repository: "file://../sheepdog" + condition: sheepdog.enabled + - name: ssjdispatcher + version: 0.1.11 + repository: "file://../ssjdispatcher" + condition: ssjdispatcher.enabled + - name: sower + version: 0.1.13 + condition: sower.enabled + repository: "file://../sower" + - name: wts + version: 0.1.14 + repository: "file://../wts" + condition: wts.enabled + - name: gen3-network-policies + version: 0.1.1 + repository: "file://../../wip/gen3-network-policies" + condition: global.netPolicy.enabled -- name: elasticsearch - version: 7.10.2 - repository: "https://helm.elastic.co" - condition: global.dev -- name: postgresql - version: 11.9.13 - repository: "https://charts.bitnami.com/bitnami" - condition: global.dev + - name: elasticsearch + version: 7.10.2 + repository: "https://helm.elastic.co" + condition: global.dev + - name: postgresql + version: 11.9.13 + repository: "https://charts.bitnami.com/bitnami" + condition: global.dev -# (optional) NeuVector Kubernetes Security Policy templates to protect Gen3 -# NeuVector must be installed separately. -# Reference: https://open-docs.neuvector.com/basics/overview -# Reference: https://github.com/neuvector/neuvector-helm -# For more information, please use the Gen3 community Slack. -- name: neuvector - version: "0.1.0" - repository: "file://../neuvector" - condition: neuvector.enabled + # (optional) NeuVector Kubernetes Security Policy templates to protect Gen3 + # NeuVector must be installed separately. + # Reference: https://open-docs.neuvector.com/basics/overview + # Reference: https://github.com/neuvector/neuvector-helm + # For more information, please use the Gen3 community Slack. + - name: neuvector + version: "0.1.0" + repository: "file://../neuvector" + condition: neuvector.enabled # A chart can be either an 'application' or a 'library' chart. # @@ -128,7 +132,7 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.42 +version: 0.1.43 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to diff --git a/helm/gen3/README.md b/helm/gen3/README.md index ed27d3c7..f8556fa3 100644 --- a/helm/gen3/README.md +++ b/helm/gen3/README.md @@ -1,6 +1,6 @@ # gen3 -![Version: 0.1.42](https://img.shields.io/badge/Version-0.1.42-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) +![Version: 0.1.43](https://img.shields.io/badge/Version-0.1.43-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) Helm chart to deploy Gen3 Data Commons @@ -18,6 +18,7 @@ Helm chart to deploy Gen3 Data Commons | Repository | Name | Version | |------------|------|---------| +| file://../../wip/gen3-network-policies | gen3-network-policies | 0.1.1 | | file://../ambassador | ambassador | 0.1.12 | | file://../arborist | arborist | 0.1.12 | | file://../argo-wrapper | argo-wrapper | 0.1.8 | @@ -102,7 +103,9 @@ Helm chart to deploy Gen3 Data Commons | global.frontendRoot | string | `"portal"` | Which app will be served on /. Needs be set to portal for portal, or "gen3ff" for frontendframework. | | global.hostname | string | `"localhost"` | Hostname for the deployment. | | global.manifestGlobalExtraValues | map | `{}` | If you would like to add any extra values to the manifest-global configmap. | -| global.netPolicy | bool | `true` | Whether network policies are enabled. | +| global.netPolicy | bool | `{"dbSubnet":"","enabled":false}` | Global flags to control and manage network policies for a Gen3 installation | +| global.netPolicy.dbSubnet | array | `""` | A CIDR range representing a database subnet, that services with a database need access to | +| global.netPolicy.enabled | bool | `false` | Whether network policies are enabled | | global.portalApp | string | `"gitops"` | Portal application name. | | global.postgres.dbCreate | bool | `true` | Whether the database create job should run. | | global.postgres.master.host | string | `nil` | global postgres master host | @@ -178,3 +181,5 @@ Helm chart to deploy Gen3 Data Commons | ssjdispatcher.enabled | bool | `false` | Whether to deploy the ssjdispatcher subchart. | | wts.enabled | bool | `true` | Whether to deploy the wts subchart. | +---------------------------------------------- +Autogenerated from chart metadata using [helm-docs v1.13.1](https://github.com/norwoodj/helm-docs/releases/v1.13.1) diff --git a/helm/gen3/values.yaml b/helm/gen3/values.yaml index d644eaa4..078dff1d 100644 --- a/helm/gen3/values.yaml +++ b/helm/gen3/values.yaml @@ -60,8 +60,13 @@ global: tierAccessLevel: libre # -- (int) Only relevant if tireAccessLevel is set to "regular". Summary charts below this limit will not appear for aggregated data. tierAccessLimit: "1000" - # -- (bool) Whether network policies are enabled. - netPolicy: true + # -- (bool) Global flags to control and manage network policies for a Gen3 installation + netPolicy: + # -- (bool) Whether network policies are enabled + enabled: false + + # -- (array) A CIDR range representing a database subnet, that services with a database need access to + dbSubnet: "" # -- (int) Number of dispatcher jobs. dispatcherJobNum: "10" # -- (map) If you would like to add any extra values to the manifest-global configmap. @@ -93,7 +98,6 @@ audit: # -- (bool) Whether to deploy the audit subchart. enabled: true - aws-es-proxy: # -- (bool) Whether to deploy the aws-es-proxy subchart. enabled: false @@ -155,7 +159,7 @@ hatchery: hatchery: sidecarContainer: # -- (string) The maximum amount of CPU the sidecar container can use - cpu-limit: '0.1' + cpu-limit: "0.1" # -- (string) The maximum amount of memory the sidecar container can use memory-limit: 256Mi # -- (string) The sidecar image. @@ -168,21 +172,20 @@ hatchery: args: [] # -- (list) Commands to run for the sidecar container. command: - - "/bin/bash" - - "./sidecar.sh" + - "/bin/bash" + - "./sidecar.sh" lifecycle-pre-stop: - - su - - "-c" - - echo test - - "-s" - - "/bin/sh" - - root + - su + - "-c" + - echo test + - "-s" + - "/bin/sh" + - root containers: - - - # -- (int) port to proxy traffic to in docker contaniner + - # -- (int) port to proxy traffic to in docker contaniner target-port: 8888 # -- (string) cpu limit of workspace container - cpu-limit: '1.0' + cpu-limit: "1.0" # -- (string) memory limit of workspace container memory-limit: 2Gi # -- (string) name of workspace @@ -193,35 +196,33 @@ hatchery: env: FRAME_ANCESTORS: https://{{ .Values.global.hostname }} args: - - "--NotebookApp.base_url=/lw-workspace/proxy/" - - "--NotebookApp.default_url=/lab" - - "--NotebookApp.password=''" - - "--NotebookApp.token=''" - - "--NotebookApp.shutdown_no_activity_timeout=5400" - - "--NotebookApp.quit_button=False" + - "--NotebookApp.base_url=/lw-workspace/proxy/" + - "--NotebookApp.default_url=/lab" + - "--NotebookApp.password=''" + - "--NotebookApp.token=''" + - "--NotebookApp.shutdown_no_activity_timeout=5400" + - "--NotebookApp.quit_button=False" command: - - start-notebook.sh + - start-notebook.sh path-rewrite: "/lw-workspace/proxy/" - use-tls: 'false' + use-tls: "false" ready-probe: "/lw-workspace/proxy/" lifecycle-post-start: - - "/bin/sh" - - "-c" - - export IAM=`whoami`; rm -rf /home/$IAM/pd/dockerHome; rm -rf /home/$IAM/pd/lost+found; - ln -s /data /home/$IAM/pd/; true + - "/bin/sh" + - "-c" + - export IAM=`whoami`; rm -rf /home/$IAM/pd/dockerHome; rm -rf /home/$IAM/pd/lost+found; + ln -s /data /home/$IAM/pd/; true user-uid: 1000 fs-gid: 100 user-volume-location: "/home/jovyan/pd" gen3-volume-location: "/home/jovyan/.gen3" - indexd: # -- (bool) Whether to deploy the indexd subchart. enabled: true # -- (string) the default prefix for indexd records defaultPrefix: "PREFIX/" - manifestservice: # -- (bool) Whether to deploy the manifest service subchart. enabled: true @@ -242,7 +243,6 @@ portal: # -- (bool) Whether to deploy the portal subchart. enabled: true - requestor: # -- (bool) Whether to deploy the requestor subchart. enabled: false @@ -255,7 +255,8 @@ revproxy: # -- (bool) Whether to create the custom revproxy ingress enabled: false # -- (map) Annotations to add to the ingress. - annotations: {} + annotations: + {} # kubernetes.io/ingress.class: nginx # kubernetes.io/tls-acme: "true" # -- (list) Where to route the traffic. diff --git a/helm/guppy/Chart.yaml b/helm/guppy/Chart.yaml index dd539db1..ffa25912 100644 --- a/helm/guppy/Chart.yaml +++ b/helm/guppy/Chart.yaml @@ -15,7 +15,7 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.13 +version: 0.1.14 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to diff --git a/helm/guppy/README.md b/helm/guppy/README.md index a6fb665e..c8dfca42 100644 --- a/helm/guppy/README.md +++ b/helm/guppy/README.md @@ -1,6 +1,6 @@ # guppy -![Version: 0.1.13](https://img.shields.io/badge/Version-0.1.13-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) +![Version: 0.1.14](https://img.shields.io/badge/Version-0.1.14-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) A Helm chart for gen3 Guppy Service @@ -49,7 +49,7 @@ A Helm chart for gen3 Guppy Service | global.kubeBucket | string | `"kube-gen3"` | S3 bucket name for Kubernetes manifest files. | | global.logsBucket | string | `"logs-gen3"` | S3 bucket name for log files. | | global.minAvialable | int | `1` | The minimum amount of pods that are available at all times if the PDB is deployed. | -| global.netPolicy | bool | `true` | Whether network policies are enabled. | +| global.netPolicy | bool | `{"enabled":true}` | Whether network policies are enabled. | | global.pdb | bool | `false` | If the service will be deployed with a Pod Disruption Budget. Note- you need to have more than 2 replicas for the pdb to be deployed. | | global.portalApp | string | `"gitops"` | Portal application name. | | global.postgres.dbCreate | bool | `true` | Whether the database should be created. | @@ -93,3 +93,5 @@ A Helm chart for gen3 Guppy Service | volumeMounts | list | `[{"mountPath":"/guppy/guppy_config.json","name":"guppy-config","readOnly":true,"subPath":"guppy_config.json"}]` | Volumes to mount to the container. | | volumes | list | `[{"configMap":{"items":[{"key":"guppy_config.json","path":"guppy_config.json"}],"name":"manifest-guppy"},"name":"guppy-config"}]` | Volumes to attach to the pod. | +---------------------------------------------- +Autogenerated from chart metadata using [helm-docs v1.13.1](https://github.com/norwoodj/helm-docs/releases/v1.13.1) diff --git a/helm/guppy/values.yaml b/helm/guppy/values.yaml index 1f2ec669..5b01a36c 100644 --- a/helm/guppy/values.yaml +++ b/helm/guppy/values.yaml @@ -2,7 +2,6 @@ # This is a YAML-formatted file. # Declare variables to be passed into your templates. - # Global configuration global: # -- (map) AWS configuration @@ -52,7 +51,8 @@ global: # -- (int) Only relevant if tireAccessLevel is set to "regular". Summary charts below this limit will not appear for aggregated data. tierAccessLimit: "1000" # -- (bool) Whether network policies are enabled. - netPolicy: true + netPolicy: + enabled: true # -- (int) Number of dispatcher jobs. dispatcherJobNum: "10" # -- (bool) If the service will be deployed with a Pod Disruption Budget. Note- you need to have more than 2 replicas for the pdb to be deployed. @@ -106,20 +106,20 @@ affinity: podAntiAffinity: # -- (map) Option for scheduling to be required or preferred. preferredDuringSchedulingIgnoredDuringExecution: - # -- (int) Weight value for preferred scheduling. - - weight: 100 - podAffinityTerm: - labelSelector: - matchExpressions: - # -- (list) Label key for match expression. - - key: app - # -- (string) Operation type for the match expression. - operator: In - # -- (list) Value for the match expression key. - values: - - guppy - # -- (string) Value for topology key label. - topologyKey: "kubernetes.io/hostname" + # -- (int) Weight value for preferred scheduling. + - weight: 100 + podAffinityTerm: + labelSelector: + matchExpressions: + # -- (list) Label key for match expression. + - key: app + # -- (string) Operation type for the match expression. + operator: In + # -- (list) Value for the match expression key. + values: + - guppy + # -- (string) Value for topology key label. + topologyKey: "kubernetes.io/hostname" # -- (list) Volumes to attach to the pod. volumes: @@ -142,7 +142,6 @@ image: # -- (string) Overrides the image tag whose default is the chart appVersion. tag: "" - # Environment Variables # -- (string) Elasticsearch endpoint. esEndpoint: "gen3-elasticsearch-master:9200" @@ -171,7 +170,6 @@ resources: # -- (string) The maximum amount of memory the container can use memory: 2Gi - # -- (map) Kubernetes service information. service: # -- (string) Type of service. Valid values are "ClusterIP", "NodePort", "LoadBalancer", "ExternalName". @@ -186,10 +184,10 @@ service: # Configmap # -- (list) Elasticsearch index configurations indices: -- index: dev_case - type: case -- index: dev_file - type: file + - index: dev_case + type: case + - index: dev_file + type: file # -- (string) The Elasticsearch configuration index configIndex: dev_case-array-config # -- (string) The field used for access control and authorization filters diff --git a/helm/hatchery/Chart.yaml b/helm/hatchery/Chart.yaml index 126d1bc7..1b4f5ab5 100644 --- a/helm/hatchery/Chart.yaml +++ b/helm/hatchery/Chart.yaml @@ -15,7 +15,7 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.10 +version: 0.1.11 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to diff --git a/helm/hatchery/README.md b/helm/hatchery/README.md index 74059ee6..8bdf0435 100644 --- a/helm/hatchery/README.md +++ b/helm/hatchery/README.md @@ -1,6 +1,6 @@ # hatchery -![Version: 0.1.10](https://img.shields.io/badge/Version-0.1.10-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) +![Version: 0.1.11](https://img.shields.io/badge/Version-0.1.11-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) A Helm chart for gen3 Hatchery @@ -36,7 +36,7 @@ A Helm chart for gen3 Hatchery | global.kubeBucket | string | `"kube-gen3"` | S3 bucket name for Kubernetes manifest files. | | global.logsBucket | string | `"logs-gen3"` | S3 bucket name for log files. | | global.minAvialable | int | `1` | The minimum amount of pods that are available at all times if the PDB is deployed. | -| global.netPolicy | bool | `true` | Whether network policies are enabled. | +| global.netPolicy | bool | `{"enabled":true}` | Whether network policies are enabled. | | global.pdb | bool | `false` | If the service will be deployed with a Pod Disruption Budget. Note- you need to have more than 2 replicas for the pdb to be deployed. | | global.portalApp | string | `"gitops"` | Portal application name. | | global.postgres.dbCreate | bool | `true` | Whether the database should be created. | @@ -50,6 +50,7 @@ A Helm chart for gen3 Hatchery | global.revproxyArn | string | `"arn:aws:acm:us-east-1:123456:certificate"` | ARN of the reverse proxy certificate. | | global.tierAccessLevel | string | `"libre"` | Access level for tiers. acceptable values for `tier_access_level` are: `libre`, `regular` and `private`. If omitted, by default common will be treated as `private` | | hatchery | map | `{"containers":[{"args":["--NotebookApp.base_url=/lw-workspace/proxy/","--NotebookApp.default_url=/lab","--NotebookApp.password=''","--NotebookApp.token=''","--NotebookApp.shutdown_no_activity_timeout=5400","--NotebookApp.quit_button=False"],"command":["start-notebook.sh"],"cpu-limit":"1.0","env":{"FRAME_ANCESTORS":"https://{{ .Values.global.hostname }}"},"fs-gid":100,"gen3-volume-location":"/home/jovyan/.gen3","image":"quay.io/cdis/heal-notebooks:combined_tutorials__latest","lifecycle-post-start":["/bin/sh","-c","export IAM=`whoami`; rm -rf /home/$IAM/pd/dockerHome; rm -rf /home/$IAM/pd/lost+found; ln -s /data /home/$IAM/pd/; true"],"memory-limit":"2Gi","name":"(Tutorials) Example Analysis Jupyter Lab Notebooks","path-rewrite":"/lw-workspace/proxy/","ready-probe":"/lw-workspace/proxy/","target-port":8888,"use-tls":"false","user-uid":1000,"user-volume-location":"/home/jovyan/pd"}],"sidecarContainer":{"args":[],"command":["/bin/bash","./sidecar.sh"],"cpu-limit":"0.1","env":{"HOSTNAME":"{{ .Values.global.hostname }}","NAMESPACE":"{{ .Release.Namespace }}"},"image":"quay.io/cdis/ecs-ws-sidecar:master","lifecycle-pre-stop":["su","-c","echo test","-s","/bin/sh","root"],"memory-limit":"256Mi"}}` | Hatchery sidcar container configuration. | +| hatchery.containers | list | `[{"args":["--NotebookApp.base_url=/lw-workspace/proxy/","--NotebookApp.default_url=/lab","--NotebookApp.password=''","--NotebookApp.token=''","--NotebookApp.shutdown_no_activity_timeout=5400","--NotebookApp.quit_button=False"],"command":["start-notebook.sh"],"cpu-limit":"1.0","env":{"FRAME_ANCESTORS":"https://{{ .Values.global.hostname }}"},"fs-gid":100,"gen3-volume-location":"/home/jovyan/.gen3","image":"quay.io/cdis/heal-notebooks:combined_tutorials__latest","lifecycle-post-start":["/bin/sh","-c","export IAM=`whoami`; rm -rf /home/$IAM/pd/dockerHome; rm -rf /home/$IAM/pd/lost+found; ln -s /data /home/$IAM/pd/; true"],"memory-limit":"2Gi","name":"(Tutorials) Example Analysis Jupyter Lab Notebooks","path-rewrite":"/lw-workspace/proxy/","ready-probe":"/lw-workspace/proxy/","target-port":8888,"use-tls":"false","user-uid":1000,"user-volume-location":"/home/jovyan/pd"}]` | Notebook configuration. | | hatchery.sidecarContainer.args | list | `[]` | Arguments to pass to the sidecare container. | | hatchery.sidecarContainer.command | list | `["/bin/bash","./sidecar.sh"]` | Commands to run for the sidecar container. | | hatchery.sidecarContainer.cpu-limit | string | `"0.1"` | The maximum amount of CPU the sidecar container can use | @@ -83,3 +84,5 @@ A Helm chart for gen3 Hatchery | volumeMounts | list | `[{"mountPath":"/hatchery.json","name":"hatchery-config","readOnly":true,"subPath":"json"}]` | Volumes to mount to the container. | | volumes | list | `[{"configMap":{"name":"manifest-hatchery"},"name":"hatchery-config"}]` | Volumes to attach to the container. | +---------------------------------------------- +Autogenerated from chart metadata using [helm-docs v1.13.1](https://github.com/norwoodj/helm-docs/releases/v1.13.1) diff --git a/helm/hatchery/values.yaml b/helm/hatchery/values.yaml index b1cd4c10..df31fa5a 100644 --- a/helm/hatchery/values.yaml +++ b/helm/hatchery/values.yaml @@ -2,7 +2,6 @@ # This is a YAML-formatted file. # Declare variables to be passed into your templates. - # Global configuration global: # -- (map) AWS configuration @@ -50,7 +49,8 @@ global: # -- (string) Access level for tiers. acceptable values for `tier_access_level` are: `libre`, `regular` and `private`. If omitted, by default common will be treated as `private` tierAccessLevel: libre # -- (bool) Whether network policies are enabled. - netPolicy: true + netPolicy: + enabled: true # -- (int) Number of dispatcher jobs. dispatcherJobNum: "10" # -- (bool) If the service will be deployed with a Pod Disruption Budget. Note- you need to have more than 2 replicas for the pdb to be deployed. @@ -127,31 +127,31 @@ affinity: {} # -- (list) Environment variables to pass to the container env: -- name: HTTP_PORT - value: "8000" -- name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace + - name: HTTP_PORT + value: "8000" + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace # -- (list) Volumes to attach to the container. volumes: -- name: hatchery-config - configMap: - name: manifest-hatchery + - name: hatchery-config + configMap: + name: manifest-hatchery # -- (list) Volumes to mount to the container. volumeMounts: -- name: hatchery-config - readOnly: true - mountPath: /hatchery.json - subPath: json + - name: hatchery-config + readOnly: true + mountPath: /hatchery.json + subPath: json # -- (map) Hatchery sidcar container configuration. hatchery: sidecarContainer: # -- (string) The maximum amount of CPU the sidecar container can use - cpu-limit: '0.1' + cpu-limit: "0.1" # -- (string) The maximum amount of memory the sidecar container can use memory-limit: 256Mi # -- (string) The sidecar image. @@ -164,43 +164,43 @@ hatchery: args: [] # -- (list) Commands to run for the sidecar container. command: - - "/bin/bash" - - "./sidecar.sh" + - "/bin/bash" + - "./sidecar.sh" # -- (list) Commands that are run before the container is stopped. lifecycle-pre-stop: - - su - - "-c" - - echo test - - "-s" - - "/bin/sh" - - root - -# -- (list) Notebook configuration. + - su + - "-c" + - echo test + - "-s" + - "/bin/sh" + - root + + # -- (list) Notebook configuration. containers: - target-port: 8888 - cpu-limit: '1.0' + cpu-limit: "1.0" memory-limit: 2Gi name: "(Tutorials) Example Analysis Jupyter Lab Notebooks" image: quay.io/cdis/heal-notebooks:combined_tutorials__latest env: FRAME_ANCESTORS: https://{{ .Values.global.hostname }} args: - - "--NotebookApp.base_url=/lw-workspace/proxy/" - - "--NotebookApp.default_url=/lab" - - "--NotebookApp.password=''" - - "--NotebookApp.token=''" - - "--NotebookApp.shutdown_no_activity_timeout=5400" - - "--NotebookApp.quit_button=False" + - "--NotebookApp.base_url=/lw-workspace/proxy/" + - "--NotebookApp.default_url=/lab" + - "--NotebookApp.password=''" + - "--NotebookApp.token=''" + - "--NotebookApp.shutdown_no_activity_timeout=5400" + - "--NotebookApp.quit_button=False" command: - - start-notebook.sh + - start-notebook.sh path-rewrite: "/lw-workspace/proxy/" - use-tls: 'false' + use-tls: "false" ready-probe: "/lw-workspace/proxy/" lifecycle-post-start: - - "/bin/sh" - - "-c" - - export IAM=`whoami`; rm -rf /home/$IAM/pd/dockerHome; rm -rf /home/$IAM/pd/lost+found; - ln -s /data /home/$IAM/pd/; true + - "/bin/sh" + - "-c" + - export IAM=`whoami`; rm -rf /home/$IAM/pd/dockerHome; rm -rf /home/$IAM/pd/lost+found; + ln -s /data /home/$IAM/pd/; true user-uid: 1000 fs-gid: 100 user-volume-location: "/home/jovyan/pd" diff --git a/helm/indexd/Chart.yaml b/helm/indexd/Chart.yaml index b5879156..94144dc0 100644 --- a/helm/indexd/Chart.yaml +++ b/helm/indexd/Chart.yaml @@ -15,7 +15,7 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.15 +version: 0.1.16 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to diff --git a/helm/indexd/README.md b/helm/indexd/README.md index 17430159..cd0b21ec 100644 --- a/helm/indexd/README.md +++ b/helm/indexd/README.md @@ -1,6 +1,6 @@ # indexd -![Version: 0.1.15](https://img.shields.io/badge/Version-0.1.15-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) +![Version: 0.1.16](https://img.shields.io/badge/Version-0.1.16-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) A Helm chart for gen3 indexd @@ -43,7 +43,7 @@ A Helm chart for gen3 indexd | global.kubeBucket | string | `"kube-gen3"` | S3 bucket name for Kubernetes manifest files. | | global.logsBucket | string | `"logs-gen3"` | S3 bucket name for log files. | | global.minAvialable | int | `1` | The minimum amount of pods that are available at all times if the PDB is deployed. | -| global.netPolicy | bool | `true` | Whether network policies are enabled. | +| global.netPolicy | bool | `{"enabled":true}` | Whether network policies are enabled. | | global.pdb | bool | `false` | If the service will be deployed with a Pod Disruption Budget. Note- you need to have more than 2 replicas for the pdb to be deployed. | | global.portalApp | string | `"gitops"` | Portal application name. | | global.postgres.dbCreate | bool | `true` | Whether the database should be created. | @@ -64,6 +64,9 @@ A Helm chart for gen3 indexd | imagePullSecrets | list | `[]` | Docker image pull secrets. | | metricsEnabled | bool | `false` | Whether Metrics are enabled. | | nameOverride | string | `""` | Override the name of the chart. | +| netPolicy | map | `{"egressApps":["fence","presigned-url-fence","fenceshib","peregrine","sheepdog","ssjdispatcherjob","metadata","mariner","mariner-engine"],"ingressApps":["fence","presigned-url-fence","fenceshib","peregrine","sheepdog","ssjdispatcherjob","metadata","mariner","mariner-engine"]}` | Configuration for network policies created by this chart. Only relevant if "global.netPolicy.enabled" is set to true | +| netPolicy.egressApps | array | `["fence","presigned-url-fence","fenceshib","peregrine","sheepdog","ssjdispatcherjob","metadata","mariner","mariner-engine"]` | List of apps that this app requires egress to | +| netPolicy.ingressApps | array | `["fence","presigned-url-fence","fenceshib","peregrine","sheepdog","ssjdispatcherjob","metadata","mariner","mariner-engine"]` | List of app labels that require ingress to this service | | nodeSelector | map | `{}` | Node Selector for the pods | | partOf | string | `"S3-GS"` | Label to help organize pods and their use. Any value is valid, but use "_" or "-" to divide words. | | podAnnotations | map | `{}` | Annotations to add to the pod | @@ -104,3 +107,5 @@ A Helm chart for gen3 indexd | volumeMounts | list | `[{"mountPath":"/var/www/indexd/local_settings.py","name":"config-volume","readOnly":true,"subPath":"local_settings.py"}]` | Volumes to mount to the container. | | volumes | list | `[{"configMap":{"name":"indexd-uwsgi"},"name":"uwsgi-config"},{"name":"config-volume","secret":{"secretName":"indexd-settings"}}]` | Volumes to attach to the pod | +---------------------------------------------- +Autogenerated from chart metadata using [helm-docs v1.13.1](https://github.com/norwoodj/helm-docs/releases/v1.13.1) diff --git a/helm/indexd/templates/netpolicy.yaml b/helm/indexd/templates/netpolicy.yaml new file mode 100644 index 00000000..93949e3a --- /dev/null +++ b/helm/indexd/templates/netpolicy.yaml @@ -0,0 +1,9 @@ +{{ include "common.db_netpolicy" . }} + +--- + +{{ include "common.ingress_netpolicy" . }} + +--- + +{{ include "common.egress_netpolicy" . }} \ No newline at end of file diff --git a/helm/indexd/values.yaml b/helm/indexd/values.yaml index 97b71d49..3cb6b905 100644 --- a/helm/indexd/values.yaml +++ b/helm/indexd/values.yaml @@ -2,7 +2,6 @@ # This is a YAML-formatted file. # Declare variables to be passed into your templates. - # Global configuration global: # -- (map) AWS configuration @@ -52,7 +51,8 @@ global: # -- (int) Only relevant if tireAccessLevel is set to "regular". Summary charts below this limit will not appear for aggregated data. tierAccessLimit: "1000" # -- (bool) Whether network policies are enabled. - netPolicy: true + netPolicy: + enabled: true # -- (int) Number of dispatcher jobs. dispatcherJobNum: "10" # -- (bool) If the service will be deployed with a Pod Disruption Budget. Note- you need to have more than 2 replicas for the pdb to be deployed. @@ -69,6 +69,32 @@ global: # -- (bool) Whether Metrics are enabled. metricsEnabled: false +# -- (map) Configuration for network policies created by this chart. Only relevant if "global.netPolicy.enabled" is set to true +netPolicy: + # -- (array) List of app labels that require ingress to this service + ingressApps: + - fence + - presigned-url-fence + - fenceshib + - peregrine + - sheepdog + - ssjdispatcherjob + - metadata + - mariner + - mariner-engine + + # -- (array) List of apps that this app requires egress to + egressApps: + - fence + - presigned-url-fence + - fenceshib + - peregrine + - sheepdog + - ssjdispatcherjob + - metadata + - mariner + - mariner-engine + # -- (map) External Secrets settings. externalSecrets: # -- (string) Will create the Helm "indexd-service-creds" secret even if Secrets Manager is enabled. This is helpful if you are wanting to use External Secrets for some, but not all secrets. @@ -150,11 +176,13 @@ serviceAccount: podAnnotations: {} # -- (map) Security context for the pod -podSecurityContext: {} +podSecurityContext: + {} # fsGroup: 2000 # -- (map) Security context for the containers in the pod -securityContext: {} +securityContext: + {} # capabilities: # drop: # - ALL @@ -206,19 +234,19 @@ affinity: {} # -- (list) Volumes to attach to the pod volumes: -- name: uwsgi-config - configMap: - name: indexd-uwsgi -- name: config-volume - secret: - secretName: "indexd-settings" + - name: uwsgi-config + configMap: + name: indexd-uwsgi + - name: config-volume + secret: + secretName: "indexd-settings" # -- (list) Volumes to mount to the container. volumeMounts: -- name: "config-volume" - readOnly: true - mountPath: "/var/www/indexd/local_settings.py" - subPath: "local_settings.py" + - name: "config-volume" + readOnly: true + mountPath: "/var/www/indexd/local_settings.py" + subPath: "local_settings.py" # -- (list) Environment variables to pass to the container env: diff --git a/helm/manifestservice/Chart.yaml b/helm/manifestservice/Chart.yaml index 66288065..debd8e30 100644 --- a/helm/manifestservice/Chart.yaml +++ b/helm/manifestservice/Chart.yaml @@ -15,7 +15,7 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.15 +version: 0.1.16 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to diff --git a/helm/manifestservice/README.md b/helm/manifestservice/README.md index 03d6d3c0..417150bb 100644 --- a/helm/manifestservice/README.md +++ b/helm/manifestservice/README.md @@ -1,6 +1,6 @@ # manifestservice -![Version: 0.1.15](https://img.shields.io/badge/Version-0.1.15-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) +![Version: 0.1.16](https://img.shields.io/badge/Version-0.1.16-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) A Helm chart for Kubernetes @@ -82,3 +82,5 @@ A Helm chart for Kubernetes | volumeMounts | list | `[{"mountPath":"/var/gen3/config/","name":"config-volume","readOnly":true}]` | Volumes to mount to the container. | | volumes | list | `[{"name":"config-volume","secret":{"secretName":"manifestservice-g3auto"}}]` | Volumes to attach to the container. | +---------------------------------------------- +Autogenerated from chart metadata using [helm-docs v1.13.1](https://github.com/norwoodj/helm-docs/releases/v1.13.1) diff --git a/helm/metadata/Chart.yaml b/helm/metadata/Chart.yaml index 6b4ce861..4b5070b2 100644 --- a/helm/metadata/Chart.yaml +++ b/helm/metadata/Chart.yaml @@ -15,7 +15,7 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.13 +version: 0.1.14 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to diff --git a/helm/metadata/README.md b/helm/metadata/README.md index c81a3f00..a50f37d0 100644 --- a/helm/metadata/README.md +++ b/helm/metadata/README.md @@ -1,6 +1,6 @@ # metadata -![Version: 0.1.13](https://img.shields.io/badge/Version-0.1.13-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) +![Version: 0.1.14](https://img.shields.io/badge/Version-0.1.14-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) A Helm chart for gen3 Metadata Service @@ -62,7 +62,7 @@ A Helm chart for gen3 Metadata Service | global.kubeBucket | string | `"kube-gen3"` | S3 bucket name for Kubernetes manifest files. | | global.logsBucket | string | `"logs-gen3"` | S3 bucket name for log files. | | global.minAvialable | int | `1` | The minimum amount of pods that are available at all times if the PDB is deployed. | -| global.netPolicy | bool | `true` | Whether network policies are enabled. | +| global.netPolicy | bool | `{"enabled":true}` | Whether network policies are enabled. | | global.pdb | bool | `false` | If the service will be deployed with a Pod Disruption Budget. Note- you need to have more than 2 replicas for the pdb to be deployed. | | global.portalApp | string | `"gitops"` | Portal application name. | | global.postgres.dbCreate | bool | `true` | Whether the database should be created. | @@ -121,3 +121,5 @@ A Helm chart for gen3 Metadata Service | useAggMds | bool | `"True"` | Set to true to aggregate metadata from multiple other Metadata Service instances. | | volumeMounts | list | `[{"mountPath":"/src/.env","name":"config-volume-g3auto","readOnly":true,"subPath":"metadata.env"},{"mountPath":"/aggregate_config.json","name":"config-volume","readOnly":true,"subPath":"aggregate_config.json"},{"mountPath":"/metadata.json","name":"config-manifest","readOnly":true,"subPath":"json"}]` | Volumes to mount to the container. | +---------------------------------------------- +Autogenerated from chart metadata using [helm-docs v1.13.1](https://github.com/norwoodj/helm-docs/releases/v1.13.1) diff --git a/helm/metadata/templates/netpolicy.yaml b/helm/metadata/templates/netpolicy.yaml new file mode 100644 index 00000000..70a5c3b5 --- /dev/null +++ b/helm/metadata/templates/netpolicy.yaml @@ -0,0 +1 @@ +{{ include "common.db_netpolicy" . }} \ No newline at end of file diff --git a/helm/metadata/values.yaml b/helm/metadata/values.yaml index 97d13e7c..5f8866e2 100644 --- a/helm/metadata/values.yaml +++ b/helm/metadata/values.yaml @@ -2,7 +2,6 @@ # This is a YAML-formatted file. # Declare variables to be passed into your templates. - # Global configuration global: # -- (map) AWS configuration @@ -50,7 +49,8 @@ global: # -- (string) Access level for tiers. acceptable values for `tier_access_level` are: `libre`, `regular` and `private`. If omitted, by default common will be treated as `private` tierAccessLevel: libre # -- (bool) Whether network policies are enabled. - netPolicy: true + netPolicy: + enabled: true # -- (int) Number of dispatcher jobs. dispatcherJobNum: "10" # -- (bool) If the service will be deployed with a Pod Disruption Budget. Note- you need to have more than 2 replicas for the pdb to be deployed. @@ -140,20 +140,20 @@ affinity: podAntiAffinity: # -- (map) Option for scheduling to be required or preferred. preferredDuringSchedulingIgnoredDuringExecution: - # -- (int) Weight value for preferred scheduling. - - weight: 100 - podAffinityTerm: - labelSelector: - matchExpressions: - # -- (list) Label key for match expression. - - key: app - # -- (string) Operation type for the match expression. - operator: In - # -- (list) Value for the match expression key. - values: - - metadata - # -- (string) Value for topology key label. - topologyKey: "kubernetes.io/hostname" + # -- (int) Weight value for preferred scheduling. + - weight: 100 + podAffinityTerm: + labelSelector: + matchExpressions: + # -- (list) Label key for match expression. + - key: app + # -- (string) Operation type for the match expression. + operator: In + # -- (list) Value for the match expression key. + values: + - metadata + # -- (string) Value for topology key label. + topologyKey: "kubernetes.io/hostname" # -- (bool) Automount the default service account token automountServiceAccountToken: false @@ -177,7 +177,6 @@ useAggMds: "True" # -- (string) Namespae to use if AggMds is enabled. aggMdsNamespace: default - aggMdsConfig: | { "configuration": { diff --git a/helm/neuvector/Chart.yaml b/helm/neuvector/Chart.yaml index 46be470b..1a064380 100644 --- a/helm/neuvector/Chart.yaml +++ b/helm/neuvector/Chart.yaml @@ -19,7 +19,7 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.0 +version: 0.1.1 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to diff --git a/helm/neuvector/README.md b/helm/neuvector/README.md index c69d8513..6584a6d8 100644 --- a/helm/neuvector/README.md +++ b/helm/neuvector/README.md @@ -1,6 +1,6 @@ # neuvector -![Version: 0.1.0](https://img.shields.io/badge/Version-0.1.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 1.16.0](https://img.shields.io/badge/AppVersion-1.16.0-informational?style=flat-square) +![Version: 0.1.1](https://img.shields.io/badge/Version-0.1.1-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 1.16.0](https://img.shields.io/badge/AppVersion-1.16.0-informational?style=flat-square) NeuVector Kubernetes Security Policy templates to protect Gen3 @@ -19,3 +19,5 @@ NeuVector Kubernetes Security Policy templates to protect Gen3 | policies.include | bool | `true` | | | policies.policyMode | string | `"Monitor"` | | +---------------------------------------------- +Autogenerated from chart metadata using [helm-docs v1.13.1](https://github.com/norwoodj/helm-docs/releases/v1.13.1) diff --git a/helm/peregrine/Chart.yaml b/helm/peregrine/Chart.yaml index e190277b..24be0632 100644 --- a/helm/peregrine/Chart.yaml +++ b/helm/peregrine/Chart.yaml @@ -15,7 +15,7 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.14 +version: 0.1.15 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to diff --git a/helm/peregrine/README.md b/helm/peregrine/README.md index 0272b818..fcb545cd 100644 --- a/helm/peregrine/README.md +++ b/helm/peregrine/README.md @@ -1,6 +1,6 @@ # peregrine -![Version: 0.1.14](https://img.shields.io/badge/Version-0.1.14-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) +![Version: 0.1.15](https://img.shields.io/badge/Version-0.1.15-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) A Helm chart for gen3 Peregrine service @@ -43,7 +43,7 @@ A Helm chart for gen3 Peregrine service | global.kubeBucket | string | `"kube-gen3"` | S3 bucket name for Kubernetes manifest files. | | global.logsBucket | string | `"logs-gen3"` | S3 bucket name for log files. | | global.minAvialable | int | `1` | The minimum amount of pods that are available at all times if the PDB is deployed. | -| global.netPolicy | bool | `true` | Whether network policies are enabled. | +| global.netPolicy | bool | `{"enabled":true}` | Whether network policies are enabled. | | global.pdb | bool | `false` | If the service will be deployed with a Pod Disruption Budget. Note- you need to have more than 2 replicas for the pdb to be deployed. | | global.portalApp | string | `"gitops"` | Portal application name. | | global.postgres.dbCreate | bool | `true` | Whether the database should be created. | @@ -61,6 +61,9 @@ A Helm chart for gen3 Peregrine service | imagePullSecrets | list | `[]` | Docker image pull secrets. | | metricsEnabled | bool | `false` | Whether Metrics are enabled. | | nameOverride | string | `""` | Override the name of the chart. | +| netPolicy | map | `{"egressApps":["pidgin"],"ingressApps":["pidgin"]}` | Configuration for network policies created by this chart. Only relevant if "global.netPolicy.enabled" is set to true | +| netPolicy.egressApps | array | `["pidgin"]` | List of apps that this app requires egress to | +| netPolicy.ingressApps | array | `["pidgin"]` | List of app labels that require ingress to this service | | nodeSelector | map | `{}` | Node Selector for the pods | | partOf | string | `"Core-Service"` | Label to help organize pods and their use. Any value is valid, but use "_" or "-" to divide words. | | podAnnotations | map | `{}` | Annotations to add to the pod | @@ -99,3 +102,5 @@ A Helm chart for gen3 Peregrine service | volumeMounts | list | `[{"mountPath":"/var/www/peregrine/settings.py","name":"config-volume","readOnly":true,"subPath":"settings.py"}]` | Volumes to mount to the container. | | volumes | list | `[{"emptyDir":{},"name":"shared-data"},{"name":"config-volume","secret":{"secretName":"peregrine-secret"}}]` | Volumes to attach to the container. | +---------------------------------------------- +Autogenerated from chart metadata using [helm-docs v1.13.1](https://github.com/norwoodj/helm-docs/releases/v1.13.1) diff --git a/helm/peregrine/templates/netpolicy.yaml b/helm/peregrine/templates/netpolicy.yaml new file mode 100644 index 00000000..93949e3a --- /dev/null +++ b/helm/peregrine/templates/netpolicy.yaml @@ -0,0 +1,9 @@ +{{ include "common.db_netpolicy" . }} + +--- + +{{ include "common.ingress_netpolicy" . }} + +--- + +{{ include "common.egress_netpolicy" . }} \ No newline at end of file diff --git a/helm/peregrine/values.yaml b/helm/peregrine/values.yaml index 79c488dd..051c6563 100644 --- a/helm/peregrine/values.yaml +++ b/helm/peregrine/values.yaml @@ -1,7 +1,6 @@ # Default values for peregrine. # This is a YAML-formatted file. - # Global configuration global: # -- (map) AWS configuration @@ -47,7 +46,8 @@ global: # -- (string) Access level for tiers. acceptable values for `tier_access_level` are: `libre`, `regular` and `private`. If omitted, by default common will be treated as `private` tierAccessLevel: libre # -- (bool) Whether network policies are enabled. - netPolicy: true + netPolicy: + enabled: true # -- (int) Number of dispatcher jobs. dispatcherJobNum: "10" # -- (bool) If the service will be deployed with a Pod Disruption Budget. Note- you need to have more than 2 replicas for the pdb to be deployed. @@ -75,7 +75,6 @@ secrets: # -- (str) AWS secret access key ID. Overrides global key. awsSecretAccessKey: - # -- (map) Postgres database configuration. If db does not exist in postgres cluster and dbCreate is set ot true then these databases will be created for you postgres: # (bool) Whether the database should be restored from s3. Default to global.postgres.dbRestore @@ -139,11 +138,13 @@ serviceAccount: podAnnotations: {} # -- (map) Security context for the pod -podSecurityContext: {} +podSecurityContext: + {} # fsGroup: 2000 # -- (map) Security context for the containers in the pod -securityContext: {} +securityContext: + {} # capabilities: # drop: # - ALL @@ -158,6 +159,16 @@ service: # -- (int) The port number that the service exposes. port: 80 +# -- (map) Configuration for network policies created by this chart. Only relevant if "global.netPolicy.enabled" is set to true +netPolicy: + # -- (array) List of app labels that require ingress to this service + ingressApps: + - pidgin + + # -- (array) List of apps that this app requires egress to + egressApps: + - pidgin + # -- (map) Resource requests and limits for the containers in the pod resources: # -- (map) The amount of resources that the container requests @@ -199,11 +210,11 @@ env: # -- (list) Volumes to attach to the container. volumes: -- name: shared-data - emptyDir: {} -- name: config-volume - secret: - secretName: "peregrine-secret" + - name: shared-data + emptyDir: {} + - name: config-volume + secret: + secretName: "peregrine-secret" # -- (list) Volumes to mount to the container. volumeMounts: diff --git a/helm/pidgin/Chart.yaml b/helm/pidgin/Chart.yaml index 0a535a12..0b4d9182 100644 --- a/helm/pidgin/Chart.yaml +++ b/helm/pidgin/Chart.yaml @@ -15,7 +15,7 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.11 +version: 0.1.12 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to diff --git a/helm/pidgin/README.md b/helm/pidgin/README.md index 522b1c49..afd80b13 100644 --- a/helm/pidgin/README.md +++ b/helm/pidgin/README.md @@ -1,6 +1,6 @@ # pidgin -![Version: 0.1.11](https://img.shields.io/badge/Version-0.1.11-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) +![Version: 0.1.12](https://img.shields.io/badge/Version-0.1.12-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) A Helm chart for gen3 Pidgin Service @@ -46,7 +46,7 @@ A Helm chart for gen3 Pidgin Service | global.kubeBucket | string | `"kube-gen3"` | S3 bucket name for Kubernetes manifest files. | | global.logsBucket | string | `"logs-gen3"` | S3 bucket name for log files. | | global.minAvialable | int | `1` | The minimum amount of pods that are available at all times if the PDB is deployed. | -| global.netPolicy | bool | `true` | Whether network policies are enabled. | +| global.netPolicy | bool | `{"enabled":true}` | Whether network policies are enabled. | | global.pdb | bool | `false` | If the service will be deployed with a Pod Disruption Budget. Note- you need to have more than 2 replicas for the pdb to be deployed. | | global.portalApp | string | `"gitops"` | Portal application name. | | global.postgres.dbCreate | bool | `true` | Whether the database should be created. | @@ -82,3 +82,5 @@ A Helm chart for gen3 Pidgin Service | strategy.rollingUpdate.maxSurge | int | `1` | Number of additional replicas to add during rollout. | | strategy.rollingUpdate.maxUnavailable | int | `0` | Maximum amount of pods that can be unavailable during the update. | +---------------------------------------------- +Autogenerated from chart metadata using [helm-docs v1.13.1](https://github.com/norwoodj/helm-docs/releases/v1.13.1) diff --git a/helm/pidgin/values.yaml b/helm/pidgin/values.yaml index 414d642b..b4db3558 100644 --- a/helm/pidgin/values.yaml +++ b/helm/pidgin/values.yaml @@ -2,7 +2,6 @@ # This is a YAML-formatted file. # Declare variables to be passed into your templates. - # Global configuration global: # -- (map) AWS configuration @@ -50,7 +49,8 @@ global: # -- (string) Access level for tiers. acceptable values for `tier_access_level` are: `libre`, `regular` and `private`. If omitted, by default common will be treated as `private` tierAccessLevel: libre # -- (bool) Whether network policies are enabled. - netPolicy: true + netPolicy: + enabled: true # -- (int) Number of dispatcher jobs. dispatcherJobNum: "10" # -- (bool) Whether Datadog is enabled. @@ -114,20 +114,20 @@ affinity: podAntiAffinity: # -- (map) Option for scheduling to be required or preferred. preferredDuringSchedulingIgnoredDuringExecution: - # -- (int) Weight value for preferred scheduling. - - weight: 100 - podAffinityTerm: - labelSelector: - matchExpressions: - # -- (list) Label key for match expression. - - key: app - # -- (string) Operation type for the match expression. - operator: In - # -- (list) Value for the match expression key. - values: - - pidgin - # -- (string) Value for topology key label. - topologyKey: "kubernetes.io/hostname" + # -- (int) Weight value for preferred scheduling. + - weight: 100 + podAffinityTerm: + labelSelector: + matchExpressions: + # -- (list) Label key for match expression. + - key: app + # -- (string) Operation type for the match expression. + operator: In + # -- (list) Value for the match expression key. + values: + - pidgin + # -- (string) Value for topology key label. + topologyKey: "kubernetes.io/hostname" # -- (bool) Automount the default service account token automountServiceAccountToken: false diff --git a/helm/portal/Chart.yaml b/helm/portal/Chart.yaml index 5eac7025..ff1ec9d4 100644 --- a/helm/portal/Chart.yaml +++ b/helm/portal/Chart.yaml @@ -15,7 +15,7 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.17 +version: 0.1.18 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to diff --git a/helm/portal/README.md b/helm/portal/README.md index 3a868761..a0ab696e 100644 --- a/helm/portal/README.md +++ b/helm/portal/README.md @@ -1,6 +1,6 @@ # portal -![Version: 0.1.17](https://img.shields.io/badge/Version-0.1.17-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) +![Version: 0.1.18](https://img.shields.io/badge/Version-0.1.18-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) A Helm chart for gen3 data-portal @@ -50,7 +50,7 @@ A Helm chart for gen3 data-portal | global.kubeBucket | string | `"kube-gen3"` | S3 bucket name for Kubernetes manifest files. | | global.logsBucket | string | `"logs-gen3"` | S3 bucket name for log files. | | global.minAvialable | int | `1` | The minimum amount of pods that are available at all times if the PDB is deployed. | -| global.netPolicy | bool | `true` | Whether network policies are enabled. | +| global.netPolicy | bool | `{"enabled":true}` | Whether network policies are enabled. | | global.pdb | bool | `false` | If the service will be deployed with a Pod Disruption Budget. Note- you need to have more than 2 replicas for the pdb to be deployed. | | global.portalApp | string | `"gitops"` | Portal application name. | | global.postgres.dbCreate | bool | `true` | Whether the database should be created. | @@ -98,3 +98,5 @@ A Helm chart for gen3 data-portal | strategy.rollingUpdate.maxUnavailable | int | `"25%"` | Maximum amount of pods that can be unavailable during the update. | | tolerations | list | `[]` | Tolerations to apply to the pod | +---------------------------------------------- +Autogenerated from chart metadata using [helm-docs v1.13.1](https://github.com/norwoodj/helm-docs/releases/v1.13.1) diff --git a/helm/portal/values.yaml b/helm/portal/values.yaml index be861167..e75d4cd7 100644 --- a/helm/portal/values.yaml +++ b/helm/portal/values.yaml @@ -51,7 +51,8 @@ global: # -- (int) Only relevant if tireAccessLevel is set to "regular". Summary charts below this limit will not appear for aggregated data. tierAccessLimit: "1000" # -- (bool) Whether network policies are enabled. - netPolicy: true + netPolicy: + enabled: true # -- (int) Number of dispatcher jobs. dispatcherJobNum: "10" # -- (bool) If the service will be deployed with a Pod Disruption Budget. Note- you need to have more than 2 replicas for the pdb to be deployed. @@ -99,11 +100,13 @@ serviceAccount: podAnnotations: {} # -- (map) Security context to apply to the pod -podSecurityContext: {} +podSecurityContext: + {} # fsGroup: 2000 # -- (map) Security context to apply to the container -securityContext: {} +securityContext: + {} # capabilities: # drop: # - ALL @@ -153,20 +156,20 @@ affinity: podAntiAffinity: # -- (map) Option for scheduling to be required or preferred. preferredDuringSchedulingIgnoredDuringExecution: - # -- (int) Weight value for preferred scheduling. - - weight: 100 - podAffinityTerm: - labelSelector: - matchExpressions: - # -- (list) Label key for match expression. - - key: app - # -- (string) Operation type for the match expression. - operator: In - # -- (list) Value for the match expression key. - values: - - portal - # -- (string) Value for topology key label. - topologyKey: "kubernetes.io/hostname" + # -- (int) Weight value for preferred scheduling. + - weight: 100 + podAffinityTerm: + labelSelector: + matchExpressions: + # -- (list) Label key for match expression. + - key: app + # -- (string) Operation type for the match expression. + operator: In + # -- (list) Value for the match expression key. + values: + - portal + # -- (string) Value for topology key label. + topologyKey: "kubernetes.io/hostname" # -- (bool) Automount the default service account token automountServiceAccountToken: false @@ -200,7 +203,6 @@ commonLabels: extraImages: # - url: https://raw.githubusercontent.com/uc-cdis/gen3-helm/master/docs/images/gen3-blue-dark.png - # -- (map) GitOps configuration for portal gitops: # -- (string) multiline string - gitops.json @@ -463,15 +465,12 @@ gitops: } } # -- (string) - favicon in base64 - favicon: - "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" + favicon: "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" # -- (string) - multiline string - gitops.css css: | /* gitops default css */ # -- (string) - logo in base64 - logo: - "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" + logo: "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" # -- (string) - createdby.png - base64 - createdby: - "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" + createdby: "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" sponsors: diff --git a/helm/requestor/Chart.yaml b/helm/requestor/Chart.yaml index 5244fd6c..05ea48a5 100644 --- a/helm/requestor/Chart.yaml +++ b/helm/requestor/Chart.yaml @@ -15,7 +15,7 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.12 +version: 0.1.13 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to diff --git a/helm/requestor/README.md b/helm/requestor/README.md index 01e5bf48..ed3436c1 100644 --- a/helm/requestor/README.md +++ b/helm/requestor/README.md @@ -1,6 +1,6 @@ # requestor -![Version: 0.1.12](https://img.shields.io/badge/Version-0.1.12-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) +![Version: 0.1.13](https://img.shields.io/badge/Version-0.1.13-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) A Helm chart for gen3 Requestor Service @@ -51,7 +51,7 @@ A Helm chart for gen3 Requestor Service | global.kubeBucket | string | `"kube-gen3"` | S3 bucket name for Kubernetes manifest files. | | global.logsBucket | string | `"logs-gen3"` | S3 bucket name for log files. | | global.minAvialable | int | `1` | The minimum amount of pods that are available at all times if the PDB is deployed. | -| global.netPolicy | bool | `true` | Whether network policies are enabled. | +| global.netPolicy | bool | `{"enabled":true}` | Whether network policies are enabled. | | global.onlyDbgap | bool | `false` | Forces ONLY a dbgap sync if "true", IGNORING user.yaml | | global.pdb | bool | `false` | If the service will be deployed with a Pod Disruption Budget. Note- you need to have more than 2 replicas for the pdb to be deployed. | | global.portalApp | string | `"gitops"` | Portal application name. | @@ -114,3 +114,5 @@ A Helm chart for gen3 Requestor Service | strategy.rollingUpdate.maxUnavailable | int | `0` | Maximum amount of pods that can be unavailable during the update. | | volumeMounts | list | `nil` | Volumes to mount to the container. | +---------------------------------------------- +Autogenerated from chart metadata using [helm-docs v1.13.1](https://github.com/norwoodj/helm-docs/releases/v1.13.1) diff --git a/helm/requestor/templates/netpolicy.yaml b/helm/requestor/templates/netpolicy.yaml new file mode 100644 index 00000000..70a5c3b5 --- /dev/null +++ b/helm/requestor/templates/netpolicy.yaml @@ -0,0 +1 @@ +{{ include "common.db_netpolicy" . }} \ No newline at end of file diff --git a/helm/requestor/values.yaml b/helm/requestor/values.yaml index e64454ad..724a4236 100644 --- a/helm/requestor/values.yaml +++ b/helm/requestor/values.yaml @@ -2,7 +2,6 @@ # This is a YAML-formatted file. # Declare variables to be passed into your templates. - # Global configuration global: # -- (map) AWS configuration @@ -64,7 +63,8 @@ global: # -- (string) Access level for tiers. acceptable values for `tier_access_level` are: `libre`, `regular` and `private`. If omitted, by default common will be treated as `private` tierAccessLevel: libre # -- (bool) Whether network policies are enabled. - netPolicy: true + netPolicy: + enabled: true # -- (int) Number of dispatcher jobs. dispatcherJobNum: "10" # -- (bool) If the service will be deployed with a Pod Disruption Budget. Note- you need to have more than 2 replicas for the pdb to be deployed. @@ -153,20 +153,20 @@ affinity: podAntiAffinity: # -- (map) Option for scheduling to be required or preferred. preferredDuringSchedulingIgnoredDuringExecution: - # -- (int) Weight value for preferred scheduling. - - weight: 100 - podAffinityTerm: - labelSelector: - matchExpressions: - # -- (list) Label key for match expression. - - key: app - # -- (string) Operation type for the match expression. - operator: In - # -- (list) Value for the match expression key. - values: - - requestor - # -- (string) Value for topology key label. - topologyKey: "kubernetes.io/hostname" + # -- (int) Weight value for preferred scheduling. + - weight: 100 + podAffinityTerm: + labelSelector: + matchExpressions: + # -- (list) Label key for match expression. + - key: app + # -- (string) Operation type for the match expression. + operator: In + # -- (list) Value for the match expression key. + values: + - requestor + # -- (string) Value for topology key label. + topologyKey: "kubernetes.io/hostname" # -- (bool) Automount the default service account token automountServiceAccountToken: false diff --git a/helm/revproxy/Chart.yaml b/helm/revproxy/Chart.yaml index 85531fe6..0c06ffea 100644 --- a/helm/revproxy/Chart.yaml +++ b/helm/revproxy/Chart.yaml @@ -15,7 +15,7 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.17 +version: 0.1.18 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to diff --git a/helm/revproxy/README.md b/helm/revproxy/README.md index 430e223e..7e4f7b1f 100644 --- a/helm/revproxy/README.md +++ b/helm/revproxy/README.md @@ -1,6 +1,6 @@ # revproxy -![Version: 0.1.17](https://img.shields.io/badge/Version-0.1.17-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) +![Version: 0.1.18](https://img.shields.io/badge/Version-0.1.18-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) A Helm chart for gen3 revproxy @@ -38,7 +38,7 @@ A Helm chart for gen3 revproxy | global.kubeBucket | string | `"kube-gen3"` | S3 bucket name for Kubernetes manifest files. | | global.logsBucket | string | `"logs-gen3"` | S3 bucket name for log files. | | global.minAvialable | int | `1` | The minimum amount of pods that are available at all times if the PDB is deployed. | -| global.netPolicy | bool | `true` | Whether network policies are enabled. | +| global.netPolicy | bool | `{"enabled":true}` | Whether network policies are enabled. | | global.pdb | bool | `false` | If the service will be deployed with a Pod Disruption Budget. Note- you need to have more than 2 replicas for the pdb to be deployed. | | global.portalApp | string | `"gitops"` | Portal application name. | | global.postgres.dbCreate | bool | `true` | Whether the database should be created. | @@ -67,6 +67,9 @@ A Helm chart for gen3 revproxy | ingress.tls | list | `[]` | To secure an Ingress by specifying a secret that contains a TLS private key and certificate. | | metricsEnabled | bool | `false` | Whether Metrics are enabled. | | nameOverride | string | `""` | Override the name of the chart. | +| netPolicy | map | `{"egressApps":["portal","sowerjob"],"ingressApps":["portal","sowerjob"]}` | Configuration for network policies created by this chart. Only relevant if "global.netPolicy.enabled" is set to true | +| netPolicy.egressApps | array | `["portal","sowerjob"]` | List of apps that this app requires egress to | +| netPolicy.ingressApps | array | `["portal","sowerjob"]` | List of app labels that require ingress to this service | | nodeSelector | map | `{}` | Node selector labels. | | partOf | string | `"Front-End"` | Label to help organize pods and their use. Any value is valid, but use "_" or "-" to divide words. | | podAnnotations | map | `{}` | Annotations to add to the pod. | @@ -104,3 +107,5 @@ A Helm chart for gen3 revproxy | tolerations | list | `[]` | Tolerations to use for the deployment. | | userhelperEnabled | bool | `false` | | +---------------------------------------------- +Autogenerated from chart metadata using [helm-docs v1.13.1](https://github.com/norwoodj/helm-docs/releases/v1.13.1) diff --git a/helm/revproxy/templates/netpolicy.yaml b/helm/revproxy/templates/netpolicy.yaml new file mode 100644 index 00000000..7db06ee7 --- /dev/null +++ b/helm/revproxy/templates/netpolicy.yaml @@ -0,0 +1,59 @@ +{{ include "common.ingress_netpolicy" . }} + +--- + +{{ include "common.egress_netpolicy" . }} + +--- + +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: netpolicy-revproxy +spec: + podSelector: + matchExpressions: + - key: app + operator: In + values: + - revproxy + - ambassador-gen3 + - auspice + - ohdsi-atlas + - ohdsi-webapi + - superset + - superset-worker + - superset-redis-master + ingress: + - from: + - ipBlock: + cidr: 0.0.0.0/0 + ports: + - port: 80 + - port: 4000 + - port: 8080 + - port: 81 + - port: 82 + - port: 443 + - port: 8088 + - port: 9090 + egress: + - to: + - namespaceSelector: + matchLabels: + app: prometheus + - to: + - namespaceSelector: + matchLabels: + app: grafana + - to: + - namespaceSelector: + matchLabels: + app: argo + - to: + - namespaceSelector: + matchLabels: + app: argocd + policyTypes: + - Ingress + - Egress \ No newline at end of file diff --git a/helm/revproxy/values.yaml b/helm/revproxy/values.yaml index f2748347..b23a41a9 100644 --- a/helm/revproxy/values.yaml +++ b/helm/revproxy/values.yaml @@ -2,7 +2,6 @@ # This is a YAML-formatted file. # Declare variables to be passed into your templates. - # Global configuration global: tls: @@ -61,7 +60,8 @@ global: # -- (int) Only relevant if tireAccessLevel is set to "regular". Summary charts below this limit will not appear for aggregated data. tierAccessLimit: "1000" # -- (bool) Whether network policies are enabled. - netPolicy: true + netPolicy: + enabled: true # -- (int) Number of dispatcher jobs. dispatcherJobNum: "10" # -- (bool) If the service will be deployed with a Pod Disruption Budget. Note- you need to have more than 2 replicas for the pdb to be deployed. @@ -124,11 +124,13 @@ serviceAccount: podAnnotations: {} # -- (map) Pod-level security context. -podSecurityContext: {} +podSecurityContext: + {} # fsGroup: 2000 # -- (map) Container-level security context. -securityContext: {} +securityContext: + {} # capabilities: # drop: # - ALL @@ -143,6 +145,18 @@ service: # -- (int) The port number that the service exposes. port: 80 +# -- (map) Configuration for network policies created by this chart. Only relevant if "global.netPolicy.enabled" is set to true +netPolicy: + # -- (array) List of app labels that require ingress to this service + ingressApps: + - portal + - sowerjob + + # -- (array) List of apps that this app requires egress to + egressApps: + - portal + - sowerjob + # -- (map) Configuration for revproxy ingress. ingress: # -- (bool) Whether to create the ingress @@ -150,7 +164,8 @@ ingress: # -- (string) The ingress class name. className: "" # -- (map) Annotations to add to the ingress. - annotations: {} + annotations: + {} # kubernetes.io/ingress.class: nginx # kubernetes.io/tls-acme: "true" # -- (list) Where to route the traffic. diff --git a/helm/sheepdog/Chart.yaml b/helm/sheepdog/Chart.yaml index fbaa346b..ddde7c4e 100644 --- a/helm/sheepdog/Chart.yaml +++ b/helm/sheepdog/Chart.yaml @@ -15,7 +15,7 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.15 +version: 0.1.16 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to diff --git a/helm/sheepdog/README.md b/helm/sheepdog/README.md index f785ceaa..abaa5912 100644 --- a/helm/sheepdog/README.md +++ b/helm/sheepdog/README.md @@ -1,6 +1,6 @@ # sheepdog -![Version: 0.1.15](https://img.shields.io/badge/Version-0.1.15-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) +![Version: 0.1.16](https://img.shields.io/badge/Version-0.1.16-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) A Helm chart for gen3 Sheepdog Service @@ -52,7 +52,7 @@ A Helm chart for gen3 Sheepdog Service | global.kubeBucket | string | `"kube-gen3"` | S3 bucket name for Kubernetes manifest files. | | global.logsBucket | string | `"logs-gen3"` | S3 bucket name for log files. | | global.minAvialable | int | `1` | The minimum amount of pods that are available at all times if the PDB is deployed. | -| global.netPolicy | bool | `true` | Whether network policies are enabled. | +| global.netPolicy | bool | `{"enabled":true}` | Whether network policies are enabled. | | global.pdb | bool | `false` | If the service will be deployed with a Pod Disruption Budget. Note- you need to have more than 2 replicas for the pdb to be deployed. | | global.portalApp | string | `"gitops"` | Portal application name. | | global.postgres.dbCreate | bool | `true` | Whether the database should be created. | @@ -107,3 +107,5 @@ A Helm chart for gen3 Sheepdog Service | terminationGracePeriodSeconds | int | `50` | sheepdog transactions take forever - try to let the complete before termination | | volumeMounts | list | `[{"mountPath":"/var/www/sheepdog/settings.py","name":"config-volume","readOnly":true,"subPath":"settings.py"}]` | Volumes to mount to the container. | +---------------------------------------------- +Autogenerated from chart metadata using [helm-docs v1.13.1](https://github.com/norwoodj/helm-docs/releases/v1.13.1) diff --git a/helm/sheepdog/templates/netpolicy.yaml b/helm/sheepdog/templates/netpolicy.yaml new file mode 100644 index 00000000..70a5c3b5 --- /dev/null +++ b/helm/sheepdog/templates/netpolicy.yaml @@ -0,0 +1 @@ +{{ include "common.db_netpolicy" . }} \ No newline at end of file diff --git a/helm/sheepdog/values.yaml b/helm/sheepdog/values.yaml index 268b1223..71e65b16 100644 --- a/helm/sheepdog/values.yaml +++ b/helm/sheepdog/values.yaml @@ -2,7 +2,6 @@ # This is a YAML-formatted file. # Declare variables to be passed into your templates. - # Global configuration global: # -- (map) AWS configuration @@ -50,7 +49,8 @@ global: # -- (string) Access level for tiers. acceptable values for `tier_access_level` are: `libre`, `regular` and `private`. If omitted, by default common will be treated as `private` tierAccessLevel: libre # -- (bool) Whether network policies are enabled. - netPolicy: true + netPolicy: + enabled: true # -- (int) Number of dispatcher jobs. dispatcherJobNum: "10" # -- (bool) If the service will be deployed with a Pod Disruption Budget. Note- you need to have more than 2 replicas for the pdb to be deployed. @@ -103,7 +103,7 @@ postgresql: releaseLabel: production # -- (map) Annotations to add to the pod -podAnnotations: {"gen3.io/network-ingress": "sheepdog"} +podAnnotations: { "gen3.io/network-ingress": "sheepdog" } # -- (map) Configuration for autoscaling the number of replicas autoscaling: @@ -141,20 +141,20 @@ affinity: podAntiAffinity: # -- (map) Option for scheduling to be required or preferred. preferredDuringSchedulingIgnoredDuringExecution: - # -- (int) Weight value for preferred scheduling. - - weight: 100 - podAffinityTerm: - labelSelector: - matchExpressions: - # -- (list) Label key for match expression. - - key: app - # -- (string) Operation type for the match expression. - operator: In - # -- (list) Value for the match expression key. - values: - - sheepdog - # -- (string) Value for topology key label. - topologyKey: "kubernetes.io/hostname" + # -- (int) Weight value for preferred scheduling. + - weight: 100 + podAffinityTerm: + labelSelector: + matchExpressions: + # -- (list) Label key for match expression. + - key: app + # -- (string) Operation type for the match expression. + operator: In + # -- (list) Value for the match expression key. + values: + - sheepdog + # -- (string) Value for topology key label. + topologyKey: "kubernetes.io/hostname" # -- (bool) Automount the default service account token automountServiceAccountToken: false diff --git a/helm/sower/Chart.yaml b/helm/sower/Chart.yaml index 5e6090aa..6e18c4ed 100644 --- a/helm/sower/Chart.yaml +++ b/helm/sower/Chart.yaml @@ -15,7 +15,7 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.13 +version: 0.1.14 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to diff --git a/helm/sower/README.md b/helm/sower/README.md index ff634448..33aaffa5 100644 --- a/helm/sower/README.md +++ b/helm/sower/README.md @@ -1,6 +1,6 @@ # sower -![Version: 0.1.13](https://img.shields.io/badge/Version-0.1.13-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) +![Version: 0.1.14](https://img.shields.io/badge/Version-0.1.14-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) A Helm chart for gen3 sower @@ -50,7 +50,7 @@ A Helm chart for gen3 sower | global.hostname | string | `"localhost"` | Hostname for the deployment. | | global.kubeBucket | string | `"kube-gen3"` | S3 bucket name for Kubernetes manifest files. | | global.logsBucket | string | `"logs-gen3"` | S3 bucket name for log files. | -| global.netPolicy | bool | `true` | Whether network policies are enabled. | +| global.netPolicy | bool | `{"enabled":true}` | Whether network policies are enabled. | | global.portalApp | string | `"gitops"` | Portal application name. | | global.postgres.dbCreate | bool | `true` | Whether the database should be created. | | global.postgres.externalSecret | string | `""` | Name of external secret. Disabled if empty | @@ -69,6 +69,9 @@ A Helm chart for gen3 sower | imagePullSecrets | list | `[]` | Docker image pull secrets. | | metricsEnabled | bool | `false` | Whether Metrics are enabled. | | nameOverride | string | `""` | Override the name of the chart. | +| netPolicy | map | `{"egressApps":["pidgin"],"ingressApps":["pidgin"]}` | Configuration for network policies created by this chart. Only relevant if "global.netPolicy.enabled" is set to true | +| netPolicy.egressApps | array | `["pidgin"]` | List of apps that this app requires egress to | +| netPolicy.ingressApps | array | `["pidgin"]` | List of app labels that require ingress to this service | | nodeSelector | map | `{}` | Node Selector for the pods | | partOf | string | `"Core-Service"` | Label to help organize pods and their use. Any value is valid, but use "_" or "-" to divide words. | | podSecurityContext | map | `{"fsGroup":1000,"runAsUser":1000}` | Security context to apply to the pod | @@ -181,3 +184,5 @@ A Helm chart for gen3 sower | volumeMounts | list | `[{"mountPath":"/sower_config.json","name":"sower-config","readOnly":true,"subPath":"sower_config.json"}]` | Volumes to mount to the container. | | volumes | list | `[{"configMap":{"items":[{"key":"json","path":"sower_config.json"}],"name":"manifest-sower"},"name":"sower-config"}]` | Volumes to attach to the container. | +---------------------------------------------- +Autogenerated from chart metadata using [helm-docs v1.13.1](https://github.com/norwoodj/helm-docs/releases/v1.13.1) diff --git a/helm/sower/templates/netpolicy.yaml b/helm/sower/templates/netpolicy.yaml new file mode 100644 index 00000000..82813feb --- /dev/null +++ b/helm/sower/templates/netpolicy.yaml @@ -0,0 +1,20 @@ +{{ include "common.ingress_netpolicy" . }} + +--- + +{{ include "common.egress_netpolicy" . }} + +--- + +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: netpolicy-sowerjob +spec: + podSelector: + matchLabels: + app: sowerjob + egress: + - {} + policyTypes: + - Egress diff --git a/helm/sower/values.yaml b/helm/sower/values.yaml index b4d1d955..f0b1e703 100644 --- a/helm/sower/values.yaml +++ b/helm/sower/values.yaml @@ -2,7 +2,6 @@ # This is a YAML-formatted file. # Declare variables to be passed into your templates. - # Global configuration global: # -- (map) AWS configuration @@ -50,7 +49,8 @@ global: # -- (string) Access level for tiers. acceptable values for `tier_access_level` are: `libre`, `regular` and `private`. If omitted, by default common will be treated as `private` tierAccessLevel: libre # -- (bool) Whether network policies are enabled. - netPolicy: true + netPolicy: + enabled: true # -- (int) Number of dispatcher jobs. dispatcherJobNum: "10" # -- (map) External Secrets settings. @@ -99,7 +99,8 @@ nameOverride: "" fullnameOverride: "" # -- (map) Security context for the containers in the pod -securityContext: {} +securityContext: + {} # capabilities: # drop: # - ALL @@ -114,6 +115,16 @@ service: # -- (int) The port number that the service exposes. port: 80 +# -- (map) Configuration for network policies created by this chart. Only relevant if "global.netPolicy.enabled" is set to true +netPolicy: + # -- (array) List of app labels that require ingress to this service + ingressApps: + - pidgin + + # -- (array) List of apps that this app requires egress to + egressApps: + - pidgin + # -- (map) Configuration for autoscaling the number of replicas autoscaling: # -- (bool) Whether autoscaling is enabled @@ -144,20 +155,20 @@ affinity: podAntiAffinity: # -- (map) Option for scheduling to be required or preferred. preferredDuringSchedulingIgnoredDuringExecution: - # -- (int) Weight value for preferred scheduling. - - weight: 100 - podAffinityTerm: - labelSelector: - matchExpressions: - # -- (list) Label key for match expression. - - key: app - # -- (string) Operation type for the match expression. - operator: In - # -- (list) Value for the match expression key. - values: - - sower - # -- (string) Value for topology key label. - topologyKey: "kubernetes.io/hostname" + # -- (int) Weight value for preferred scheduling. + - weight: 100 + podAffinityTerm: + labelSelector: + matchExpressions: + # -- (list) Label key for match expression. + - key: app + # -- (string) Operation type for the match expression. + operator: In + # -- (list) Value for the match expression key. + values: + - sower + # -- (string) Value for topology key label. + topologyKey: "kubernetes.io/hostname" # -- (list) Volumes to attach to the container. volumes: @@ -214,54 +225,54 @@ sowerConfig: image: quay.io/cdis/pelican-export:GPE-1252 pull_policy: Always env: - - name: DICTIONARY_URL - valueFrom: - configMapKeyRef: - name: manifest-global - key: dictionary_url - - name: GEN3_HOSTNAME - valueFrom: - configMapKeyRef: - name: manifest-global - key: hostname - - name: ROOT_NODE - value: subject - - name: DB_HOST - valueFrom: - secretKeyRef: - name: peregrine-dbcreds - key: host - - name: DB_DATABASE - valueFrom: - secretKeyRef: - name: peregrine-dbcreds - key: database - - name: DB_USER - valueFrom: - secretKeyRef: - name: peregrine-dbcreds - key: username - - name: DB_PASS - valueFrom: - secretKeyRef: - name: peregrine-dbcreds - key: password - - name: SHEEPDOG - valueFrom: - secretKeyRef: - name: indexd-service-creds - key: sheepdog + - name: DICTIONARY_URL + valueFrom: + configMapKeyRef: + name: manifest-global + key: dictionary_url + - name: GEN3_HOSTNAME + valueFrom: + configMapKeyRef: + name: manifest-global + key: hostname + - name: ROOT_NODE + value: subject + - name: DB_HOST + valueFrom: + secretKeyRef: + name: peregrine-dbcreds + key: host + - name: DB_DATABASE + valueFrom: + secretKeyRef: + name: peregrine-dbcreds + key: database + - name: DB_USER + valueFrom: + secretKeyRef: + name: peregrine-dbcreds + key: username + - name: DB_PASS + valueFrom: + secretKeyRef: + name: peregrine-dbcreds + key: password + - name: SHEEPDOG + valueFrom: + secretKeyRef: + name: indexd-service-creds + key: sheepdog volumeMounts: - - name: pelican-creds-volume - readOnly: true - mountPath: "/pelican-creds.json" - subPath: config.json - cpu-limit: '1' + - name: pelican-creds-volume + readOnly: true + mountPath: "/pelican-creds.json" + subPath: config.json + cpu-limit: "1" memory-limit: 12Gi volumes: - - name: pelican-creds-volume - secret: - secretName: pelicanservice-g3auto + - name: pelican-creds-volume + secret: + secretName: pelicanservice-g3auto restart_policy: Never - name: pelican-export-files action: export-files @@ -270,63 +281,62 @@ sowerConfig: image: quay.io/cdis/pelican-export:GPE-1252 pull_policy: Always env: - - name: DICTIONARY_URL - valueFrom: - configMapKeyRef: - name: manifest-global - key: dictionary_url - - name: GEN3_HOSTNAME - valueFrom: - configMapKeyRef: - name: manifest-global - key: hostname - - name: ROOT_NODE - value: file - - name: EXTRA_NODES - value: '' - - name: DB_HOST - valueFrom: - secretKeyRef: - name: peregrine-dbcreds - key: host - - name: DB_DATABASE - valueFrom: - secretKeyRef: - name: peregrine-dbcreds - key: database - - name: DB_USER - valueFrom: - secretKeyRef: - name: peregrine-dbcreds - key: username - - name: DB_PASS - valueFrom: - secretKeyRef: - name: peregrine-dbcreds - key: password - - name: SHEEPDOG - valueFrom: - secretKeyRef: - name: indexd-service-creds - key: sheepdog + - name: DICTIONARY_URL + valueFrom: + configMapKeyRef: + name: manifest-global + key: dictionary_url + - name: GEN3_HOSTNAME + valueFrom: + configMapKeyRef: + name: manifest-global + key: hostname + - name: ROOT_NODE + value: file + - name: EXTRA_NODES + value: "" + - name: DB_HOST + valueFrom: + secretKeyRef: + name: peregrine-dbcreds + key: host + - name: DB_DATABASE + valueFrom: + secretKeyRef: + name: peregrine-dbcreds + key: database + - name: DB_USER + valueFrom: + secretKeyRef: + name: peregrine-dbcreds + key: username + - name: DB_PASS + valueFrom: + secretKeyRef: + name: peregrine-dbcreds + key: password + - name: SHEEPDOG + valueFrom: + secretKeyRef: + name: indexd-service-creds + key: sheepdog volumeMounts: - - name: pelican-creds-volume - readOnly: true - mountPath: "/pelican-creds.json" - subPath: config.json - - name: peregrine-creds-volume - readOnly: true - mountPath: "/peregrine-creds.json" - subPath: creds.json - cpu-limit: '1' + - name: pelican-creds-volume + readOnly: true + mountPath: "/pelican-creds.json" + subPath: config.json + - name: peregrine-creds-volume + readOnly: true + mountPath: "/peregrine-creds.json" + subPath: creds.json + cpu-limit: "1" memory-limit: 12Gi volumes: - - name: pelican-creds-volume - secret: - secretName: pelicanservice-g3auto + - name: pelican-creds-volume + secret: + secretName: pelicanservice-g3auto restart_policy: Never - # -- (map) Service account to use or create. serviceAccount: # -- (bool) Specifies whether a service account should be created. diff --git a/helm/ssjdispatcher/Chart.yaml b/helm/ssjdispatcher/Chart.yaml index 2e96e49d..b5771e97 100644 --- a/helm/ssjdispatcher/Chart.yaml +++ b/helm/ssjdispatcher/Chart.yaml @@ -15,7 +15,7 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.11 +version: 0.1.12 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to diff --git a/helm/ssjdispatcher/README.md b/helm/ssjdispatcher/README.md index 2e476daf..c672e10b 100644 --- a/helm/ssjdispatcher/README.md +++ b/helm/ssjdispatcher/README.md @@ -1,6 +1,6 @@ # ssjdispatcher -![Version: 0.1.11](https://img.shields.io/badge/Version-0.1.11-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) +![Version: 0.1.12](https://img.shields.io/badge/Version-0.1.12-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) A Helm chart for gen3 ssjdispatcher @@ -46,7 +46,7 @@ A Helm chart for gen3 ssjdispatcher | global.kubeBucket | string | `"kube-gen3"` | S3 bucket name for Kubernetes manifest files. | | global.logsBucket | string | `"logs-gen3"` | S3 bucket name for log files. | | global.minAvialable | int | `1` | The minimum amount of pods that are available at all times if the PDB is deployed. | -| global.netPolicy | bool | `true` | Whether network policies are enabled. | +| global.netPolicy | bool | `{"enabled":true}` | Whether network policies are enabled. | | global.pdb | bool | `false` | If the service will be deployed with a Pod Disruption Budget. Note- you need to have more than 2 replicas for the pdb to be deployed. | | global.portalApp | string | `"gitops"` | Portal application name. | | global.postgres.dbCreate | bool | `true` | Whether the database should be created. | @@ -109,3 +109,5 @@ A Helm chart for gen3 ssjdispatcher | volumeMounts | list | `[{"mountPath":"/credentials.json","name":"ssjdispatcher-creds-volume","readOnly":true,"subPath":"credentials.json"}]` | Volumes to mount to the container. | | volumes | list | `[{"name":"ssjdispatcher-creds-volume","secret":{"secretName":"ssjdispatcher-creds"}}]` | Volumes to attach to the container. | +---------------------------------------------- +Autogenerated from chart metadata using [helm-docs v1.13.1](https://github.com/norwoodj/helm-docs/releases/v1.13.1) diff --git a/helm/ssjdispatcher/templates/netpolicy.yaml b/helm/ssjdispatcher/templates/netpolicy.yaml new file mode 100644 index 00000000..5eb0d850 --- /dev/null +++ b/helm/ssjdispatcher/templates/netpolicy.yaml @@ -0,0 +1,14 @@ +{{- if .Values.ssjdispatcher.enabled }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: netpolicy-ssjdispatcherjob +spec: + podSelector: + matchLabels: + app: ssjdispatcherjob + egress: + - {} + policyTypes: + - Egress +{{- end }} \ No newline at end of file diff --git a/helm/ssjdispatcher/values.yaml b/helm/ssjdispatcher/values.yaml index f7d75a06..93caeac1 100644 --- a/helm/ssjdispatcher/values.yaml +++ b/helm/ssjdispatcher/values.yaml @@ -2,7 +2,6 @@ # This is a YAML-formatted file. # Declare variables to be passed into your templates. - # Global configuration global: # -- (map) AWS configuration @@ -50,7 +49,8 @@ global: # -- (string) Access level for tiers. acceptable values for `tier_access_level` are: `libre`, `regular` and `private`. If omitted, by default common will be treated as `private` tierAccessLevel: libre # -- (bool) Whether network policies are enabled. - netPolicy: true + netPolicy: + enabled: true # -- (int) Number of dispatcher jobs. dispatcherJobNum: "10" # -- (bool) If the service will be deployed with a Pod Disruption Budget. Note- you need to have more than 2 replicas for the pdb to be deployed. @@ -83,7 +83,8 @@ nameOverride: "" fullnameOverride: "" # -- (map) Security context for the containers in the pod -securityContext: {} +securityContext: + {} # capabilities: # drop: # - ALL @@ -128,20 +129,20 @@ affinity: podAntiAffinity: # -- (map) Option for scheduling to be required or preferred. preferredDuringSchedulingIgnoredDuringExecution: - # -- (int) Weight value for preferred scheduling. - - weight: 100 - podAffinityTerm: - labelSelector: - matchExpressions: - # -- (list) Label key for match expression. - - key: app - # -- (string) Operation type for the match expression. - operator: In - # -- (list) Value for the match expression key. - values: - - ssjdispatcher - # -- (string) Value for topology key label. - topologyKey: "kubernetes.io/hostname" + # -- (int) Weight value for preferred scheduling. + - weight: 100 + podAffinityTerm: + labelSelector: + matchExpressions: + # -- (list) Label key for match expression. + - key: app + # -- (string) Operation type for the match expression. + operator: In + # -- (list) Value for the match expression key. + values: + - ssjdispatcher + # -- (string) Value for topology key label. + topologyKey: "kubernetes.io/hostname" # -- (list) Volumes to attach to the container. volumes: diff --git a/helm/wts/Chart.yaml b/helm/wts/Chart.yaml index 843b47dd..08dd4ab3 100644 --- a/helm/wts/Chart.yaml +++ b/helm/wts/Chart.yaml @@ -15,7 +15,7 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.14 +version: 0.1.15 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to diff --git a/helm/wts/README.md b/helm/wts/README.md index 18eaaf50..00c00b5e 100644 --- a/helm/wts/README.md +++ b/helm/wts/README.md @@ -1,6 +1,6 @@ # wts -![Version: 0.1.14](https://img.shields.io/badge/Version-0.1.14-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) +![Version: 0.1.15](https://img.shields.io/badge/Version-0.1.15-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) A Helm chart for gen3 workspace token service @@ -41,7 +41,7 @@ A Helm chart for gen3 workspace token service | global.kubeBucket | string | `"kube-gen3"` | S3 bucket name for Kubernetes manifest files. | | global.logsBucket | string | `"logs-gen3"` | S3 bucket name for log files. | | global.minAvialable | int | `1` | The minimum amount of pods that are available at all times if the PDB is deployed. | -| global.netPolicy | bool | `true` | Whether network policies are enabled. | +| global.netPolicy | bool | `{"enabled":true}` | Whether network policies are enabled. | | global.pdb | bool | `false` | If the service will be deployed with a Pod Disruption Budget. Note- you need to have more than 2 replicas for the pdb to be deployed. | | global.portalApp | string | `"gitops"` | Portal application name. | | global.postgres.dbCreate | bool | `true` | Whether the database should be created. | @@ -102,3 +102,5 @@ A Helm chart for gen3 workspace token service | serviceAccount.name | string | `""` | The name of the service account to use. If not set and create is true, a name is generated using the fullname template | | tolerations | list | `[]` | Tolerations for the pods | +---------------------------------------------- +Autogenerated from chart metadata using [helm-docs v1.13.1](https://github.com/norwoodj/helm-docs/releases/v1.13.1) diff --git a/helm/wts/values.yaml b/helm/wts/values.yaml index e00aa2fe..0904a496 100644 --- a/helm/wts/values.yaml +++ b/helm/wts/values.yaml @@ -2,7 +2,6 @@ # This is a YAML-formatted file. # Declare variables to be passed into your templates. - # Global configuration global: # -- (map) AWS configuration @@ -50,7 +49,8 @@ global: # -- (string) Access level for tiers. acceptable values for `tier_access_level` are: `libre`, `regular` and `private`. If omitted, by default common will be treated as `private` tierAccessLevel: libre # -- (bool) Whether network policies are enabled. - netPolicy: true + netPolicy: + enabled: true # -- (int) Number of dispatcher jobs. dispatcherJobNum: "10" # -- (bool) If the service will be deployed with a Pod Disruption Budget. Note- you need to have more than 2 replicas for the pdb to be deployed. @@ -140,11 +140,13 @@ serviceAccount: podAnnotations: {} # -- (map) Security context for the pod -podSecurityContext: {} +podSecurityContext: + {} # fsGroup: 2000 # -- (map) Security context for the containers in the pod -securityContext: {} +securityContext: + {} # capabilities: # drop: # - ALL diff --git a/wip/gen3-network-policies/.helmignore b/wip/gen3-network-policies/.helmignore new file mode 100644 index 00000000..0e8a0eb3 --- /dev/null +++ b/wip/gen3-network-policies/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/wip/gen3-network-policies/Chart.yaml b/wip/gen3-network-policies/Chart.yaml new file mode 100644 index 00000000..7bc53bc1 --- /dev/null +++ b/wip/gen3-network-policies/Chart.yaml @@ -0,0 +1,9 @@ +apiVersion: v2 +name: gen3-network-policies +description: A Helm chart that holds network policies needed to run Gen3 + +type: application + +version: 0.1.1 + +appVersion: "0.1.1" diff --git a/wip/gen3-network-policies/templates/_helpers.tpl b/wip/gen3-network-policies/templates/_helpers.tpl new file mode 100644 index 00000000..344fd593 --- /dev/null +++ b/wip/gen3-network-policies/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "gen3-network-policies.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "gen3-network-policies.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "gen3-network-policies.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "gen3-network-policies.labels" -}} +helm.sh/chart: {{ include "gen3-network-policies.chart" . }} +{{ include "gen3-network-policies.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "gen3-network-policies.selectorLabels" -}} +app.kubernetes.io/name: {{ include "gen3-network-policies.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "gen3-network-policies.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "gen3-network-policies.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/wip/gen3-network-policies/templates/allow_nothing_netpolicy.yaml b/wip/gen3-network-policies/templates/allow_nothing_netpolicy.yaml new file mode 100644 index 00000000..749a9b29 --- /dev/null +++ b/wip/gen3-network-policies/templates/allow_nothing_netpolicy.yaml @@ -0,0 +1,11 @@ +kind: NetworkPolicy +apiVersion: networking.k8s.io/v1 +metadata: + name: netpolicy-allow-nothing +spec: + policyTypes: + - Ingress + - Egress + podSelector: {} + ingress: [] + egress: [] diff --git a/wip/gen3-network-policies/templates/allowdns_netpolicy.yaml b/wip/gen3-network-policies/templates/allowdns_netpolicy.yaml new file mode 100644 index 00000000..5fd50016 --- /dev/null +++ b/wip/gen3-network-policies/templates/allowdns_netpolicy.yaml @@ -0,0 +1,19 @@ +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: allowdns-netpolicy +spec: + podSelector: + matchLabels: {} + egress: + - to: + - namespaceSelector: + {} + ports: + - protocol: TCP + port: 53 + - protocol: UDP + port: 53 + + policyTypes: + - Egress diff --git a/wip/gen3-network-policies/templates/argo_workflows_netpolicy.yaml b/wip/gen3-network-policies/templates/argo_workflows_netpolicy.yaml new file mode 100644 index 00000000..1760ddb7 --- /dev/null +++ b/wip/gen3-network-policies/templates/argo_workflows_netpolicy.yaml @@ -0,0 +1,35 @@ +{{- if index .Values "argo-workflows" "enabled" }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: argo-workflows-netpolicy +spec: + podSelector: + matchExpressions: + - key: app + operator: In + values: + - revproxy + - cohort-middleware + - wts + - indexd + ingress: + - from: + - ipBlock: + cidr: 0.0.0.0/0 + ports: + - port: 80 + - port: 4000 + - port: 8080 + - port: 81 + - port: 82 + - port: 443 + egress: + - to: + - namespaceSelector: + matchLabels: + app: argo + policyTypes: + - Ingress + - Egress +{{- end }} \ No newline at end of file diff --git a/wip/gen3-network-policies/templates/argocd_netpolicy.yaml b/wip/gen3-network-policies/templates/argocd_netpolicy.yaml new file mode 100644 index 00000000..a3861e5e --- /dev/null +++ b/wip/gen3-network-policies/templates/argocd_netpolicy.yaml @@ -0,0 +1,34 @@ +{{- if .Values.argocd.enabled }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: argocd-netpolicy +spec: + podSelector: + matchExpressions: + - key: app + operator: In + values: + - revproxy + - cohort-middleware + - wts + ingress: + - from: + - ipBlock: + cidr: 0.0.0.0/0 + ports: + - port: 80 + - port: 4000 + - port: 8080 + - port: 81 + - port: 82 + - port: 443 + egress: + - to: + - namespaceSelector: + matchLabels: + app: argocd + policyTypes: + - Ingress + - Egress +{{- end }} \ No newline at end of file diff --git a/wip/gen3-network-policies/templates/auth_netpolicy.yaml b/wip/gen3-network-policies/templates/auth_netpolicy.yaml new file mode 100644 index 00000000..7b413239 --- /dev/null +++ b/wip/gen3-network-policies/templates/auth_netpolicy.yaml @@ -0,0 +1,27 @@ +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: auth-egress-netpolicy +spec: + egress: + - to: + - podSelector: + matchLabels: + authprovider: "yes" + podSelector: {} + policyTypes: + - Egress +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: netpolicy-auth-ingress +spec: + ingress: + - from: + - podSelector: {} + podSelector: + matchLabels: + authprovider: "yes" + policyTypes: + - Ingress \ No newline at end of file diff --git a/wip/gen3-network-policies/templates/dev_elasticsearch_netpolicy.yaml b/wip/gen3-network-policies/templates/dev_elasticsearch_netpolicy.yaml new file mode 100644 index 00000000..0b544b8e --- /dev/null +++ b/wip/gen3-network-policies/templates/dev_elasticsearch_netpolicy.yaml @@ -0,0 +1,29 @@ +{{- if .Values.global.dev }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: dev-elasticsearch-ingress-netpolicy +spec: + podSelector: + matchLabels: + app: gen3-elasticsearch-master + policyTypes: + - Ingress + ingress: + - from: + - podSelector: {} +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: dev-elasticsearch-egress-netpolicy +spec: + podSelector: {} + policyTypes: + - Egress + egress: + - to: + - podSelector: + matchLabels: + app: gen3-elasticsearch-master +{{- end }} \ No newline at end of file diff --git a/wip/gen3-network-policies/templates/dev_kube_api_netpolicy.yaml b/wip/gen3-network-policies/templates/dev_kube_api_netpolicy.yaml new file mode 100644 index 00000000..85c13912 --- /dev/null +++ b/wip/gen3-network-policies/templates/dev_kube_api_netpolicy.yaml @@ -0,0 +1,18 @@ +# This one needs some explanation. As far as we can tell, on AWS, other network policies allow traffic to reach the +# Kubernetes API. If you're running in another env (such as a local deployment), you'll need this policy to allow access +# to the API server, without knowing ahead of time what the IP address is (since selectors won't work) + +{{- if .Values.global.dev }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: dev-allow-ambassador-egress-netpolicy +spec: + podSelector: + matchLabels: + app: ambassador + policyTypes: + - Egress + egress: + - {} +{{- end }} \ No newline at end of file diff --git a/wip/gen3-network-policies/templates/dev_postgres_netpolicy.yaml b/wip/gen3-network-policies/templates/dev_postgres_netpolicy.yaml new file mode 100644 index 00000000..3ea5de58 --- /dev/null +++ b/wip/gen3-network-policies/templates/dev_postgres_netpolicy.yaml @@ -0,0 +1,29 @@ +{{- if .Values.global.dev }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: dev-postgres-ingress-netpolicy +spec: + podSelector: + matchLabels: + app.kubernetes.io/name: postgresql + policyTypes: + - Ingress + ingress: + - from: + - podSelector: {} +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: dev-postgres-egress-netpolicy +spec: + podSelector: {} + policyTypes: + - Egress + egress: + - to: + - podSelector: + matchLabels: + app.kubernetes.io/name: postgresql +{{- end }} \ No newline at end of file diff --git a/wip/gen3-network-policies/templates/external_egress_netpolicy.yaml b/wip/gen3-network-policies/templates/external_egress_netpolicy.yaml new file mode 100644 index 00000000..5d17ce5a --- /dev/null +++ b/wip/gen3-network-policies/templates/external_egress_netpolicy.yaml @@ -0,0 +1,22 @@ +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: external-egress-netpolicy +spec: + egress: + - to: + - ipBlock: + cidr: 0.0.0.0/0 + except: + - 169.254.0.0/16 + - 172.16.0.0/12 + - 10.0.0.0/8 + # - to: + # - ipBlock: + # # TODO this looks like squid, do we need it? + # cidr: 172.26.225.72/32 + podSelector: + matchLabels: + internet: "yes" + policyTypes: + - Egress \ No newline at end of file diff --git a/wip/gen3-network-policies/templates/gen3job_netpolicy.yaml b/wip/gen3-network-policies/templates/gen3job_netpolicy.yaml new file mode 100644 index 00000000..df6550ed --- /dev/null +++ b/wip/gen3-network-policies/templates/gen3job_netpolicy.yaml @@ -0,0 +1,26 @@ +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: gen3job-netpolicy +spec: + podSelector: + matchLabels: + app: gen3job + egress: + - {} + policyTypes: + - Egress +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: netpolicy-gen3job-in +spec: + podSelector: {} + ingress: + - from: + - podSelector: + matchLabels: + app: gen3job + policyTypes: + - Ingress diff --git a/wip/gen3-network-policies/templates/jh_netpolicy.yaml b/wip/gen3-network-policies/templates/jh_netpolicy.yaml new file mode 100644 index 00000000..82c02509 --- /dev/null +++ b/wip/gen3-network-policies/templates/jh_netpolicy.yaml @@ -0,0 +1,42 @@ +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: jupyter-hub-netpolicy +spec: + podSelector: + matchLabels: + app: jupyter-hub + ingress: + - from: + - podSelector: + matchLabels: + app: revproxy + ports: + - port: 3838 + egress: + - {} + policyTypes: + - Ingress + - Egress +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: jupyter-hub-nb-netpolicy +spec: + podSelector: + matchLabels: + app: jupyterhub + ingress: + - from: + - podSelector: + matchLabels: + app: jupyter-hub + ports: + - {} + egress: + - {} + policyTypes: + - Ingress + - Egress diff --git a/wip/gen3-network-policies/templates/linklocal_netpolicy.yaml b/wip/gen3-network-policies/templates/linklocal_netpolicy.yaml new file mode 100644 index 00000000..aacb0e72 --- /dev/null +++ b/wip/gen3-network-policies/templates/linklocal_netpolicy.yaml @@ -0,0 +1,14 @@ +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: linklocal-netpolicy +spec: + egress: + - to: + - ipBlock: + cidr: 169.254.0.0/16 + podSelector: + matchLabels: + linklocal: "yes" + policyTypes: + - Egress \ No newline at end of file diff --git a/wip/gen3-network-policies/templates/public_service_egress_netpolicy.yaml b/wip/gen3-network-policies/templates/public_service_egress_netpolicy.yaml new file mode 100644 index 00000000..a8d035eb --- /dev/null +++ b/wip/gen3-network-policies/templates/public_service_egress_netpolicy.yaml @@ -0,0 +1,19 @@ +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: general-egress-netpolicy +spec: + egress: + - to: + - podSelector: + matchLabels: + public: "yes" + podSelector: + matchExpressions: + - key: app + operator: In + values: + - revproxy + - ambassador-gen3 + policyTypes: + - Egress diff --git a/wip/gen3-network-policies/templates/s3_netpolicy.yaml b/wip/gen3-network-policies/templates/s3_netpolicy.yaml new file mode 100644 index 00000000..b7ed1303 --- /dev/null +++ b/wip/gen3-network-policies/templates/s3_netpolicy.yaml @@ -0,0 +1,12 @@ +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: s3-netpolicy +spec: + egress: + - to: {{ toYaml .Values.s3CidrRanges | nindent 4}} + podSelector: + matchLabels: + s3: "yes" + policyTypes: + - Egress \ No newline at end of file diff --git a/wip/gen3-network-policies/values.yaml b/wip/gen3-network-policies/values.yaml new file mode 100644 index 00000000..2d97161f --- /dev/null +++ b/wip/gen3-network-policies/values.yaml @@ -0,0 +1,29 @@ +argo-workflows: + enabled: true + +argocd: + enabled: true + +# This is a list of CIDR ranges that may be used by AWS. This is needed +# to allow egress to S3 for services that need it +s3CidrRanges: + - ipBlock: + cidr: 18.34.0.0/19 + - ipBlock: + cidr: 16.15.192.0/18 + - ipBlock: + cidr: 54.231.0.0/16 + - ipBlock: + cidr: 52.216.0.0/15 + - ipBlock: + cidr: 18.34.232.0/21 + - ipBlock: + cidr: 16.15.176.0/20 + - ipBlock: + cidr: 16.182.0.0/16 + - ipBlock: + cidr: 3.5.0.0/19 + - ipBlock: + cidr: 44.192.134.240/28 + - ipBlock: + cidr: 44.192.140.64/28 From 93da1c66f49bacea4b8dc565987e812e6b22107a Mon Sep 17 00:00:00 2001 From: Aidan Hilt Date: Thu, 10 Oct 2024 16:20:33 -0400 Subject: [PATCH 02/11] Adding an s3: yes label to peregrine --- helm/gen3/Chart.yaml | 48 ++++++++++++------------ helm/gen3/README.md | 48 ++++++++++++------------ helm/peregrine/Chart.yaml | 15 ++++---- helm/peregrine/README.md | 2 +- helm/peregrine/templates/deployment.yaml | 1 + 5 files changed, 57 insertions(+), 57 deletions(-) diff --git a/helm/gen3/Chart.yaml b/helm/gen3/Chart.yaml index 4b15d822..75fce98b 100644 --- a/helm/gen3/Chart.yaml +++ b/helm/gen3/Chart.yaml @@ -5,94 +5,94 @@ description: Helm chart to deploy Gen3 Data Commons # Dependencies dependencies: - name: ambassador - version: 0.1.12 + version: 0.1.13 repository: "file://../ambassador" condition: ambassador.enabled - name: arborist - version: 0.1.12 + version: 0.1.13 repository: "file://../arborist" condition: arborist.enabled - name: argo-wrapper - version: 0.1.8 + version: 0.1.9 repository: "file://../argo-wrapper" condition: argo-wrapper.enabled - name: audit - version: 0.1.13 + version: 0.1.14 repository: "file://../audit" condition: audit.enabled - name: aws-es-proxy - version: 0.1.10 + version: 0.1.11 repository: "file://../aws-es-proxy" condition: aws-es-proxy.enabled - name: common - version: 0.1.14 + version: 0.1.15 repository: file://../common - name: etl - version: 0.1.1 + version: 0.1.2 repository: file://../etl condition: etl.enabled - name: frontend-framework - version: 0.1.3 + version: 0.1.4 repository: "file://../frontend-framework" condition: frontend-framework.enabled - name: fence - version: 0.1.23 + version: 0.1.24 repository: "file://../fence" condition: fence.enabled - name: guppy - version: 0.1.13 + version: 0.1.14 repository: "file://../guppy" condition: guppy.enabled - name: hatchery - version: 0.1.10 + version: 0.1.11 repository: "file://../hatchery" condition: hatchery.enabled - name: indexd - version: 0.1.15 + version: 0.1.16 repository: "file://../indexd" condition: indexd.enabled - name: manifestservice - version: 0.1.15 + version: 0.1.16 repository: "file://../manifestservice" condition: manifestservice.enabled - name: metadata - version: 0.1.13 + version: 0.1.14 repository: "file://../metadata" condition: metadata.enabled - name: peregrine - version: 0.1.14 + version: 0.1.15 repository: "file://../peregrine" condition: peregrine.enabled - name: pidgin - version: 0.1.11 + version: 0.1.12 repository: "file://../pidgin" condition: pidgin.enabled - name: portal - version: 0.1.17 + version: 0.1.18 repository: "file://../portal" condition: portal.enabled - name: requestor - version: 0.1.12 + version: 0.1.13 repository: "file://../requestor" condition: requestor.enabled - name: revproxy - version: 0.1.17 + version: 0.1.18 repository: "file://../revproxy" condition: revproxy.enabled - name: sheepdog - version: 0.1.15 + version: 0.1.16 repository: "file://../sheepdog" condition: sheepdog.enabled - name: ssjdispatcher - version: 0.1.11 + version: 0.1.12 repository: "file://../ssjdispatcher" condition: ssjdispatcher.enabled - name: sower - version: 0.1.13 + version: 0.1.14 condition: sower.enabled repository: "file://../sower" - name: wts - version: 0.1.14 + version: 0.1.15 repository: "file://../wts" condition: wts.enabled - name: gen3-network-policies @@ -115,7 +115,7 @@ dependencies: # Reference: https://github.com/neuvector/neuvector-helm # For more information, please use the Gen3 community Slack. - name: neuvector - version: "0.1.0" + version: "0.1.1" repository: "file://../neuvector" condition: neuvector.enabled diff --git a/helm/gen3/README.md b/helm/gen3/README.md index f8556fa3..3b5ac0df 100644 --- a/helm/gen3/README.md +++ b/helm/gen3/README.md @@ -19,30 +19,30 @@ Helm chart to deploy Gen3 Data Commons | Repository | Name | Version | |------------|------|---------| | file://../../wip/gen3-network-policies | gen3-network-policies | 0.1.1 | -| file://../ambassador | ambassador | 0.1.12 | -| file://../arborist | arborist | 0.1.12 | -| file://../argo-wrapper | argo-wrapper | 0.1.8 | -| file://../audit | audit | 0.1.13 | -| file://../aws-es-proxy | aws-es-proxy | 0.1.10 | -| file://../common | common | 0.1.14 | -| file://../etl | etl | 0.1.1 | -| file://../fence | fence | 0.1.23 | -| file://../frontend-framework | frontend-framework | 0.1.3 | -| file://../guppy | guppy | 0.1.13 | -| file://../hatchery | hatchery | 0.1.10 | -| file://../indexd | indexd | 0.1.15 | -| file://../manifestservice | manifestservice | 0.1.15 | -| file://../metadata | metadata | 0.1.13 | -| file://../neuvector | neuvector | 0.1.0 | -| file://../peregrine | peregrine | 0.1.14 | -| file://../pidgin | pidgin | 0.1.11 | -| file://../portal | portal | 0.1.17 | -| file://../requestor | requestor | 0.1.12 | -| file://../revproxy | revproxy | 0.1.17 | -| file://../sheepdog | sheepdog | 0.1.15 | -| file://../sower | sower | 0.1.13 | -| file://../ssjdispatcher | ssjdispatcher | 0.1.11 | -| file://../wts | wts | 0.1.14 | +| file://../ambassador | ambassador | 0.1.13 | +| file://../arborist | arborist | 0.1.13 | +| file://../argo-wrapper | argo-wrapper | 0.1.9 | +| file://../audit | audit | 0.1.14 | +| file://../aws-es-proxy | aws-es-proxy | 0.1.11 | +| file://../common | common | 0.1.15 | +| file://../etl | etl | 0.1.2 | +| file://../fence | fence | 0.1.24 | +| file://../frontend-framework | frontend-framework | 0.1.4 | +| file://../guppy | guppy | 0.1.14 | +| file://../hatchery | hatchery | 0.1.11 | +| file://../indexd | indexd | 0.1.16 | +| file://../manifestservice | manifestservice | 0.1.16 | +| file://../metadata | metadata | 0.1.14 | +| file://../neuvector | neuvector | 0.1.1 | +| file://../peregrine | peregrine | 0.1.15 | +| file://../pidgin | pidgin | 0.1.12 | +| file://../portal | portal | 0.1.18 | +| file://../requestor | requestor | 0.1.13 | +| file://../revproxy | revproxy | 0.1.18 | +| file://../sheepdog | sheepdog | 0.1.16 | +| file://../sower | sower | 0.1.14 | +| file://../ssjdispatcher | ssjdispatcher | 0.1.12 | +| file://../wts | wts | 0.1.15 | | https://charts.bitnami.com/bitnami | postgresql | 11.9.13 | | https://helm.elastic.co | elasticsearch | 7.10.2 | diff --git a/helm/peregrine/Chart.yaml b/helm/peregrine/Chart.yaml index 24be0632..58ea23bf 100644 --- a/helm/peregrine/Chart.yaml +++ b/helm/peregrine/Chart.yaml @@ -23,12 +23,11 @@ version: 0.1.15 # It is recommended to use it with quotes. appVersion: "master" - dependencies: -- name: common - version: 0.1.14 - repository: file://../common -- name: postgresql - version: 11.9.13 - repository: "https://charts.bitnami.com/bitnami" - condition: postgres.separate + - name: common + version: 0.1.15 + repository: file://../common + - name: postgresql + version: 11.9.13 + repository: "https://charts.bitnami.com/bitnami" + condition: postgres.separate diff --git a/helm/peregrine/README.md b/helm/peregrine/README.md index fcb545cd..4473e7ad 100644 --- a/helm/peregrine/README.md +++ b/helm/peregrine/README.md @@ -8,7 +8,7 @@ A Helm chart for gen3 Peregrine service | Repository | Name | Version | |------------|------|---------| -| file://../common | common | 0.1.14 | +| file://../common | common | 0.1.15 | | https://charts.bitnami.com/bitnami | postgresql | 11.9.13 | ## Values diff --git a/helm/peregrine/templates/deployment.yaml b/helm/peregrine/templates/deployment.yaml index 978b5a68..13ba70b9 100644 --- a/helm/peregrine/templates/deployment.yaml +++ b/helm/peregrine/templates/deployment.yaml @@ -21,6 +21,7 @@ spec: {{- include "common.grafanaAnnotations" . | nindent 8 }} {{- end }} labels: + s3: "yes" {{- include "peregrine.selectorLabels" . | nindent 8 }} {{- include "common.extraLabels" . | nindent 8 }} spec: From e46520da65d3740288b834fb4140e3b5d551ead3 Mon Sep 17 00:00:00 2001 From: Aidan Hilt Date: Thu, 10 Oct 2024 17:00:00 -0400 Subject: [PATCH 03/11] Fixing typo in ssjdispatcher's netpolicy --- helm/ssjdispatcher/templates/netpolicy.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helm/ssjdispatcher/templates/netpolicy.yaml b/helm/ssjdispatcher/templates/netpolicy.yaml index 5eb0d850..5d40eb9d 100644 --- a/helm/ssjdispatcher/templates/netpolicy.yaml +++ b/helm/ssjdispatcher/templates/netpolicy.yaml @@ -1,4 +1,4 @@ -{{- if .Values.ssjdispatcher.enabled }} +{{- if .Values.global.netpolicy.enabled }} apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: From a04f928ba819c50687b237ed772d280c724d3d1f Mon Sep 17 00:00:00 2001 From: Aidan Hilt Date: Thu, 10 Oct 2024 17:07:55 -0400 Subject: [PATCH 04/11] Updating netpolicy names --- helm/revproxy/templates/netpolicy.yaml | 2 +- helm/sower/templates/netpolicy.yaml | 2 +- helm/ssjdispatcher/templates/netpolicy.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/helm/revproxy/templates/netpolicy.yaml b/helm/revproxy/templates/netpolicy.yaml index 7db06ee7..8b191a95 100644 --- a/helm/revproxy/templates/netpolicy.yaml +++ b/helm/revproxy/templates/netpolicy.yaml @@ -9,7 +9,7 @@ apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: - name: netpolicy-revproxy + name: revproxy-netpolicy spec: podSelector: matchExpressions: diff --git a/helm/sower/templates/netpolicy.yaml b/helm/sower/templates/netpolicy.yaml index 82813feb..d0e949e1 100644 --- a/helm/sower/templates/netpolicy.yaml +++ b/helm/sower/templates/netpolicy.yaml @@ -9,7 +9,7 @@ apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: - name: netpolicy-sowerjob + name: sowerjob-netpolicy spec: podSelector: matchLabels: diff --git a/helm/ssjdispatcher/templates/netpolicy.yaml b/helm/ssjdispatcher/templates/netpolicy.yaml index 5d40eb9d..772cefc6 100644 --- a/helm/ssjdispatcher/templates/netpolicy.yaml +++ b/helm/ssjdispatcher/templates/netpolicy.yaml @@ -2,7 +2,7 @@ apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: - name: netpolicy-ssjdispatcherjob + name: ssjdispatcherjob-netpolicy spec: podSelector: matchLabels: From 3d2f2b09e2063295d562202440cd59da5f01e8fd Mon Sep 17 00:00:00 2001 From: Aidan Hilt Date: Thu, 10 Oct 2024 18:07:57 -0400 Subject: [PATCH 05/11] Figured out why things weren't working, so blocked some stuff behind a feature flag, and cleaned up some values files elsewhere --- helm/common/README.md | 4 +++- helm/common/templates/_netpolicy_templates.tpl | 10 ++++++---- helm/common/values.yaml | 6 +++++- helm/revproxy/templates/netpolicy.yaml | 4 +++- helm/sower/templates/netpolicy.yaml | 2 ++ helm/ssjdispatcher/templates/netpolicy.yaml | 2 +- 6 files changed, 20 insertions(+), 8 deletions(-) diff --git a/helm/common/README.md b/helm/common/README.md index 1ff085b1..e120cef9 100644 --- a/helm/common/README.md +++ b/helm/common/README.md @@ -18,7 +18,9 @@ A Helm chart for provisioning databases in gen3 | global.hostname | string | `"localhost"` | Hostname for the deployment. | | global.kubeBucket | string | `"kube-gen3"` | S3 bucket name for Kubernetes manifest files. | | global.logsBucket | string | `"logs-gen3"` | S3 bucket name for log files. | -| global.netPolicy | bool | `{"enabled":true}` | Whether network policies are enabled. | +| global.netPolicy | map | `{"dbSubnets":[],"enabled":true}` | Configuration for network policies. | +| global.netPolicy.dbSubnets | array | `[]` | A list of subnets where databases reside. This is to enable access in production environments | +| global.netPolicy.enabled | bool | `true` | Whether or not to apply netpolicies | | global.portalApp | string | `"gitops"` | Portal application name. | | global.postgres.dbCreate | bool | `true` | Whether the database should be created. | | global.postgres.externalSecret | string | `""` | Name of external secret. Disabled if empty | diff --git a/helm/common/templates/_netpolicy_templates.tpl b/helm/common/templates/_netpolicy_templates.tpl index 267134f1..9613db41 100644 --- a/helm/common/templates/_netpolicy_templates.tpl +++ b/helm/common/templates/_netpolicy_templates.tpl @@ -2,23 +2,25 @@ Templates for network policies that can be used by various subcharts */}} -{{ define "common.db_netpolicy" -}} - {{- if .Values.global.netPolicy.enabled }} +{{- define "common.db_netpolicy" -}} + {{- if .Values.global.netPolicy.enabled }} apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: {{ .Chart.Name }}-db-netpolicy spec: egress: + {{- range .Values.global.netPolicy.dbSubnets }} - to: - ipBlock: - cidr: {{ .Values.global.netPolicy.dbSubnet }} + cidr: {{ . }} + {{- end }} podSelector: matchLabels: app: {{ .Chart.Name }} policyTypes: - Egress - {{- end }} + {{- end }} {{- end }} {{ define "common.ingress_netpolicy" -}} diff --git a/helm/common/values.yaml b/helm/common/values.yaml index 19feb2e4..c30dfc91 100644 --- a/helm/common/values.yaml +++ b/helm/common/values.yaml @@ -44,9 +44,13 @@ global: publicDataSets: true # -- (string) Access level for tiers. acceptable values for `tier_access_level` are: `libre`, `regular` and `private`. If omitted, by default common will be treated as `private` tierAccessLevel: libre - # -- (bool) Whether network policies are enabled. + # -- (map) Configuration for network policies. netPolicy: + # -- (bool) Whether or not to apply netpolicies enabled: true + + # -- (array) A list of subnets where databases reside. This is to enable access in production environments + dbSubnets: [] # -- (int) Number of dispatcher jobs. dispatcherJobNum: "10" # -- (bool) Whether Datadog is enabled. diff --git a/helm/revproxy/templates/netpolicy.yaml b/helm/revproxy/templates/netpolicy.yaml index 8b191a95..1c7bd36c 100644 --- a/helm/revproxy/templates/netpolicy.yaml +++ b/helm/revproxy/templates/netpolicy.yaml @@ -6,6 +6,7 @@ --- +{{- if .Values.global.netPolicy.enabled }} apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: @@ -56,4 +57,5 @@ spec: app: argocd policyTypes: - Ingress - - Egress \ No newline at end of file + - Egress +{{- end }} \ No newline at end of file diff --git a/helm/sower/templates/netpolicy.yaml b/helm/sower/templates/netpolicy.yaml index d0e949e1..227f111c 100644 --- a/helm/sower/templates/netpolicy.yaml +++ b/helm/sower/templates/netpolicy.yaml @@ -6,6 +6,7 @@ --- +{{- if .Values.global.netPolicy.enabled }} apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: @@ -18,3 +19,4 @@ spec: - {} policyTypes: - Egress +{{- end }} diff --git a/helm/ssjdispatcher/templates/netpolicy.yaml b/helm/ssjdispatcher/templates/netpolicy.yaml index 772cefc6..2e8a29a0 100644 --- a/helm/ssjdispatcher/templates/netpolicy.yaml +++ b/helm/ssjdispatcher/templates/netpolicy.yaml @@ -1,4 +1,4 @@ -{{- if .Values.global.netpolicy.enabled }} +{{- if .Values.global.netPolicy.enabled }} apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: From f554b73f653d24a7b9c652b1813dbf31a4ef7b46 Mon Sep 17 00:00:00 2001 From: Aidan Hilt Date: Fri, 11 Oct 2024 17:15:07 -0400 Subject: [PATCH 06/11] Updating some labels for network policies --- .secrets.baseline | 10 ++- helm/ambassador/templates/deployment.yaml | 3 + helm/arborist/templates/deployment.yaml | 3 + helm/fence/templates/fence-deployment.yaml | 3 + helm/fence/templates/presigned-url-fence.yaml | 6 +- helm/hatchery/templates/deployment.yaml | 3 + helm/indexd/templates/deployment.yaml | 1 + .../manifestservice/templates/deployment.yaml | 6 +- helm/metadata/templates/deployment.yaml | 7 +- helm/peregrine/templates/deployment.yaml | 1 + helm/portal/templates/deployment.yaml | 2 +- helm/sheepdog/templates/deployment.yaml | 8 +- helm/sower/templates/deployment.yaml | 6 +- helm/ssjdispatcher/templates/deployment.yaml | 4 +- helm/wts/templates/deployment.yaml | 6 +- .../templates/allow_nothing_netpolicy.yaml | 2 +- .../templates/auth_netpolicy.yaml | 2 +- .../templates/gen3job_netpolicy.yaml | 2 +- .../templates/public_netpolicy.yaml | 89 +++++++++++++++++++ .../public_service_egress_netpolicy.yaml | 19 ---- 20 files changed, 137 insertions(+), 46 deletions(-) create mode 100644 wip/gen3-network-policies/templates/public_netpolicy.yaml delete mode 100644 wip/gen3-network-policies/templates/public_service_egress_netpolicy.yaml diff --git a/.secrets.baseline b/.secrets.baseline index 28da4aa2..7e7a2e7b 100644 --- a/.secrets.baseline +++ b/.secrets.baseline @@ -90,6 +90,10 @@ { "path": "detect_secrets.filters.allowlist.is_line_allowlisted" }, + { + "path": "detect_secrets.filters.common.is_baseline_file", + "filename": ".secrets.baseline" + }, { "path": "detect_secrets.filters.common.is_ignored_due_to_verification_policies", "min_level": 2 @@ -467,14 +471,14 @@ "filename": "helm/metadata/templates/deployment.yaml", "hashed_secret": "e14f65c8ca7f3b27a0f0f5463569954841e162c9", "is_verified": false, - "line_number": 41 + "line_number": 40 }, { "type": "Secret Keyword", "filename": "helm/metadata/templates/deployment.yaml", "hashed_secret": "c27babf45eb0ed87329e69c7d47dba611e859c5d", "is_verified": false, - "line_number": 44 + "line_number": 43 } ], "helm/metadata/templates/external-secret.yaml": [ @@ -833,5 +837,5 @@ } ] }, - "generated_at": "2024-10-09T21:29:00Z" + "generated_at": "2024-10-11T21:14:31Z" } diff --git a/helm/ambassador/templates/deployment.yaml b/helm/ambassador/templates/deployment.yaml index 8b2cb2d8..6caaa168 100644 --- a/helm/ambassador/templates/deployment.yaml +++ b/helm/ambassador/templates/deployment.yaml @@ -21,6 +21,9 @@ spec: {{- include "common.grafanaAnnotations" . | nindent 8 }} {{- end }} labels: + netnolimit: "yes" + public: "yes" + userhelper: "yes" {{- include "ambassador.selectorLabels" . | nindent 8 }} {{- include "common.extraLabels" . | nindent 8 }} spec: diff --git a/helm/arborist/templates/deployment.yaml b/helm/arborist/templates/deployment.yaml index 4b31f3a5..4f04a80b 100644 --- a/helm/arborist/templates/deployment.yaml +++ b/helm/arborist/templates/deployment.yaml @@ -21,6 +21,9 @@ spec: {{- include "common.grafanaAnnotations" . | nindent 8 }} {{- end }} labels: + authprovider: "yes" + dbarborist: "yes" + public: "yes" {{- include "arborist.selectorLabels" . | nindent 8 }} {{- include "common.extraLabels" . | nindent 8 }} spec: diff --git a/helm/fence/templates/fence-deployment.yaml b/helm/fence/templates/fence-deployment.yaml index ba4ad72c..09484c52 100644 --- a/helm/fence/templates/fence-deployment.yaml +++ b/helm/fence/templates/fence-deployment.yaml @@ -21,6 +21,9 @@ spec: {{- include "common.grafanaAnnotations" . | nindent 8 }} {{- end }} labels: + authprovider: "yes" + netnolimit: "yes" + userhelper: "yes" {{- include "fence.selectorLabels" . | nindent 8 }} {{- include "common.extraLabels" . | nindent 8 }} spec: diff --git a/helm/fence/templates/presigned-url-fence.yaml b/helm/fence/templates/presigned-url-fence.yaml index a4c5628f..3bb3d568 100644 --- a/helm/fence/templates/presigned-url-fence.yaml +++ b/helm/fence/templates/presigned-url-fence.yaml @@ -21,7 +21,11 @@ spec: {{- include "common.grafanaAnnotations" . | nindent 8 }} {{- end }} labels: - app: presigned-url-fence + app: "presigned-url-fence" + authprovder: "yes" + netnolimit: "yes" + public: "yes" + userhelper: "yes" spec: serviceAccountName: {{ include "fence.serviceAccountName" . }} volumes: diff --git a/helm/hatchery/templates/deployment.yaml b/helm/hatchery/templates/deployment.yaml index 4a22be93..81ae84aa 100644 --- a/helm/hatchery/templates/deployment.yaml +++ b/helm/hatchery/templates/deployment.yaml @@ -21,6 +21,9 @@ spec: {{- include "common.grafanaAnnotations" . | nindent 8 }} {{- end }} labels: + netnolimit: "yes" + public: "yes" + userhelper: "yes" {{- include "hatchery.selectorLabels" . | nindent 8 }} {{- include "common.extraLabels" . | nindent 8 }} spec: diff --git a/helm/indexd/templates/deployment.yaml b/helm/indexd/templates/deployment.yaml index 85656b54..cbb05552 100644 --- a/helm/indexd/templates/deployment.yaml +++ b/helm/indexd/templates/deployment.yaml @@ -21,6 +21,7 @@ spec: {{- include "common.grafanaAnnotations" . | nindent 8 }} {{- end }} labels: + public: "yes" {{- include "indexd.selectorLabels" . | nindent 8 }} {{- include "common.extraLabels" . | nindent 8 }} spec: diff --git a/helm/manifestservice/templates/deployment.yaml b/helm/manifestservice/templates/deployment.yaml index 7c2cee70..9c362f6a 100644 --- a/helm/manifestservice/templates/deployment.yaml +++ b/helm/manifestservice/templates/deployment.yaml @@ -17,11 +17,11 @@ spec: template: metadata: labels: - {{- include "manifestservice.selectorLabels" . | nindent 8 }} - {{- include "common.extraLabels" . | nindent 8 }} - s3: "yes" public: "yes" + s3: "yes" userhelper: "yes" + {{- include "manifestservice.selectorLabels" . | nindent 8 }} + {{- include "common.extraLabels" . | nindent 8 }} annotations: {{- if .Values.metricsEnabled }} {{- include "common.grafanaAnnotations" . | nindent 8 }} diff --git a/helm/metadata/templates/deployment.yaml b/helm/metadata/templates/deployment.yaml index a8ec17ad..58e06603 100644 --- a/helm/metadata/templates/deployment.yaml +++ b/helm/metadata/templates/deployment.yaml @@ -19,12 +19,11 @@ spec: template: metadata: labels: + netnolimit: "yes" + public: "yes" + userhelper: "yes" {{- include "metadata.selectorLabels" . | nindent 8 }} {{- include "common.extraLabels" . | nindent 8 }} - # gen3 networkpolicy labels - netnolimit: 'yes' - public: 'yes' - userhelper: 'yes' annotations: {{- if .Values.metricsEnabled }} {{- include "common.grafanaAnnotations" . | nindent 8 }} diff --git a/helm/peregrine/templates/deployment.yaml b/helm/peregrine/templates/deployment.yaml index 13ba70b9..b56eca44 100644 --- a/helm/peregrine/templates/deployment.yaml +++ b/helm/peregrine/templates/deployment.yaml @@ -21,6 +21,7 @@ spec: {{- include "common.grafanaAnnotations" . | nindent 8 }} {{- end }} labels: + public: "yes" s3: "yes" {{- include "peregrine.selectorLabels" . | nindent 8 }} {{- include "common.extraLabels" . | nindent 8 }} diff --git a/helm/portal/templates/deployment.yaml b/helm/portal/templates/deployment.yaml index 4ca45131..2445821f 100644 --- a/helm/portal/templates/deployment.yaml +++ b/helm/portal/templates/deployment.yaml @@ -24,9 +24,9 @@ spec: {{- include "common.grafanaAnnotations" . | nindent 8 }} {{- end }} labels: + public: "yes" {{- include "portal.selectorLabels" . | nindent 8 }} {{- include "common.extraLabels" . | nindent 8 }} - public: "yes" spec: {{- with .Values.nodeSelector }} nodeSelector: diff --git a/helm/sheepdog/templates/deployment.yaml b/helm/sheepdog/templates/deployment.yaml index 296595db..e7d11c17 100644 --- a/helm/sheepdog/templates/deployment.yaml +++ b/helm/sheepdog/templates/deployment.yaml @@ -23,12 +23,12 @@ spec: template: metadata: labels: + # gen3 networkpolicy labels + public: "yes" + netnolimit: "yes" + s3: "yes" {{- include "sheepdog.selectorLabels" . | nindent 8 }} {{- include "common.extraLabels" . | nindent 8 }} - # gen3 networkpolicy labels - netnolimit: 'yes' - public: 'yes' - s3: 'yes' annotations: {{- if .Values.metricsEnabled }} {{- include "common.grafanaAnnotations" . | nindent 8 }} diff --git a/helm/sower/templates/deployment.yaml b/helm/sower/templates/deployment.yaml index e051994d..456c6cca 100644 --- a/helm/sower/templates/deployment.yaml +++ b/helm/sower/templates/deployment.yaml @@ -16,10 +16,10 @@ spec: template: metadata: labels: - {{- include "sower.selectorLabels" . | nindent 8 }} - {{- include "common.extraLabels" . | nindent 8 }} - public: "yes" netnolimit: "yes" + public: "yes" + {{- include "sower.selectorLabels" . | nindent 8 }} + {{- include "common.extraLabels" . | nindent 8 }} annotations: {{- if .Values.metricsEnabled }} {{- include "common.grafanaAnnotations" . | nindent 8 }} diff --git a/helm/ssjdispatcher/templates/deployment.yaml b/helm/ssjdispatcher/templates/deployment.yaml index f54e3029..7d03f7fa 100644 --- a/helm/ssjdispatcher/templates/deployment.yaml +++ b/helm/ssjdispatcher/templates/deployment.yaml @@ -14,10 +14,10 @@ spec: template: metadata: labels: - {{- include "ssjdispatcher.selectorLabels" . | nindent 8 }} - {{- include "common.extraLabels" . | nindent 8 }} netnolimit: "yes" public: "yes" + {{- include "ssjdispatcher.selectorLabels" . | nindent 8 }} + {{- include "common.extraLabels" . | nindent 8 }} annotations: {{- if .Values.metricsEnabled }} {{- include "common.grafanaAnnotations" . | nindent 8 }} diff --git a/helm/wts/templates/deployment.yaml b/helm/wts/templates/deployment.yaml index 464607e9..eaa5d4e5 100644 --- a/helm/wts/templates/deployment.yaml +++ b/helm/wts/templates/deployment.yaml @@ -30,11 +30,11 @@ spec: {{- include "common.grafanaAnnotations" . | nindent 8 }} {{- end }} labels: - {{- include "wts.selectorLabels" . | nindent 8 }} - {{- include "common.extraLabels" . | nindent 8 }} - public: "yes" netnolimit: "yes" + public: "yes" userhelper: "yes" + {{- include "wts.selectorLabels" . | nindent 8 }} + {{- include "common.extraLabels" . | nindent 8 }} spec: affinity: podAntiAffinity: diff --git a/wip/gen3-network-policies/templates/allow_nothing_netpolicy.yaml b/wip/gen3-network-policies/templates/allow_nothing_netpolicy.yaml index 749a9b29..387cac04 100644 --- a/wip/gen3-network-policies/templates/allow_nothing_netpolicy.yaml +++ b/wip/gen3-network-policies/templates/allow_nothing_netpolicy.yaml @@ -1,7 +1,7 @@ kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: - name: netpolicy-allow-nothing + name: allow-nothing-netpolicy spec: policyTypes: - Ingress diff --git a/wip/gen3-network-policies/templates/auth_netpolicy.yaml b/wip/gen3-network-policies/templates/auth_netpolicy.yaml index 7b413239..28f96a83 100644 --- a/wip/gen3-network-policies/templates/auth_netpolicy.yaml +++ b/wip/gen3-network-policies/templates/auth_netpolicy.yaml @@ -15,7 +15,7 @@ spec: apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: - name: netpolicy-auth-ingress + name: auth-ingress-netpolicy spec: ingress: - from: diff --git a/wip/gen3-network-policies/templates/gen3job_netpolicy.yaml b/wip/gen3-network-policies/templates/gen3job_netpolicy.yaml index df6550ed..f4d7317d 100644 --- a/wip/gen3-network-policies/templates/gen3job_netpolicy.yaml +++ b/wip/gen3-network-policies/templates/gen3job_netpolicy.yaml @@ -14,7 +14,7 @@ spec: apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: - name: netpolicy-gen3job-in + name: gen3job-in-netpolicy spec: podSelector: {} ingress: diff --git a/wip/gen3-network-policies/templates/public_netpolicy.yaml b/wip/gen3-network-policies/templates/public_netpolicy.yaml new file mode 100644 index 00000000..f06683a8 --- /dev/null +++ b/wip/gen3-network-policies/templates/public_netpolicy.yaml @@ -0,0 +1,89 @@ +qureshi@cdistestdevadmin:~/gen3-helm/helm/gen3$ kubectl get networkpolicies +NAME POD-SELECTOR AGE +allowdns-netpolicy 21m +arborist-db-netpolicy app=arborist 21m +argo-workflows-netpolicy app in (cohort-middleware,indexd,revproxy,wts) 21m +argocd-netpolicy app in (cohort-middleware,revproxy,wts) 21m +auth-egress-netpolicy 21m +aws-es-proxy-egress-netpolicy app in (arranger,arranger-dashboard,arranger-server,guppy,metadata,spark,tube) 21m +aws-es-proxy-ingress-netpolicy app=aws-es-proxy 21m +external-egress-netpolicy internet=yes 12m +fence-db-netpolicy app=fence 21m +gen3job-netpolicy app=gen3job 21m +general-egress-netpolicy app in (ambassador-gen3,revproxy) 21m +indexd-db-netpolicy app=indexd 21m +indexd-egress-netpolicy app in (fence,fenceshib,mariner,mariner-engine,metadata,peregrine,presigned-url-fence,sheepdog,ssjdispatcherjob) 21m +indexd-ingress-netpolicy app=indexd 21m +jupyter-hub-nb-netpolicy app=jupyterhub 21m +jupyter-hub-netpolicy app=jupyter-hub 21m +linklocal-netpolicy linklocal=yes 13m +metadata-db-netpolicy app=metadata 21m +netpolicy-allow-nothing 13m +netpolicy-auth-ingress authprovider=yes 21m +netpolicy-gen3job-in 21m +peregrine-db-netpolicy app=peregrine 21m +peregrine-egress-netpolicy app in (pidgin) 21m +peregrine-ingress-netpolicy app=peregrine 21m +revproxy-egress-netpolicy app in (portal,sowerjob) 21m +revproxy-ingress-netpolicy app=revproxy 21m +revproxy-netpolicy app in (ambassador-gen3,auspice,ohdsi-atlas,ohdsi-webapi,revproxy,superset,superset-redis-master,superset-worker) 21m +s3-netpolicy s3=yes 21m +sheepdog-db-netpolicy app=sheepdog 21m +ssjdispatcherjob-netpolicy app=ssjdispatcherjob 21m +qureshi@cdistestdevadmin:~/gen3-helm/helm/gen3$ cd +qureshi@cdistestdevadmin:~$ vi +qureshi@cdistestdevadmin:~$ vi cloud-automation^C +qureshi@cdistestdevadmin:~$ vi cloud-automation/kube/services/netpolicy/ +base/ gen3/ README.md user/ +qureshi@cdistestdevadmin:~$ vi cloud-automation/kube/services/netpolicy/base/ +allowdns_netpolicy.yaml allow_nothing_netpolicy.yaml metrics_netpolicy.yaml README.md +qureshi@cdistestdevadmin:~$ vi cloud-automation/kube/services/netpolicy/gen3/ +auth_netpolicy.yaml nolimit_netpolicy.yaml README.md userhelper_netpolicy.yaml +linklocal_netpolicy.yaml public_netpolicy.yaml services/ vpc_netpolicy.yaml +qureshi@cdistestdevadmin:~$ vi cloud-automation/kube/services/netpolicy/gen3/public_netpolicy.yaml + + + + + + + +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: public-ingress-to-netpolicy +spec: + podSelector: + matchLabels: + public: "yes" + ingress: + - from: + - podSelector: + matchLabels: + app: revproxy + - podSelector: + matchLabels: + app: ambassador-gen3 + policyTypes: + - Ingress +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: public-egress-to-netpolicy +spec: + podSelector: + matchExpressions: + - key: app + operator: In + values: + - revproxy + - ambassador-gen3 + egress: + - to: + - podSelector: + matchLabels: + public: "yes" + policyTypes: + - Egress diff --git a/wip/gen3-network-policies/templates/public_service_egress_netpolicy.yaml b/wip/gen3-network-policies/templates/public_service_egress_netpolicy.yaml deleted file mode 100644 index a8d035eb..00000000 --- a/wip/gen3-network-policies/templates/public_service_egress_netpolicy.yaml +++ /dev/null @@ -1,19 +0,0 @@ -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - name: general-egress-netpolicy -spec: - egress: - - to: - - podSelector: - matchLabels: - public: "yes" - podSelector: - matchExpressions: - - key: app - operator: In - values: - - revproxy - - ambassador-gen3 - policyTypes: - - Egress From 3e32c17862ede046c56281136ce18e142370e9ab Mon Sep 17 00:00:00 2001 From: Aidan Hilt Date: Fri, 11 Oct 2024 17:27:50 -0400 Subject: [PATCH 07/11] Do not understand how that happened --- .../templates/public_netpolicy.yaml | 51 ------------------- 1 file changed, 51 deletions(-) diff --git a/wip/gen3-network-policies/templates/public_netpolicy.yaml b/wip/gen3-network-policies/templates/public_netpolicy.yaml index f06683a8..a6364e7c 100644 --- a/wip/gen3-network-policies/templates/public_netpolicy.yaml +++ b/wip/gen3-network-policies/templates/public_netpolicy.yaml @@ -1,54 +1,3 @@ -qureshi@cdistestdevadmin:~/gen3-helm/helm/gen3$ kubectl get networkpolicies -NAME POD-SELECTOR AGE -allowdns-netpolicy 21m -arborist-db-netpolicy app=arborist 21m -argo-workflows-netpolicy app in (cohort-middleware,indexd,revproxy,wts) 21m -argocd-netpolicy app in (cohort-middleware,revproxy,wts) 21m -auth-egress-netpolicy 21m -aws-es-proxy-egress-netpolicy app in (arranger,arranger-dashboard,arranger-server,guppy,metadata,spark,tube) 21m -aws-es-proxy-ingress-netpolicy app=aws-es-proxy 21m -external-egress-netpolicy internet=yes 12m -fence-db-netpolicy app=fence 21m -gen3job-netpolicy app=gen3job 21m -general-egress-netpolicy app in (ambassador-gen3,revproxy) 21m -indexd-db-netpolicy app=indexd 21m -indexd-egress-netpolicy app in (fence,fenceshib,mariner,mariner-engine,metadata,peregrine,presigned-url-fence,sheepdog,ssjdispatcherjob) 21m -indexd-ingress-netpolicy app=indexd 21m -jupyter-hub-nb-netpolicy app=jupyterhub 21m -jupyter-hub-netpolicy app=jupyter-hub 21m -linklocal-netpolicy linklocal=yes 13m -metadata-db-netpolicy app=metadata 21m -netpolicy-allow-nothing 13m -netpolicy-auth-ingress authprovider=yes 21m -netpolicy-gen3job-in 21m -peregrine-db-netpolicy app=peregrine 21m -peregrine-egress-netpolicy app in (pidgin) 21m -peregrine-ingress-netpolicy app=peregrine 21m -revproxy-egress-netpolicy app in (portal,sowerjob) 21m -revproxy-ingress-netpolicy app=revproxy 21m -revproxy-netpolicy app in (ambassador-gen3,auspice,ohdsi-atlas,ohdsi-webapi,revproxy,superset,superset-redis-master,superset-worker) 21m -s3-netpolicy s3=yes 21m -sheepdog-db-netpolicy app=sheepdog 21m -ssjdispatcherjob-netpolicy app=ssjdispatcherjob 21m -qureshi@cdistestdevadmin:~/gen3-helm/helm/gen3$ cd -qureshi@cdistestdevadmin:~$ vi -qureshi@cdistestdevadmin:~$ vi cloud-automation^C -qureshi@cdistestdevadmin:~$ vi cloud-automation/kube/services/netpolicy/ -base/ gen3/ README.md user/ -qureshi@cdistestdevadmin:~$ vi cloud-automation/kube/services/netpolicy/base/ -allowdns_netpolicy.yaml allow_nothing_netpolicy.yaml metrics_netpolicy.yaml README.md -qureshi@cdistestdevadmin:~$ vi cloud-automation/kube/services/netpolicy/gen3/ -auth_netpolicy.yaml nolimit_netpolicy.yaml README.md userhelper_netpolicy.yaml -linklocal_netpolicy.yaml public_netpolicy.yaml services/ vpc_netpolicy.yaml -qureshi@cdistestdevadmin:~$ vi cloud-automation/kube/services/netpolicy/gen3/public_netpolicy.yaml - - - - - - - ---- apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: From 34cf0f80cbf4cbe96f276eba35824108cc443dfb Mon Sep 17 00:00:00 2001 From: Aidan Hilt Date: Wed, 16 Oct 2024 14:17:08 -0400 Subject: [PATCH 08/11] Well, that was embarassing --- .../templates/nolimit_netpolicy.yaml | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 wip/gen3-network-policies/templates/nolimit_netpolicy.yaml diff --git a/wip/gen3-network-policies/templates/nolimit_netpolicy.yaml b/wip/gen3-network-policies/templates/nolimit_netpolicy.yaml new file mode 100644 index 00000000..5bcd33bd --- /dev/null +++ b/wip/gen3-network-policies/templates/nolimit_netpolicy.yaml @@ -0,0 +1,12 @@ +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: netpolicy-nolimit +spec: + egress: + - {} + podSelector: + matchLabels: + netnolimit: "yes" + policyTypes: + - Egress \ No newline at end of file From 5a0f7b3e3204bb12498e67ee2db63de4f5cd2b22 Mon Sep 17 00:00:00 2001 From: Aidan Hilt Date: Wed, 16 Oct 2024 14:19:33 -0400 Subject: [PATCH 09/11] Postfix --- wip/gen3-network-policies/templates/nolimit_netpolicy.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wip/gen3-network-policies/templates/nolimit_netpolicy.yaml b/wip/gen3-network-policies/templates/nolimit_netpolicy.yaml index 5bcd33bd..b0ab7f61 100644 --- a/wip/gen3-network-policies/templates/nolimit_netpolicy.yaml +++ b/wip/gen3-network-policies/templates/nolimit_netpolicy.yaml @@ -1,7 +1,7 @@ apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: - name: netpolicy-nolimit + name: nolimit-netpolicy spec: egress: - {} From e99c2dd426884051d92567d79cd43ac1d14c9f9f Mon Sep 17 00:00:00 2001 From: Aidan Hilt Date: Wed, 16 Oct 2024 16:52:56 -0400 Subject: [PATCH 10/11] Added the VPC netpolicy --- .../templates/vpc_netpolicy.yaml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 wip/gen3-network-policies/templates/vpc_netpolicy.yaml diff --git a/wip/gen3-network-policies/templates/vpc_netpolicy.yaml b/wip/gen3-network-policies/templates/vpc_netpolicy.yaml new file mode 100644 index 00000000..9d214618 --- /dev/null +++ b/wip/gen3-network-policies/templates/vpc_netpolicy.yaml @@ -0,0 +1,14 @@ +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: vpc-netpolicy +spec: + egress: + - to: + - ipBlock: + cidr: 172.0.0.0/8 + podSelector: + matchLabels: + netvpc: "yes" + policyTypes: + - Egress \ No newline at end of file From 5b38f380172546173f1b1cb29737c902f7794c6b Mon Sep 17 00:00:00 2001 From: Aidan Hilt Date: Thu, 7 Nov 2024 11:17:16 -0500 Subject: [PATCH 11/11] Adding a beta flag to net policies --- helm/ambassador/README.md | 2 +- helm/arborist/README.md | 2 +- helm/argo-wrapper/README.md | 2 +- helm/audit/README.md | 2 +- helm/aws-es-proxy/README.md | 2 +- helm/common/README.md | 2 +- helm/dicom-server/README.md | 2 +- helm/dicom-viewer/README.md | 2 +- helm/etl/Chart.yaml | 2 +- helm/etl/README.md | 4 ++-- helm/fence/README.md | 2 +- helm/frontend-framework/README.md | 2 +- helm/gen3/README.md | 4 ++-- helm/gen3/values.yaml | 1 + helm/guppy/README.md | 2 +- helm/hatchery/README.md | 2 +- helm/indexd/README.md | 2 +- helm/manifestservice/README.md | 2 +- helm/metadata/README.md | 2 +- helm/neuvector/README.md | 2 +- helm/peregrine/README.md | 2 +- helm/pidgin/README.md | 2 +- helm/portal/README.md | 2 +- helm/requestor/README.md | 2 +- helm/revproxy/README.md | 2 +- helm/sheepdog/README.md | 2 +- helm/sower/README.md | 2 +- helm/ssjdispatcher/README.md | 2 +- helm/wts/README.md | 2 +- 29 files changed, 31 insertions(+), 30 deletions(-) diff --git a/helm/ambassador/README.md b/helm/ambassador/README.md index 18e39969..4e5e3c61 100644 --- a/helm/ambassador/README.md +++ b/helm/ambassador/README.md @@ -58,4 +58,4 @@ A Helm chart for deploying ambassador for gen3 | userNamespace | string | `"jupyter-pods"` | Namespace to use for user resources. | ---------------------------------------------- -Autogenerated from chart metadata using [helm-docs v1.13.1](https://github.com/norwoodj/helm-docs/releases/v1.13.1) +Autogenerated from chart metadata using [helm-docs v1.14.2](https://github.com/norwoodj/helm-docs/releases/v1.14.2) diff --git a/helm/arborist/README.md b/helm/arborist/README.md index 787b51a0..5ff32e58 100644 --- a/helm/arborist/README.md +++ b/helm/arborist/README.md @@ -103,4 +103,4 @@ A Helm chart for gen3 arborist | volumes | list | `[]` | Volumes to attach to the pod | ---------------------------------------------- -Autogenerated from chart metadata using [helm-docs v1.13.1](https://github.com/norwoodj/helm-docs/releases/v1.13.1) +Autogenerated from chart metadata using [helm-docs v1.14.2](https://github.com/norwoodj/helm-docs/releases/v1.14.2) diff --git a/helm/argo-wrapper/README.md b/helm/argo-wrapper/README.md index 87a4de2b..2e5df003 100644 --- a/helm/argo-wrapper/README.md +++ b/helm/argo-wrapper/README.md @@ -65,4 +65,4 @@ A Helm chart for gen3 Argo Wrapper Service | volumes | list | `[{"configMap":{"items":[{"key":"argo.json","path":"argo.json"}],"name":"manifest-argo"},"name":"argo-config"}]` | Volumes to attach to the pod. | ---------------------------------------------- -Autogenerated from chart metadata using [helm-docs v1.13.1](https://github.com/norwoodj/helm-docs/releases/v1.13.1) +Autogenerated from chart metadata using [helm-docs v1.14.2](https://github.com/norwoodj/helm-docs/releases/v1.14.2) diff --git a/helm/audit/README.md b/helm/audit/README.md index 46ecc76f..767c1706 100644 --- a/helm/audit/README.md +++ b/helm/audit/README.md @@ -124,4 +124,4 @@ A Helm chart for Kubernetes | volumes | list | `[]` | Volumes to attach to the container. | ---------------------------------------------- -Autogenerated from chart metadata using [helm-docs v1.13.1](https://github.com/norwoodj/helm-docs/releases/v1.13.1) +Autogenerated from chart metadata using [helm-docs v1.14.2](https://github.com/norwoodj/helm-docs/releases/v1.14.2) diff --git a/helm/aws-es-proxy/README.md b/helm/aws-es-proxy/README.md index df8ba4ef..80e5b7ae 100644 --- a/helm/aws-es-proxy/README.md +++ b/helm/aws-es-proxy/README.md @@ -68,4 +68,4 @@ A Helm chart for AWS ES Proxy Service for gen3 | volumes | list | `nil` | Volumes to attach to the pod | ---------------------------------------------- -Autogenerated from chart metadata using [helm-docs v1.13.1](https://github.com/norwoodj/helm-docs/releases/v1.13.1) +Autogenerated from chart metadata using [helm-docs v1.14.2](https://github.com/norwoodj/helm-docs/releases/v1.14.2) diff --git a/helm/common/README.md b/helm/common/README.md index e120cef9..5fc9d467 100644 --- a/helm/common/README.md +++ b/helm/common/README.md @@ -34,4 +34,4 @@ A Helm chart for provisioning databases in gen3 | global.tierAccessLevel | string | `"libre"` | Access level for tiers. acceptable values for `tier_access_level` are: `libre`, `regular` and `private`. If omitted, by default common will be treated as `private` | ---------------------------------------------- -Autogenerated from chart metadata using [helm-docs v1.13.1](https://github.com/norwoodj/helm-docs/releases/v1.13.1) +Autogenerated from chart metadata using [helm-docs v1.14.2](https://github.com/norwoodj/helm-docs/releases/v1.14.2) diff --git a/helm/dicom-server/README.md b/helm/dicom-server/README.md index bee47187..99f770ba 100644 --- a/helm/dicom-server/README.md +++ b/helm/dicom-server/README.md @@ -51,4 +51,4 @@ A Helm chart for gen3 Dicom Server | volumes | list | `[{"name":"config-volume-g3auto","secret":{"secretName":"orthanc-g3auto"}}]` | Volumes to attach to the pod. | ---------------------------------------------- -Autogenerated from chart metadata using [helm-docs v1.13.1](https://github.com/norwoodj/helm-docs/releases/v1.13.1) +Autogenerated from chart metadata using [helm-docs v1.14.2](https://github.com/norwoodj/helm-docs/releases/v1.14.2) diff --git a/helm/dicom-viewer/README.md b/helm/dicom-viewer/README.md index 845b6984..739f7698 100644 --- a/helm/dicom-viewer/README.md +++ b/helm/dicom-viewer/README.md @@ -38,4 +38,4 @@ A Helm chart for gen3 Dicom Viewer | service.type | string | `"ClusterIP"` | Type of service. Valid values are "ClusterIP", "NodePort", "LoadBalancer", "ExternalName". | ---------------------------------------------- -Autogenerated from chart metadata using [helm-docs v1.13.1](https://github.com/norwoodj/helm-docs/releases/v1.13.1) +Autogenerated from chart metadata using [helm-docs v1.14.2](https://github.com/norwoodj/helm-docs/releases/v1.14.2) diff --git a/helm/etl/Chart.yaml b/helm/etl/Chart.yaml index 3a862865..497180b1 100644 --- a/helm/etl/Chart.yaml +++ b/helm/etl/Chart.yaml @@ -15,7 +15,7 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.2 +version: 0.1.3 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to diff --git a/helm/etl/README.md b/helm/etl/README.md index 9d7a43ee..ad7ba986 100644 --- a/helm/etl/README.md +++ b/helm/etl/README.md @@ -1,6 +1,6 @@ # etl -![Version: 0.1.2](https://img.shields.io/badge/Version-0.1.2-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) +![Version: 0.1.3](https://img.shields.io/badge/Version-0.1.3-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: master](https://img.shields.io/badge/AppVersion-master-informational?style=flat-square) A Helm chart for gen3 etl @@ -104,4 +104,4 @@ A Helm chart for gen3 etl | resources.tube.requests.memory | string | `"128Mi"` | The amount of memory requested | ---------------------------------------------- -Autogenerated from chart metadata using [helm-docs v1.13.1](https://github.com/norwoodj/helm-docs/releases/v1.13.1) +Autogenerated from chart metadata using [helm-docs v1.14.2](https://github.com/norwoodj/helm-docs/releases/v1.14.2) diff --git a/helm/fence/README.md b/helm/fence/README.md index 0344e81c..37f59cc2 100644 --- a/helm/fence/README.md +++ b/helm/fence/README.md @@ -198,4 +198,4 @@ A Helm chart for gen3 Fence | volumes | list | `[{"name":"old-config-volume","secret":{"secretName":"fence-secret"}},{"name":"json-secret-volume","secret":{"optional":true,"secretName":"fence-json-secret"}},{"name":"creds-volume","secret":{"secretName":"fence-creds"}},{"configMap":{"name":"config-helper","optional":true},"name":"config-helper"},{"configMap":{"name":"logo-config"},"name":"logo-volume"},{"name":"config-volume","secret":{"secretName":"fence-config"}},{"name":"fence-google-app-creds-secret-volume","secret":{"secretName":"fence-google-app-creds-secret"}},{"name":"fence-google-storage-creds-secret-volume","secret":{"secretName":"fence-google-storage-creds-secret"}},{"name":"fence-jwt-keys","secret":{"secretName":"fence-jwt-keys"}},{"configMap":{"name":"privacy-policy"},"name":"privacy-policy"},{"configMap":{"name":"fence-yaml-merge","optional":false},"name":"yaml-merge"},{"configMap":{"name":"manifest-fence","optional":true},"name":"config-volume-public"}]` | Volumes to attach to the container. | ---------------------------------------------- -Autogenerated from chart metadata using [helm-docs v1.13.1](https://github.com/norwoodj/helm-docs/releases/v1.13.1) +Autogenerated from chart metadata using [helm-docs v1.14.2](https://github.com/norwoodj/helm-docs/releases/v1.14.2) diff --git a/helm/frontend-framework/README.md b/helm/frontend-framework/README.md index 58c02661..843fb244 100644 --- a/helm/frontend-framework/README.md +++ b/helm/frontend-framework/README.md @@ -92,4 +92,4 @@ A Helm chart for the gen3 frontend framework | tolerations | list | `[]` | Tolerations to apply to the pod | ---------------------------------------------- -Autogenerated from chart metadata using [helm-docs v1.13.1](https://github.com/norwoodj/helm-docs/releases/v1.13.1) +Autogenerated from chart metadata using [helm-docs v1.14.2](https://github.com/norwoodj/helm-docs/releases/v1.14.2) diff --git a/helm/gen3/README.md b/helm/gen3/README.md index 3b5ac0df..5e63ea11 100644 --- a/helm/gen3/README.md +++ b/helm/gen3/README.md @@ -103,7 +103,7 @@ Helm chart to deploy Gen3 Data Commons | global.frontendRoot | string | `"portal"` | Which app will be served on /. Needs be set to portal for portal, or "gen3ff" for frontendframework. | | global.hostname | string | `"localhost"` | Hostname for the deployment. | | global.manifestGlobalExtraValues | map | `{}` | If you would like to add any extra values to the manifest-global configmap. | -| global.netPolicy | bool | `{"dbSubnet":"","enabled":false}` | Global flags to control and manage network policies for a Gen3 installation | +| global.netPolicy | bool | `{"dbSubnet":"","enabled":false}` | Global flags to control and manage network policies for a Gen3 installation NOTE: Network policies are currently a beta feature. Use with caution! | | global.netPolicy.dbSubnet | array | `""` | A CIDR range representing a database subnet, that services with a database need access to | | global.netPolicy.enabled | bool | `false` | Whether network policies are enabled | | global.portalApp | string | `"gitops"` | Portal application name. | @@ -182,4 +182,4 @@ Helm chart to deploy Gen3 Data Commons | wts.enabled | bool | `true` | Whether to deploy the wts subchart. | ---------------------------------------------- -Autogenerated from chart metadata using [helm-docs v1.13.1](https://github.com/norwoodj/helm-docs/releases/v1.13.1) +Autogenerated from chart metadata using [helm-docs v1.14.2](https://github.com/norwoodj/helm-docs/releases/v1.14.2) diff --git a/helm/gen3/values.yaml b/helm/gen3/values.yaml index 078dff1d..5e8715e1 100644 --- a/helm/gen3/values.yaml +++ b/helm/gen3/values.yaml @@ -61,6 +61,7 @@ global: # -- (int) Only relevant if tireAccessLevel is set to "regular". Summary charts below this limit will not appear for aggregated data. tierAccessLimit: "1000" # -- (bool) Global flags to control and manage network policies for a Gen3 installation + # NOTE: Network policies are currently a beta feature. Use with caution! netPolicy: # -- (bool) Whether network policies are enabled enabled: false diff --git a/helm/guppy/README.md b/helm/guppy/README.md index c8dfca42..69c34372 100644 --- a/helm/guppy/README.md +++ b/helm/guppy/README.md @@ -94,4 +94,4 @@ A Helm chart for gen3 Guppy Service | volumes | list | `[{"configMap":{"items":[{"key":"guppy_config.json","path":"guppy_config.json"}],"name":"manifest-guppy"},"name":"guppy-config"}]` | Volumes to attach to the pod. | ---------------------------------------------- -Autogenerated from chart metadata using [helm-docs v1.13.1](https://github.com/norwoodj/helm-docs/releases/v1.13.1) +Autogenerated from chart metadata using [helm-docs v1.14.2](https://github.com/norwoodj/helm-docs/releases/v1.14.2) diff --git a/helm/hatchery/README.md b/helm/hatchery/README.md index 8bdf0435..a688c2b8 100644 --- a/helm/hatchery/README.md +++ b/helm/hatchery/README.md @@ -85,4 +85,4 @@ A Helm chart for gen3 Hatchery | volumes | list | `[{"configMap":{"name":"manifest-hatchery"},"name":"hatchery-config"}]` | Volumes to attach to the container. | ---------------------------------------------- -Autogenerated from chart metadata using [helm-docs v1.13.1](https://github.com/norwoodj/helm-docs/releases/v1.13.1) +Autogenerated from chart metadata using [helm-docs v1.14.2](https://github.com/norwoodj/helm-docs/releases/v1.14.2) diff --git a/helm/indexd/README.md b/helm/indexd/README.md index cd0b21ec..4ebf27f3 100644 --- a/helm/indexd/README.md +++ b/helm/indexd/README.md @@ -108,4 +108,4 @@ A Helm chart for gen3 indexd | volumes | list | `[{"configMap":{"name":"indexd-uwsgi"},"name":"uwsgi-config"},{"name":"config-volume","secret":{"secretName":"indexd-settings"}}]` | Volumes to attach to the pod | ---------------------------------------------- -Autogenerated from chart metadata using [helm-docs v1.13.1](https://github.com/norwoodj/helm-docs/releases/v1.13.1) +Autogenerated from chart metadata using [helm-docs v1.14.2](https://github.com/norwoodj/helm-docs/releases/v1.14.2) diff --git a/helm/manifestservice/README.md b/helm/manifestservice/README.md index 417150bb..92961f88 100644 --- a/helm/manifestservice/README.md +++ b/helm/manifestservice/README.md @@ -83,4 +83,4 @@ A Helm chart for Kubernetes | volumes | list | `[{"name":"config-volume","secret":{"secretName":"manifestservice-g3auto"}}]` | Volumes to attach to the container. | ---------------------------------------------- -Autogenerated from chart metadata using [helm-docs v1.13.1](https://github.com/norwoodj/helm-docs/releases/v1.13.1) +Autogenerated from chart metadata using [helm-docs v1.14.2](https://github.com/norwoodj/helm-docs/releases/v1.14.2) diff --git a/helm/metadata/README.md b/helm/metadata/README.md index a50f37d0..65d33a01 100644 --- a/helm/metadata/README.md +++ b/helm/metadata/README.md @@ -122,4 +122,4 @@ A Helm chart for gen3 Metadata Service | volumeMounts | list | `[{"mountPath":"/src/.env","name":"config-volume-g3auto","readOnly":true,"subPath":"metadata.env"},{"mountPath":"/aggregate_config.json","name":"config-volume","readOnly":true,"subPath":"aggregate_config.json"},{"mountPath":"/metadata.json","name":"config-manifest","readOnly":true,"subPath":"json"}]` | Volumes to mount to the container. | ---------------------------------------------- -Autogenerated from chart metadata using [helm-docs v1.13.1](https://github.com/norwoodj/helm-docs/releases/v1.13.1) +Autogenerated from chart metadata using [helm-docs v1.14.2](https://github.com/norwoodj/helm-docs/releases/v1.14.2) diff --git a/helm/neuvector/README.md b/helm/neuvector/README.md index 6584a6d8..d075b808 100644 --- a/helm/neuvector/README.md +++ b/helm/neuvector/README.md @@ -20,4 +20,4 @@ NeuVector Kubernetes Security Policy templates to protect Gen3 | policies.policyMode | string | `"Monitor"` | | ---------------------------------------------- -Autogenerated from chart metadata using [helm-docs v1.13.1](https://github.com/norwoodj/helm-docs/releases/v1.13.1) +Autogenerated from chart metadata using [helm-docs v1.14.2](https://github.com/norwoodj/helm-docs/releases/v1.14.2) diff --git a/helm/peregrine/README.md b/helm/peregrine/README.md index 4473e7ad..2410fe76 100644 --- a/helm/peregrine/README.md +++ b/helm/peregrine/README.md @@ -103,4 +103,4 @@ A Helm chart for gen3 Peregrine service | volumes | list | `[{"emptyDir":{},"name":"shared-data"},{"name":"config-volume","secret":{"secretName":"peregrine-secret"}}]` | Volumes to attach to the container. | ---------------------------------------------- -Autogenerated from chart metadata using [helm-docs v1.13.1](https://github.com/norwoodj/helm-docs/releases/v1.13.1) +Autogenerated from chart metadata using [helm-docs v1.14.2](https://github.com/norwoodj/helm-docs/releases/v1.14.2) diff --git a/helm/pidgin/README.md b/helm/pidgin/README.md index afd80b13..4e024fc8 100644 --- a/helm/pidgin/README.md +++ b/helm/pidgin/README.md @@ -83,4 +83,4 @@ A Helm chart for gen3 Pidgin Service | strategy.rollingUpdate.maxUnavailable | int | `0` | Maximum amount of pods that can be unavailable during the update. | ---------------------------------------------- -Autogenerated from chart metadata using [helm-docs v1.13.1](https://github.com/norwoodj/helm-docs/releases/v1.13.1) +Autogenerated from chart metadata using [helm-docs v1.14.2](https://github.com/norwoodj/helm-docs/releases/v1.14.2) diff --git a/helm/portal/README.md b/helm/portal/README.md index a0ab696e..d1adc730 100644 --- a/helm/portal/README.md +++ b/helm/portal/README.md @@ -99,4 +99,4 @@ A Helm chart for gen3 data-portal | tolerations | list | `[]` | Tolerations to apply to the pod | ---------------------------------------------- -Autogenerated from chart metadata using [helm-docs v1.13.1](https://github.com/norwoodj/helm-docs/releases/v1.13.1) +Autogenerated from chart metadata using [helm-docs v1.14.2](https://github.com/norwoodj/helm-docs/releases/v1.14.2) diff --git a/helm/requestor/README.md b/helm/requestor/README.md index ed3436c1..415d18ef 100644 --- a/helm/requestor/README.md +++ b/helm/requestor/README.md @@ -115,4 +115,4 @@ A Helm chart for gen3 Requestor Service | volumeMounts | list | `nil` | Volumes to mount to the container. | ---------------------------------------------- -Autogenerated from chart metadata using [helm-docs v1.13.1](https://github.com/norwoodj/helm-docs/releases/v1.13.1) +Autogenerated from chart metadata using [helm-docs v1.14.2](https://github.com/norwoodj/helm-docs/releases/v1.14.2) diff --git a/helm/revproxy/README.md b/helm/revproxy/README.md index 7e4f7b1f..dee3b68d 100644 --- a/helm/revproxy/README.md +++ b/helm/revproxy/README.md @@ -108,4 +108,4 @@ A Helm chart for gen3 revproxy | userhelperEnabled | bool | `false` | | ---------------------------------------------- -Autogenerated from chart metadata using [helm-docs v1.13.1](https://github.com/norwoodj/helm-docs/releases/v1.13.1) +Autogenerated from chart metadata using [helm-docs v1.14.2](https://github.com/norwoodj/helm-docs/releases/v1.14.2) diff --git a/helm/sheepdog/README.md b/helm/sheepdog/README.md index abaa5912..1737716d 100644 --- a/helm/sheepdog/README.md +++ b/helm/sheepdog/README.md @@ -108,4 +108,4 @@ A Helm chart for gen3 Sheepdog Service | volumeMounts | list | `[{"mountPath":"/var/www/sheepdog/settings.py","name":"config-volume","readOnly":true,"subPath":"settings.py"}]` | Volumes to mount to the container. | ---------------------------------------------- -Autogenerated from chart metadata using [helm-docs v1.13.1](https://github.com/norwoodj/helm-docs/releases/v1.13.1) +Autogenerated from chart metadata using [helm-docs v1.14.2](https://github.com/norwoodj/helm-docs/releases/v1.14.2) diff --git a/helm/sower/README.md b/helm/sower/README.md index 33aaffa5..2653a054 100644 --- a/helm/sower/README.md +++ b/helm/sower/README.md @@ -185,4 +185,4 @@ A Helm chart for gen3 sower | volumes | list | `[{"configMap":{"items":[{"key":"json","path":"sower_config.json"}],"name":"manifest-sower"},"name":"sower-config"}]` | Volumes to attach to the container. | ---------------------------------------------- -Autogenerated from chart metadata using [helm-docs v1.13.1](https://github.com/norwoodj/helm-docs/releases/v1.13.1) +Autogenerated from chart metadata using [helm-docs v1.14.2](https://github.com/norwoodj/helm-docs/releases/v1.14.2) diff --git a/helm/ssjdispatcher/README.md b/helm/ssjdispatcher/README.md index c672e10b..73ac3260 100644 --- a/helm/ssjdispatcher/README.md +++ b/helm/ssjdispatcher/README.md @@ -110,4 +110,4 @@ A Helm chart for gen3 ssjdispatcher | volumes | list | `[{"name":"ssjdispatcher-creds-volume","secret":{"secretName":"ssjdispatcher-creds"}}]` | Volumes to attach to the container. | ---------------------------------------------- -Autogenerated from chart metadata using [helm-docs v1.13.1](https://github.com/norwoodj/helm-docs/releases/v1.13.1) +Autogenerated from chart metadata using [helm-docs v1.14.2](https://github.com/norwoodj/helm-docs/releases/v1.14.2) diff --git a/helm/wts/README.md b/helm/wts/README.md index 00c00b5e..2a7685e6 100644 --- a/helm/wts/README.md +++ b/helm/wts/README.md @@ -103,4 +103,4 @@ A Helm chart for gen3 workspace token service | tolerations | list | `[]` | Tolerations for the pods | ---------------------------------------------- -Autogenerated from chart metadata using [helm-docs v1.13.1](https://github.com/norwoodj/helm-docs/releases/v1.13.1) +Autogenerated from chart metadata using [helm-docs v1.14.2](https://github.com/norwoodj/helm-docs/releases/v1.14.2)